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 static void PyType_AddMethods(PyTypeObject
*type
, PyMethodDef
*methods
)
27 if (type
->tp_dict
== NULL
)
28 type
->tp_dict
= PyDict_New();
30 for (i
= 0; methods
[i
].ml_name
; i
++) {
32 if (methods
[i
].ml_flags
& METH_CLASS
)
33 descr
= PyCFunction_New(&methods
[i
], (PyObject
*)type
);
35 descr
= PyDescr_NewMethod(type
, &methods
[i
]);
36 PyDict_SetItemString(dict
, methods
[i
].ml_name
,
41 static PyObject
*py_dom_sid_split(PyObject
*py_self
, PyObject
*args
)
43 struct dom_sid
*self
= pytalloc_get_ptr(py_self
);
44 struct dom_sid
*domain_sid
;
48 PyObject
*py_domain_sid
;
50 mem_ctx
= talloc_new(NULL
);
51 if (mem_ctx
== NULL
) {
56 status
= dom_sid_split_rid(mem_ctx
, self
, &domain_sid
, &rid
);
57 if (!NT_STATUS_IS_OK(status
)) {
58 PyErr_SetString(PyExc_RuntimeError
, "dom_sid_split_rid failed");
63 py_domain_sid
= pytalloc_steal(&dom_sid_Type
, domain_sid
);
65 return Py_BuildValue("(OI)", py_domain_sid
, rid
);
68 static int py_dom_sid_cmp(PyObject
*py_self
, PyObject
*py_other
)
70 struct dom_sid
*self
= pytalloc_get_ptr(py_self
), *other
;
73 other
= pytalloc_get_ptr(py_other
);
77 val
= dom_sid_compare(self
, other
);
86 static PyObject
*py_dom_sid_str(PyObject
*py_self
)
88 struct dom_sid
*self
= pytalloc_get_ptr(py_self
);
89 char *str
= dom_sid_string(NULL
, self
);
90 PyObject
*ret
= PyString_FromString(str
);
95 static PyObject
*py_dom_sid_repr(PyObject
*py_self
)
97 struct dom_sid
*self
= pytalloc_get_ptr(py_self
);
98 char *str
= dom_sid_string(NULL
, self
);
99 PyObject
*ret
= PyString_FromFormat("dom_sid('%s')", str
);
104 static int py_dom_sid_init(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
107 struct dom_sid
*sid
= pytalloc_get_ptr(self
);
108 const char *kwnames
[] = { "str", NULL
};
110 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|s", discard_const_p(char *, kwnames
), &str
))
113 if (str
!= NULL
&& !dom_sid_parse(str
, sid
)) {
114 PyErr_SetString(PyExc_TypeError
, "Unable to parse string");
121 static PyMethodDef py_dom_sid_extra_methods
[] = {
122 { "split", (PyCFunction
)py_dom_sid_split
, METH_NOARGS
,
123 "S.split() -> (domain_sid, rid)\n"
124 "Split a domain sid" },
129 static void py_dom_sid_patch(PyTypeObject
*type
)
131 type
->tp_init
= py_dom_sid_init
;
132 type
->tp_str
= py_dom_sid_str
;
133 type
->tp_repr
= py_dom_sid_repr
;
134 type
->tp_compare
= py_dom_sid_cmp
;
135 PyType_AddMethods(type
, py_dom_sid_extra_methods
);
138 #define PY_DOM_SID_PATCH py_dom_sid_patch
140 static PyObject
*py_descriptor_sacl_add(PyObject
*self
, PyObject
*args
)
142 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
144 struct security_ace
*ace
;
147 if (!PyArg_ParseTuple(args
, "O", &py_ace
))
150 ace
= pytalloc_get_ptr(py_ace
);
151 status
= security_descriptor_sacl_add(desc
, ace
);
152 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
156 static PyObject
*py_descriptor_dacl_add(PyObject
*self
, PyObject
*args
)
158 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
160 struct security_ace
*ace
;
163 if (!PyArg_ParseTuple(args
, "O", &py_ace
))
166 ace
= pytalloc_get_ptr(py_ace
);
168 status
= security_descriptor_dacl_add(desc
, ace
);
169 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
173 static PyObject
*py_descriptor_dacl_del(PyObject
*self
, PyObject
*args
)
175 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
180 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
183 sid
= pytalloc_get_ptr(py_sid
);
184 status
= security_descriptor_dacl_del(desc
, sid
);
185 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
189 static PyObject
*py_descriptor_sacl_del(PyObject
*self
, PyObject
*args
)
191 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
196 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
199 sid
= pytalloc_get_ptr(py_sid
);
200 status
= security_descriptor_sacl_del(desc
, sid
);
201 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
205 static PyObject
*py_descriptor_new(PyTypeObject
*self
, PyObject
*args
, PyObject
*kwargs
)
207 return pytalloc_steal(self
, security_descriptor_initialise(NULL
));
210 static PyObject
*py_descriptor_from_sddl(PyObject
*self
, PyObject
*args
)
212 struct security_descriptor
*secdesc
;
217 if (!PyArg_ParseTuple(args
, "sO!", &sddl
, &dom_sid_Type
, &py_sid
))
220 sid
= pytalloc_get_ptr(py_sid
);
222 secdesc
= sddl_decode(NULL
, sddl
, sid
);
223 if (secdesc
== NULL
) {
224 PyErr_SetString(PyExc_TypeError
, "Unable to parse SDDL");
228 return pytalloc_steal((PyTypeObject
*)self
, secdesc
);
231 static PyObject
*py_descriptor_as_sddl(PyObject
*self
, PyObject
*args
)
234 PyObject
*py_sid
= Py_None
;
235 struct security_descriptor
*desc
= pytalloc_get_ptr(self
);
239 if (!PyArg_ParseTuple(args
, "|O!", &dom_sid_Type
, &py_sid
))
242 if (py_sid
!= Py_None
)
243 sid
= pytalloc_get_ptr(py_sid
);
247 text
= sddl_encode(NULL
, desc
, sid
);
249 ret
= PyString_FromString(text
);
256 static PyMethodDef py_descriptor_extra_methods
[] = {
257 { "sacl_add", (PyCFunction
)py_descriptor_sacl_add
, METH_VARARGS
,
258 "S.sacl_add(ace) -> None\n"
259 "Add a security ace to this security descriptor" },
260 { "dacl_add", (PyCFunction
)py_descriptor_dacl_add
, METH_VARARGS
,
262 { "dacl_del", (PyCFunction
)py_descriptor_dacl_del
, METH_VARARGS
,
264 { "sacl_del", (PyCFunction
)py_descriptor_sacl_del
, METH_VARARGS
,
266 { "from_sddl", (PyCFunction
)py_descriptor_from_sddl
, METH_VARARGS
|METH_CLASS
,
268 { "as_sddl", (PyCFunction
)py_descriptor_as_sddl
, METH_VARARGS
,
273 static void py_descriptor_patch(PyTypeObject
*type
)
275 type
->tp_new
= py_descriptor_new
;
276 PyType_AddMethods(type
, py_descriptor_extra_methods
);
279 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
281 static PyObject
*py_token_is_sid(PyObject
*self
, PyObject
*args
)
285 struct security_token
*token
= pytalloc_get_ptr(self
);
286 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
289 sid
= pytalloc_get_ptr(py_sid
);
291 return PyBool_FromLong(security_token_is_sid(token
, sid
));
294 static PyObject
*py_token_has_sid(PyObject
*self
, PyObject
*args
)
298 struct security_token
*token
= pytalloc_get_ptr(self
);
299 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
302 sid
= pytalloc_get_ptr(py_sid
);
304 return PyBool_FromLong(security_token_has_sid(token
, sid
));
307 static PyObject
*py_token_is_anonymous(PyObject
*self
)
309 struct security_token
*token
= pytalloc_get_ptr(self
);
311 return PyBool_FromLong(security_token_is_anonymous(token
));
314 static PyObject
*py_token_is_system(PyObject
*self
)
316 struct security_token
*token
= pytalloc_get_ptr(self
);
318 return PyBool_FromLong(security_token_is_system(token
));
321 static PyObject
*py_token_has_builtin_administrators(PyObject
*self
)
323 struct security_token
*token
= pytalloc_get_ptr(self
);
325 return PyBool_FromLong(security_token_has_builtin_administrators(token
));
328 static PyObject
*py_token_has_nt_authenticated_users(PyObject
*self
)
330 struct security_token
*token
= pytalloc_get_ptr(self
);
332 return PyBool_FromLong(security_token_has_nt_authenticated_users(token
));
335 static PyObject
*py_token_has_privilege(PyObject
*self
, PyObject
*args
)
338 struct security_token
*token
= pytalloc_get_ptr(self
);
340 if (!PyArg_ParseTuple(args
, "i", &priv
))
343 return PyBool_FromLong(security_token_has_privilege(token
, priv
));
346 static PyObject
*py_token_set_privilege(PyObject
*self
, PyObject
*args
)
349 struct security_token
*token
= pytalloc_get_ptr(self
);
351 if (!PyArg_ParseTuple(args
, "i", &priv
))
354 security_token_set_privilege(token
, priv
);
358 static PyObject
*py_token_new(PyTypeObject
*self
, PyObject
*args
, PyObject
*kwargs
)
360 return pytalloc_steal(self
, security_token_initialise(NULL
));
363 static PyMethodDef py_token_extra_methods
[] = {
364 { "is_sid", (PyCFunction
)py_token_is_sid
, METH_VARARGS
,
365 "S.is_sid(sid) -> bool\n"
366 "Check whether this token is of the specified SID." },
367 { "has_sid", (PyCFunction
)py_token_has_sid
, METH_VARARGS
,
369 { "is_anonymous", (PyCFunction
)py_token_is_anonymous
, METH_NOARGS
,
370 "S.is_anonymus() -> bool\n"
371 "Check whether this is an anonymous token." },
372 { "is_system", (PyCFunction
)py_token_is_system
, METH_NOARGS
,
374 { "has_builtin_administrators", (PyCFunction
)py_token_has_builtin_administrators
, METH_NOARGS
,
376 { "has_nt_authenticated_users", (PyCFunction
)py_token_has_nt_authenticated_users
, METH_NOARGS
,
378 { "has_privilege", (PyCFunction
)py_token_has_privilege
, METH_VARARGS
,
380 { "set_privilege", (PyCFunction
)py_token_set_privilege
, METH_VARARGS
,
385 #define PY_TOKEN_PATCH py_token_patch
386 static void py_token_patch(PyTypeObject
*type
)
388 type
->tp_new
= py_token_new
;
389 PyType_AddMethods(type
, py_token_extra_methods
);
392 static PyObject
*py_privilege_name(PyObject
*self
, PyObject
*args
)
395 if (!PyArg_ParseTuple(args
, "i", &priv
))
398 return PyString_FromString(sec_privilege_name(priv
));
401 static PyObject
*py_privilege_id(PyObject
*self
, PyObject
*args
)
405 if (!PyArg_ParseTuple(args
, "s", &name
))
408 return PyInt_FromLong(sec_privilege_id(name
));
411 static PyObject
*py_random_sid(PyObject
*self
)
415 char *str
= talloc_asprintf(NULL
, "S-1-5-21-%u-%u-%u",
416 (unsigned)generate_random(),
417 (unsigned)generate_random(),
418 (unsigned)generate_random());
420 sid
= dom_sid_parse_talloc(NULL
, str
);
422 ret
= pytalloc_steal(&dom_sid_Type
, sid
);
426 static PyMethodDef py_mod_security_extra_methods
[] = {
427 { "random_sid", (PyCFunction
)py_random_sid
, METH_NOARGS
, NULL
},
428 { "privilege_id", (PyCFunction
)py_privilege_id
, METH_VARARGS
, NULL
},
429 { "privilege_name", (PyCFunction
)py_privilege_name
, METH_VARARGS
, NULL
},
433 static void py_mod_security_patch(PyObject
*m
)
436 for (i
= 0; py_mod_security_extra_methods
[i
].ml_name
; i
++) {
437 PyObject
*descr
= PyCFunction_New(&py_mod_security_extra_methods
[i
], NULL
);
438 PyModule_AddObject(m
, py_mod_security_extra_methods
[i
].ml_name
,
443 #define PY_MOD_SECURITY_PATCH py_mod_security_patch