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