2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
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.
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.
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/>.
21 #include "libcli/security/security.h"
23 #ifndef Py_RETURN_NONE
24 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
27 static void PyType_AddMethods(PyTypeObject
*type
, PyMethodDef
*methods
)
31 if (type
->tp_dict
== NULL
)
32 type
->tp_dict
= PyDict_New();
34 for (i
= 0; methods
[i
].ml_name
; i
++) {
36 if (methods
[i
].ml_flags
& METH_CLASS
)
37 descr
= PyCFunction_New(&methods
[i
], (PyObject
*)type
);
39 descr
= PyDescr_NewMethod(type
, &methods
[i
]);
40 PyDict_SetItemString(dict
, methods
[i
].ml_name
,
45 static PyObject
*py_dom_sid_split(PyObject
*py_self
, PyObject
*args
)
47 struct dom_sid
*self
= pytalloc_get_ptr(py_self
);
48 struct dom_sid
*domain_sid
;
52 PyObject
*py_domain_sid
;
54 mem_ctx
= talloc_new(NULL
);
55 if (mem_ctx
== NULL
) {
60 status
= dom_sid_split_rid(mem_ctx
, self
, &domain_sid
, &rid
);
61 if (!NT_STATUS_IS_OK(status
)) {
62 PyErr_SetString(PyExc_RuntimeError
, "dom_sid_split_rid failed");
67 py_domain_sid
= pytalloc_steal(&dom_sid_Type
, domain_sid
);
69 return Py_BuildValue("(OI)", py_domain_sid
, rid
);
72 static int py_dom_sid_cmp(PyObject
*py_self
, PyObject
*py_other
)
74 struct dom_sid
*self
= pytalloc_get_ptr(py_self
), *other
;
77 other
= pytalloc_get_ptr(py_other
);
81 val
= dom_sid_compare(self
, other
);
90 static PyObject
*py_dom_sid_str(PyObject
*py_self
)
92 struct dom_sid
*self
= pytalloc_get_ptr(py_self
);
93 char *str
= dom_sid_string(NULL
, self
);
94 PyObject
*ret
= PyString_FromString(str
);
99 static PyObject
*py_dom_sid_repr(PyObject
*py_self
)
101 struct dom_sid
*self
= pytalloc_get_ptr(py_self
);
102 char *str
= dom_sid_string(NULL
, self
);
103 PyObject
*ret
= PyString_FromFormat("dom_sid('%s')", str
);
108 static int py_dom_sid_init(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
111 struct dom_sid
*sid
= pytalloc_get_ptr(self
);
112 const char *kwnames
[] = { "str", NULL
};
114 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|s", discard_const_p(char *, kwnames
), &str
))
117 if (str
!= NULL
&& !dom_sid_parse(str
, sid
)) {
118 PyErr_SetString(PyExc_TypeError
, "Unable to parse string");
125 static PyMethodDef py_dom_sid_extra_methods
[] = {
126 { "split", (PyCFunction
)py_dom_sid_split
, METH_NOARGS
,
127 "S.split() -> (domain_sid, rid)\n"
128 "Split a domain sid" },
133 static void py_dom_sid_patch(PyTypeObject
*type
)
135 type
->tp_init
= py_dom_sid_init
;
136 type
->tp_str
= py_dom_sid_str
;
137 type
->tp_repr
= py_dom_sid_repr
;
138 type
->tp_compare
= py_dom_sid_cmp
;
139 PyType_AddMethods(type
, py_dom_sid_extra_methods
);
142 #define PY_DOM_SID_PATCH py_dom_sid_patch
144 static PyObject
*py_descriptor_sacl_add(PyObject
*self
, PyObject
*args
)
146 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
148 struct security_ace
*ace
;
151 if (!PyArg_ParseTuple(args
, "O", &py_ace
))
154 ace
= pytalloc_get_ptr(py_ace
);
155 status
= security_descriptor_sacl_add(desc
, ace
);
156 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
160 static PyObject
*py_descriptor_dacl_add(PyObject
*self
, PyObject
*args
)
162 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
164 struct security_ace
*ace
;
167 if (!PyArg_ParseTuple(args
, "O", &py_ace
))
170 ace
= pytalloc_get_ptr(py_ace
);
172 status
= security_descriptor_dacl_add(desc
, ace
);
173 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
177 static PyObject
*py_descriptor_dacl_del(PyObject
*self
, PyObject
*args
)
179 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
184 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
187 sid
= pytalloc_get_ptr(py_sid
);
188 status
= security_descriptor_dacl_del(desc
, sid
);
189 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
193 static PyObject
*py_descriptor_sacl_del(PyObject
*self
, PyObject
*args
)
195 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
200 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
203 sid
= pytalloc_get_ptr(py_sid
);
204 status
= security_descriptor_sacl_del(desc
, sid
);
205 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
209 static PyObject
*py_descriptor_new(PyTypeObject
*self
, PyObject
*args
, PyObject
*kwargs
)
211 return pytalloc_steal(self
, security_descriptor_initialise(NULL
));
214 static PyObject
*py_descriptor_from_sddl(PyObject
*self
, PyObject
*args
)
216 struct security_descriptor
*secdesc
;
221 if (!PyArg_ParseTuple(args
, "sO!", &sddl
, &dom_sid_Type
, &py_sid
))
224 sid
= pytalloc_get_ptr(py_sid
);
226 secdesc
= sddl_decode(NULL
, sddl
, sid
);
227 if (secdesc
== NULL
) {
228 PyErr_SetString(PyExc_TypeError
, "Unable to parse SDDL");
232 return pytalloc_steal((PyTypeObject
*)self
, secdesc
);
235 static PyObject
*py_descriptor_as_sddl(PyObject
*self
, PyObject
*args
)
238 PyObject
*py_sid
= Py_None
;
239 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
243 if (!PyArg_ParseTuple(args
, "|O!", &dom_sid_Type
, &py_sid
))
246 if (py_sid
!= Py_None
)
247 sid
= pytalloc_get_ptr(py_sid
);
251 text
= sddl_encode(NULL
, desc
, sid
);
253 ret
= PyString_FromString(text
);
260 static PyMethodDef py_descriptor_extra_methods
[] = {
261 { "sacl_add", (PyCFunction
)py_descriptor_sacl_add
, METH_VARARGS
,
262 "S.sacl_add(ace) -> None\n"
263 "Add a security ace to this security descriptor" },
264 { "dacl_add", (PyCFunction
)py_descriptor_dacl_add
, METH_VARARGS
,
266 { "dacl_del", (PyCFunction
)py_descriptor_dacl_del
, METH_VARARGS
,
268 { "sacl_del", (PyCFunction
)py_descriptor_sacl_del
, METH_VARARGS
,
270 { "from_sddl", (PyCFunction
)py_descriptor_from_sddl
, METH_VARARGS
|METH_CLASS
,
272 { "as_sddl", (PyCFunction
)py_descriptor_as_sddl
, METH_VARARGS
,
277 static void py_descriptor_patch(PyTypeObject
*type
)
279 type
->tp_new
= py_descriptor_new
;
280 PyType_AddMethods(type
, py_descriptor_extra_methods
);
283 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
285 static PyObject
*py_token_is_sid(PyObject
*self
, PyObject
*args
)
289 struct security_token
*token
= pytalloc_get_ptr(self
);
290 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
293 sid
= pytalloc_get_ptr(py_sid
);
295 return PyBool_FromLong(security_token_is_sid(token
, sid
));
298 static PyObject
*py_token_has_sid(PyObject
*self
, PyObject
*args
)
302 struct security_token
*token
= pytalloc_get_ptr(self
);
303 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
306 sid
= pytalloc_get_ptr(py_sid
);
308 return PyBool_FromLong(security_token_has_sid(token
, sid
));
311 static PyObject
*py_token_is_anonymous(PyObject
*self
)
313 struct security_token
*token
= pytalloc_get_ptr(self
);
315 return PyBool_FromLong(security_token_is_anonymous(token
));
318 static PyObject
*py_token_is_system(PyObject
*self
)
320 struct security_token
*token
= pytalloc_get_ptr(self
);
322 return PyBool_FromLong(security_token_is_system(token
));
325 static PyObject
*py_token_has_builtin_administrators(PyObject
*self
)
327 struct security_token
*token
= pytalloc_get_ptr(self
);
329 return PyBool_FromLong(security_token_has_builtin_administrators(token
));
332 static PyObject
*py_token_has_nt_authenticated_users(PyObject
*self
)
334 struct security_token
*token
= pytalloc_get_ptr(self
);
336 return PyBool_FromLong(security_token_has_nt_authenticated_users(token
));
339 static PyObject
*py_token_has_privilege(PyObject
*self
, PyObject
*args
)
342 struct security_token
*token
= pytalloc_get_ptr(self
);
344 if (!PyArg_ParseTuple(args
, "i", &priv
))
347 return PyBool_FromLong(security_token_has_privilege(token
, priv
));
350 static PyObject
*py_token_set_privilege(PyObject
*self
, PyObject
*args
)
353 struct security_token
*token
= pytalloc_get_ptr(self
);
355 if (!PyArg_ParseTuple(args
, "i", &priv
))
358 security_token_set_privilege(token
, priv
);
362 static PyObject
*py_token_new(PyTypeObject
*self
, PyObject
*args
, PyObject
*kwargs
)
364 return pytalloc_steal(self
, security_token_initialise(NULL
));
367 static PyMethodDef py_token_extra_methods
[] = {
368 { "is_sid", (PyCFunction
)py_token_is_sid
, METH_VARARGS
,
369 "S.is_sid(sid) -> bool\n"
370 "Check whether this token is of the specified SID." },
371 { "has_sid", (PyCFunction
)py_token_has_sid
, METH_VARARGS
,
373 { "is_anonymous", (PyCFunction
)py_token_is_anonymous
, METH_NOARGS
,
374 "S.is_anonymus() -> bool\n"
375 "Check whether this is an anonymous token." },
376 { "is_system", (PyCFunction
)py_token_is_system
, METH_NOARGS
,
378 { "has_builtin_administrators", (PyCFunction
)py_token_has_builtin_administrators
, METH_NOARGS
,
380 { "has_nt_authenticated_users", (PyCFunction
)py_token_has_nt_authenticated_users
, METH_NOARGS
,
382 { "has_privilege", (PyCFunction
)py_token_has_privilege
, METH_VARARGS
,
384 { "set_privilege", (PyCFunction
)py_token_set_privilege
, METH_VARARGS
,
389 #define PY_TOKEN_PATCH py_token_patch
390 static void py_token_patch(PyTypeObject
*type
)
392 type
->tp_new
= py_token_new
;
393 PyType_AddMethods(type
, py_token_extra_methods
);
396 static PyObject
*py_privilege_name(PyObject
*self
, PyObject
*args
)
399 if (!PyArg_ParseTuple(args
, "i", &priv
))
402 return PyString_FromString(sec_privilege_name(priv
));
405 static PyObject
*py_privilege_id(PyObject
*self
, PyObject
*args
)
409 if (!PyArg_ParseTuple(args
, "s", &name
))
412 return PyInt_FromLong(sec_privilege_id(name
));
415 static PyObject
*py_random_sid(PyObject
*self
)
419 char *str
= talloc_asprintf(NULL
, "S-1-5-21-%u-%u-%u",
420 (unsigned)generate_random(),
421 (unsigned)generate_random(),
422 (unsigned)generate_random());
424 sid
= dom_sid_parse_talloc(NULL
, str
);
426 ret
= pytalloc_steal(&dom_sid_Type
, sid
);
430 static PyMethodDef py_mod_security_extra_methods
[] = {
431 { "random_sid", (PyCFunction
)py_random_sid
, METH_NOARGS
, NULL
},
432 { "privilege_id", (PyCFunction
)py_privilege_id
, METH_VARARGS
, NULL
},
433 { "privilege_name", (PyCFunction
)py_privilege_name
, METH_VARARGS
, NULL
},
437 static void py_mod_security_patch(PyObject
*m
)
440 for (i
= 0; py_mod_security_extra_methods
[i
].ml_name
; i
++) {
441 PyObject
*descr
= PyCFunction_New(&py_mod_security_extra_methods
[i
], NULL
);
442 PyModule_AddObject(m
, py_mod_security_extra_methods
[i
].ml_name
,
447 #define PY_MOD_SECURITY_PATCH py_mod_security_patch