2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
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.
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.
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/>.
20 #include "libcli/security/security.h"
22 #ifndef Py_RETURN_NONE
23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
26 static void PyType_AddMethods(PyTypeObject
*type
, PyMethodDef
*methods
)
30 if (type
->tp_dict
== NULL
)
31 type
->tp_dict
= PyDict_New();
33 for (i
= 0; methods
[i
].ml_name
; i
++) {
35 if (methods
[i
].ml_flags
& METH_CLASS
)
36 descr
= PyCFunction_New(&methods
[i
], (PyObject
*)type
);
38 descr
= PyDescr_NewMethod(type
, &methods
[i
]);
39 PyDict_SetItemString(dict
, methods
[i
].ml_name
,
44 static PyObject
*py_dom_sid_split(PyObject
*py_self
, PyObject
*args
)
46 struct dom_sid
*self
= py_talloc_get_ptr(py_self
);
47 struct dom_sid
*domain_sid
;
51 PyObject
*py_domain_sid
;
53 mem_ctx
= talloc_new(NULL
);
54 if (mem_ctx
== NULL
) {
59 status
= dom_sid_split_rid(mem_ctx
, self
, &domain_sid
, &rid
);
60 if (!NT_STATUS_IS_OK(status
)) {
61 PyErr_SetString(PyExc_RuntimeError
, "dom_sid_split_rid failed");
66 py_domain_sid
= py_talloc_steal(&dom_sid_Type
, domain_sid
);
68 return Py_BuildValue("(OI)", py_domain_sid
, rid
);
71 static int py_dom_sid_cmp(PyObject
*py_self
, PyObject
*py_other
)
73 struct dom_sid
*self
= py_talloc_get_ptr(py_self
), *other
;
74 other
= py_talloc_get_ptr(py_other
);
78 return dom_sid_compare(self
, other
);
81 static PyObject
*py_dom_sid_str(PyObject
*py_self
)
83 struct dom_sid
*self
= py_talloc_get_ptr(py_self
);
84 char *str
= dom_sid_string(NULL
, self
);
85 PyObject
*ret
= PyString_FromString(str
);
90 static PyObject
*py_dom_sid_repr(PyObject
*py_self
)
92 struct dom_sid
*self
= py_talloc_get_ptr(py_self
);
93 char *str
= dom_sid_string(NULL
, self
);
94 PyObject
*ret
= PyString_FromFormat("dom_sid('%s')", str
);
99 static int py_dom_sid_init(PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
102 struct dom_sid
*sid
= py_talloc_get_ptr(self
);
103 const char *kwnames
[] = { "str", NULL
};
105 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|s", discard_const_p(char *, kwnames
), &str
))
108 if (str
!= NULL
&& !dom_sid_parse(str
, sid
)) {
109 PyErr_SetString(PyExc_TypeError
, "Unable to parse string");
116 static PyMethodDef py_dom_sid_extra_methods
[] = {
117 { "split", (PyCFunction
)py_dom_sid_split
, METH_NOARGS
,
118 "S.split() -> (domain_sid, rid)\n"
119 "Split a domain sid" },
124 static void py_dom_sid_patch(PyTypeObject
*type
)
126 type
->tp_init
= py_dom_sid_init
;
127 type
->tp_str
= py_dom_sid_str
;
128 type
->tp_repr
= py_dom_sid_repr
;
129 type
->tp_compare
= py_dom_sid_cmp
;
130 PyType_AddMethods(type
, py_dom_sid_extra_methods
);
133 #define PY_DOM_SID_PATCH py_dom_sid_patch
135 static PyObject
*py_descriptor_sacl_add(PyObject
*self
, PyObject
*args
)
137 struct security_descriptor
*desc
= py_talloc_get_ptr(self
);
139 struct security_ace
*ace
;
142 if (!PyArg_ParseTuple(args
, "O", &py_ace
))
145 ace
= py_talloc_get_ptr(py_ace
);
146 status
= security_descriptor_sacl_add(desc
, ace
);
147 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
151 static PyObject
*py_descriptor_dacl_add(PyObject
*self
, PyObject
*args
)
153 struct security_descriptor
*desc
= py_talloc_get_ptr(self
);
155 struct security_ace
*ace
;
158 if (!PyArg_ParseTuple(args
, "O", &py_ace
))
161 ace
= py_talloc_get_ptr(py_ace
);
163 status
= security_descriptor_dacl_add(desc
, ace
);
164 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
168 static PyObject
*py_descriptor_dacl_del(PyObject
*self
, PyObject
*args
)
170 struct security_descriptor
*desc
= py_talloc_get_ptr(self
);
175 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
178 sid
= py_talloc_get_ptr(py_sid
);
179 status
= security_descriptor_dacl_del(desc
, sid
);
180 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
184 static PyObject
*py_descriptor_sacl_del(PyObject
*self
, PyObject
*args
)
186 struct security_descriptor
*desc
= py_talloc_get_ptr(self
);
191 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
194 sid
= py_talloc_get_ptr(py_sid
);
195 status
= security_descriptor_sacl_del(desc
, sid
);
196 PyErr_NTSTATUS_IS_ERR_RAISE(status
);
200 static PyObject
*py_descriptor_new(PyTypeObject
*self
, PyObject
*args
, PyObject
*kwargs
)
202 return py_talloc_steal(self
, security_descriptor_initialise(NULL
));
205 static PyObject
*py_descriptor_from_sddl(PyObject
*self
, PyObject
*args
)
207 struct security_descriptor
*secdesc
;
212 if (!PyArg_ParseTuple(args
, "sO!", &sddl
, &dom_sid_Type
, &py_sid
))
215 sid
= py_talloc_get_ptr(py_sid
);
217 secdesc
= sddl_decode(NULL
, sddl
, sid
);
218 if (secdesc
== NULL
) {
219 PyErr_SetString(PyExc_TypeError
, "Unable to parse SDDL");
223 return py_talloc_steal((PyTypeObject
*)self
, secdesc
);
226 static PyObject
*py_descriptor_as_sddl(PyObject
*self
, PyObject
*args
)
229 PyObject
*py_sid
= Py_None
;
230 struct security_descriptor
*desc
= py_talloc_get_ptr(self
);
234 if (!PyArg_ParseTuple(args
, "|O!", &dom_sid_Type
, &py_sid
))
237 if (py_sid
!= Py_None
)
238 sid
= py_talloc_get_ptr(py_sid
);
242 text
= sddl_encode(NULL
, desc
, sid
);
244 ret
= PyString_FromString(text
);
251 static PyMethodDef py_descriptor_extra_methods
[] = {
252 { "sacl_add", (PyCFunction
)py_descriptor_sacl_add
, METH_VARARGS
,
253 "S.sacl_add(ace) -> None\n"
254 "Add a security ace to this security descriptor" },
255 { "dacl_add", (PyCFunction
)py_descriptor_dacl_add
, METH_VARARGS
,
257 { "dacl_del", (PyCFunction
)py_descriptor_dacl_del
, METH_VARARGS
,
259 { "sacl_del", (PyCFunction
)py_descriptor_sacl_del
, METH_VARARGS
,
261 { "from_sddl", (PyCFunction
)py_descriptor_from_sddl
, METH_VARARGS
|METH_CLASS
,
263 { "as_sddl", (PyCFunction
)py_descriptor_as_sddl
, METH_VARARGS
,
268 static void py_descriptor_patch(PyTypeObject
*type
)
270 type
->tp_new
= py_descriptor_new
;
271 PyType_AddMethods(type
, py_descriptor_extra_methods
);
274 #define PY_DESCRIPTOR_PATCH py_descriptor_patch
276 static PyObject
*py_token_is_sid(PyObject
*self
, PyObject
*args
)
280 struct security_token
*token
= py_talloc_get_ptr(self
);
281 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
284 sid
= py_talloc_get_ptr(py_sid
);
286 return PyBool_FromLong(security_token_is_sid(token
, sid
));
289 static PyObject
*py_token_has_sid(PyObject
*self
, PyObject
*args
)
293 struct security_token
*token
= py_talloc_get_ptr(self
);
294 if (!PyArg_ParseTuple(args
, "O", &py_sid
))
297 sid
= py_talloc_get_ptr(py_sid
);
299 return PyBool_FromLong(security_token_has_sid(token
, sid
));
302 static PyObject
*py_token_is_anonymous(PyObject
*self
)
304 struct security_token
*token
= py_talloc_get_ptr(self
);
306 return PyBool_FromLong(security_token_is_anonymous(token
));
309 static PyObject
*py_token_is_system(PyObject
*self
)
311 struct security_token
*token
= py_talloc_get_ptr(self
);
313 return PyBool_FromLong(security_token_is_system(token
));
316 static PyObject
*py_token_has_builtin_administrators(PyObject
*self
)
318 struct security_token
*token
= py_talloc_get_ptr(self
);
320 return PyBool_FromLong(security_token_has_builtin_administrators(token
));
323 static PyObject
*py_token_has_nt_authenticated_users(PyObject
*self
)
325 struct security_token
*token
= py_talloc_get_ptr(self
);
327 return PyBool_FromLong(security_token_has_nt_authenticated_users(token
));
330 static PyObject
*py_token_has_privilege(PyObject
*self
, PyObject
*args
)
333 struct security_token
*token
= py_talloc_get_ptr(self
);
335 if (!PyArg_ParseTuple(args
, "i", &priv
))
338 return PyBool_FromLong(security_token_has_privilege(token
, priv
));
341 static PyObject
*py_token_set_privilege(PyObject
*self
, PyObject
*args
)
344 struct security_token
*token
= py_talloc_get_ptr(self
);
346 if (!PyArg_ParseTuple(args
, "i", &priv
))
349 security_token_set_privilege(token
, priv
);
353 static PyObject
*py_token_new(PyTypeObject
*self
, PyObject
*args
, PyObject
*kwargs
)
355 return py_talloc_steal(self
, security_token_initialise(NULL
));
358 static PyMethodDef py_token_extra_methods
[] = {
359 { "is_sid", (PyCFunction
)py_token_is_sid
, METH_VARARGS
,
360 "S.is_sid(sid) -> bool\n"
361 "Check whether this token is of the specified SID." },
362 { "has_sid", (PyCFunction
)py_token_has_sid
, METH_VARARGS
,
364 { "is_anonymous", (PyCFunction
)py_token_is_anonymous
, METH_NOARGS
,
365 "S.is_anonymus() -> bool\n"
366 "Check whether this is an anonymous token." },
367 { "is_system", (PyCFunction
)py_token_is_system
, METH_NOARGS
,
369 { "has_builtin_administrators", (PyCFunction
)py_token_has_builtin_administrators
, METH_NOARGS
,
371 { "has_nt_authenticated_users", (PyCFunction
)py_token_has_nt_authenticated_users
, METH_NOARGS
,
373 { "has_privilege", (PyCFunction
)py_token_has_privilege
, METH_VARARGS
,
375 { "set_privilege", (PyCFunction
)py_token_set_privilege
, METH_VARARGS
,
380 #define PY_TOKEN_PATCH py_token_patch
381 static void py_token_patch(PyTypeObject
*type
)
383 type
->tp_new
= py_token_new
;
384 PyType_AddMethods(type
, py_token_extra_methods
);
387 static PyObject
*py_privilege_name(PyObject
*self
, PyObject
*args
)
390 if (!PyArg_ParseTuple(args
, "i", &priv
))
393 return PyString_FromString(sec_privilege_name(priv
));
396 static PyObject
*py_privilege_id(PyObject
*self
, PyObject
*args
)
400 if (!PyArg_ParseTuple(args
, "s", &name
))
403 return PyInt_FromLong(sec_privilege_id(name
));
406 static PyObject
*py_random_sid(PyObject
*self
)
410 char *str
= talloc_asprintf(NULL
, "S-1-5-21-%u-%u-%u",
411 (unsigned)generate_random(),
412 (unsigned)generate_random(),
413 (unsigned)generate_random());
415 sid
= dom_sid_parse_talloc(NULL
, str
);
417 ret
= py_talloc_steal(&dom_sid_Type
, sid
);
421 static PyMethodDef py_mod_security_extra_methods
[] = {
422 { "random_sid", (PyCFunction
)py_random_sid
, METH_NOARGS
, NULL
},
423 { "privilege_id", (PyCFunction
)py_privilege_id
, METH_VARARGS
, NULL
},
424 { "privilege_name", (PyCFunction
)py_privilege_name
, METH_VARARGS
, NULL
},
428 static void py_mod_security_patch(PyObject
*m
)
431 for (i
= 0; py_mod_security_extra_methods
[i
].ml_name
; i
++) {
432 PyObject
*descr
= PyCFunction_New(&py_mod_security_extra_methods
[i
], NULL
);
433 PyModule_AddObject(m
, py_mod_security_extra_methods
[i
].ml_name
,
438 #define PY_MOD_SECURITY_PATCH py_mod_security_patch