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 20#include "includes.h" 21#include <tevent.h> 22#include <Python.h> 23#include "libcli/util/pyerrors.h" 24#include "lib/registry/registry.h" 25#include "scripting/python/modules.h" /* for py_iconv_convenience() */ 26#include <pytalloc.h> 27#include "auth/credentials/pycredentials.h" 28#include "param/pyparam.h" 29 30#ifndef Py_RETURN_NONE 31#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None 32#endif 33 34PyAPI_DATA(PyTypeObject) PyRegistryKey; 35PyAPI_DATA(PyTypeObject) PyRegistry; 36PyAPI_DATA(PyTypeObject) PyHiveKey; 37 38/*#define PyRegistryKey_AsRegistryKey(obj) py_talloc_get_type(obj, struct registry_key)*/ 39#define PyRegistry_AsRegistryContext(obj) ((struct registry_context *)py_talloc_get_ptr(obj)) 40#define PyHiveKey_AsHiveKey(obj) ((struct hive_key*)py_talloc_get_ptr(obj)) 41 42 43static PyObject *py_get_predefined_key_by_name(PyObject *self, PyObject *args) 44{ 45 char *name; 46 WERROR result; 47 struct registry_context *ctx = PyRegistry_AsRegistryContext(self); 48 struct registry_key *key; 49 50 if (!PyArg_ParseTuple(args, "s", &name)) 51 return NULL; 52 53 result = reg_get_predefined_key_by_name(ctx, name, &key); 54 PyErr_WERROR_IS_ERR_RAISE(result); 55 56 return py_talloc_steal(&PyRegistryKey, key); 57} 58 59static PyObject *py_key_del_abs(PyObject *self, PyObject *args) 60{ 61 char *path; 62 WERROR result; 63 struct registry_context *ctx = PyRegistry_AsRegistryContext(self); 64 65 if (!PyArg_ParseTuple(args, "s", &path)) 66 return NULL; 67 68 result = reg_key_del_abs(ctx, path); 69 PyErr_WERROR_IS_ERR_RAISE(result); 70 71 Py_RETURN_NONE; 72} 73 74static PyObject *py_get_predefined_key(PyObject *self, PyObject *args) 75{ 76 uint32_t hkey; 77 struct registry_context *ctx = PyRegistry_AsRegistryContext(self); 78 WERROR result; 79 struct registry_key *key; 80 81 if (!PyArg_ParseTuple(args, "I", &hkey)) 82 return NULL; 83 84 result = reg_get_predefined_key(ctx, hkey, &key); 85 PyErr_WERROR_IS_ERR_RAISE(result); 86 87 return py_talloc_steal(&PyRegistryKey, key); 88} 89 90static PyObject *py_diff_apply(PyObject *self, PyObject *args) 91{ 92 char *filename; 93 WERROR result; 94 struct registry_context *ctx = PyRegistry_AsRegistryContext(self); 95 if (!PyArg_ParseTuple(args, "s", &filename)) 96 return NULL; 97 98 result = reg_diff_apply(ctx, py_iconv_convenience(NULL), filename); 99 PyErr_WERROR_IS_ERR_RAISE(result); 100 101 Py_RETURN_NONE; 102} 103 104static PyObject *py_mount_hive(PyObject *self, PyObject *args) 105{ 106 struct registry_context *ctx = PyRegistry_AsRegistryContext(self); 107 uint32_t hkey; 108 PyObject *py_hivekey, *py_elements = Py_None; 109 const char **elements; 110 WERROR result; 111 112 if (!PyArg_ParseTuple(args, "OI|O", &py_hivekey, &hkey, &py_elements)) 113 return NULL; 114 115 if (!PyList_Check(py_elements) && py_elements != Py_None) { 116 PyErr_SetString(PyExc_TypeError, "Expected list of elements"); 117 return NULL; 118 } 119 120 if (py_elements == Py_None) { 121 elements = NULL; 122 } else { 123 int i; 124 elements = talloc_array(NULL, const char *, PyList_Size(py_elements)); 125 for (i = 0; i < PyList_Size(py_elements); i++) 126 elements[i] = PyString_AsString(PyList_GetItem(py_elements, i)); 127 } 128 129 SMB_ASSERT(ctx != NULL); 130 131 result = reg_mount_hive(ctx, PyHiveKey_AsHiveKey(py_hivekey), hkey, elements); 132 PyErr_WERROR_IS_ERR_RAISE(result); 133 134 Py_RETURN_NONE; 135} 136 137static PyObject *registry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) 138{ 139 WERROR result; 140 struct registry_context *ctx; 141 result = reg_open_local(NULL, &ctx); 142 PyErr_WERROR_IS_ERR_RAISE(result); 143 return py_talloc_steal(&PyRegistry, ctx); 144} 145 146static PyMethodDef registry_methods[] = { 147 { "get_predefined_key_by_name", py_get_predefined_key_by_name, METH_VARARGS, 148 "S.get_predefined_key_by_name(name) -> key\n" 149 "Find a predefined key by name" }, 150 { "key_del_abs", py_key_del_abs, METH_VARARGS, "S.key_del_abs(name) -> None\n" 151 "Delete a key by absolute path." }, 152 { "get_predefined_key", py_get_predefined_key, METH_VARARGS, "S.get_predefined_key(hkey_id) -> key\n" 153 "Find a predefined key by id" }, 154 { "diff_apply", py_diff_apply, METH_VARARGS, "S.diff_apply(filename) -> None\n" 155 "Apply the diff from the specified file" }, 156 { "mount_hive", py_mount_hive, METH_VARARGS, "S.mount_hive(key, key_id, elements=None) -> None\n" 157 "Mount the specified key at the specified path." }, 158 { NULL } 159}; 160 161PyTypeObject PyRegistry = { 162 .tp_name = "Registry", 163 .tp_methods = registry_methods, 164 .tp_new = registry_new, 165 .tp_basicsize = sizeof(py_talloc_Object), 166 .tp_dealloc = py_talloc_dealloc, 167 .tp_flags = Py_TPFLAGS_DEFAULT, 168}; 169 170static PyObject *py_hive_key_del(PyObject *self, PyObject *args) 171{ 172 char *name; 173 struct hive_key *key = PyHiveKey_AsHiveKey(self); 174 WERROR result; 175 176 if (!PyArg_ParseTuple(args, "s", &name)) 177 return NULL; 178 179 result = hive_key_del(key, name); 180 181 PyErr_WERROR_IS_ERR_RAISE(result); 182 183 Py_RETURN_NONE; 184} 185 186static PyObject *py_hive_key_flush(PyObject *self) 187{ 188 WERROR result; 189 struct hive_key *key = PyHiveKey_AsHiveKey(self); 190 191 result = hive_key_flush(key); 192 PyErr_WERROR_IS_ERR_RAISE(result); 193 194 Py_RETURN_NONE; 195} 196 197static PyObject *py_hive_key_del_value(PyObject *self, PyObject *args) 198{ 199 char *name; 200 WERROR result; 201 struct hive_key *key = PyHiveKey_AsHiveKey(self); 202 203 if (!PyArg_ParseTuple(args, "s", &name)) 204 return NULL; 205 206 result = hive_key_del_value(key, name); 207 208 PyErr_WERROR_IS_ERR_RAISE(result); 209 210 Py_RETURN_NONE; 211} 212 213static PyObject *py_hive_key_set_value(PyObject *self, PyObject *args) 214{ 215 char *name; 216 uint32_t type; 217 DATA_BLOB value; 218 WERROR result; 219 struct hive_key *key = PyHiveKey_AsHiveKey(self); 220 221 if (!PyArg_ParseTuple(args, "siz#", &name, &type, &value.data, &value.length)) 222 return NULL; 223 224 if (value.data != NULL) 225 result = hive_key_set_value(key, name, type, value); 226 else 227 result = hive_key_del_value(key, name); 228 229 PyErr_WERROR_IS_ERR_RAISE(result); 230 231 Py_RETURN_NONE; 232} 233 234static PyMethodDef hive_key_methods[] = { 235 { "del", py_hive_key_del, METH_VARARGS, "S.del(name) -> None\n" 236 "Delete a subkey" }, 237 { "flush", (PyCFunction)py_hive_key_flush, METH_NOARGS, "S.flush() -> None\n" 238 "Flush this key to disk" }, 239 { "del_value", py_hive_key_del_value, METH_VARARGS, "S.del_value(name) -> None\n" 240 "Delete a value" }, 241 { "set_value", py_hive_key_set_value, METH_VARARGS, "S.set_value(name, type, data) -> None\n" 242 "Set a value" }, 243 { NULL } 244}; 245 246static PyObject *hive_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) 247{ 248 /* reg_open_hive */ 249 Py_RETURN_NONE; 250} 251 252PyTypeObject PyHiveKey = { 253 .tp_name = "HiveKey", 254 .tp_methods = hive_key_methods, 255 .tp_new = hive_open, 256 .tp_basicsize = sizeof(py_talloc_Object), 257 .tp_dealloc = py_talloc_dealloc, 258 .tp_flags = Py_TPFLAGS_DEFAULT, 259}; 260 261PyTypeObject PyRegistryKey = { 262 .tp_name = "RegistryKey", 263 .tp_basicsize = sizeof(py_talloc_Object), 264 .tp_dealloc = py_talloc_dealloc, 265 .tp_flags = Py_TPFLAGS_DEFAULT, 266}; 267 268static PyObject *py_open_samba(PyObject *self, PyObject *args, PyObject *kwargs) 269{ 270 const char *kwnames[] = { "lp_ctx", "session_info", NULL }; 271 struct registry_context *reg_ctx; 272 WERROR result; 273 struct loadparm_context *lp_ctx; 274 PyObject *py_lp_ctx, *py_session_info, *py_credentials; 275 struct auth_session_info *session_info; 276 struct cli_credentials *credentials; 277 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO", discard_const_p(char *, kwnames), 278 &py_lp_ctx, &py_session_info, &py_credentials)) 279 return NULL; 280 281 lp_ctx = lp_from_py_object(py_lp_ctx); 282 if (lp_ctx == NULL) { 283 PyErr_SetString(PyExc_TypeError, "Expected loadparm context"); 284 return NULL; 285 } 286 287 credentials = cli_credentials_from_py_object(py_credentials); 288 if (credentials == NULL) { 289 PyErr_SetString(PyExc_TypeError, "Expected credentials"); 290 return NULL; 291 } 292 293 session_info = NULL; /* FIXME */ 294 295 result = reg_open_samba(NULL, ®_ctx, NULL, 296 lp_ctx, session_info, credentials); 297 if (!W_ERROR_IS_OK(result)) { 298 PyErr_SetWERROR(result); 299 return NULL; 300 } 301 302 return py_talloc_steal(&PyRegistry, reg_ctx); 303} 304 305static PyObject *py_open_directory(PyObject *self, PyObject *args) 306{ 307 char *location; 308 WERROR result; 309 struct hive_key *key; 310 311 if (!PyArg_ParseTuple(args, "s", &location)) 312 return NULL; 313 314 result = reg_open_directory(NULL, location, &key); 315 PyErr_WERROR_IS_ERR_RAISE(result); 316 317 return py_talloc_steal(&PyHiveKey, key); 318} 319 320static PyObject *py_create_directory(PyObject *self, PyObject *args) 321{ 322 char *location; 323 WERROR result; 324 struct hive_key *key; 325 326 if (!PyArg_ParseTuple(args, "s", &location)) 327 return NULL; 328 329 result = reg_create_directory(NULL, location, &key); 330 PyErr_WERROR_IS_ERR_RAISE(result); 331 332 return py_talloc_steal(&PyHiveKey, key); 333} 334 335static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwargs) 336{ 337 const char *kwnames[] = { "location", "session_info", "credentials", "lp_ctx", NULL }; 338 PyObject *py_session_info = Py_None, *py_credentials = Py_None, *py_lp_ctx = Py_None; 339 WERROR result; 340 char *location; 341 struct loadparm_context *lp_ctx; 342 struct cli_credentials *credentials; 343 struct hive_key *key; 344 struct auth_session_info *session_info; 345 346 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO", 347 discard_const_p(char *, kwnames), 348 &location, 349 &py_session_info, &py_credentials, 350 &py_lp_ctx)) 351 return NULL; 352 353 lp_ctx = lp_from_py_object(py_lp_ctx); 354 if (lp_ctx == NULL) { 355 PyErr_SetString(PyExc_TypeError, "Expected loadparm context"); 356 return NULL; 357 } 358 359 credentials = cli_credentials_from_py_object(py_credentials); 360 if (credentials == NULL) { 361 PyErr_SetString(PyExc_TypeError, "Expected credentials"); 362 return NULL; 363 } 364 365 session_info = NULL; /* FIXME */ 366 367 result = reg_open_ldb_file(NULL, location, session_info, credentials, 368 tevent_context_init(NULL), lp_ctx, &key); 369 PyErr_WERROR_IS_ERR_RAISE(result); 370 371 return py_talloc_steal(&PyHiveKey, key); 372} 373 374static PyObject *py_str_regtype(PyObject *self, PyObject *args) 375{ 376 int regtype; 377 378 if (!PyArg_ParseTuple(args, "i", ®type)) 379 return NULL; 380 381 return PyString_FromString(str_regtype(regtype)); 382} 383 384static PyObject *py_get_predef_name(PyObject *self, PyObject *args) 385{ 386 uint32_t hkey; 387 const char *str; 388 389 if (!PyArg_ParseTuple(args, "I", &hkey)) 390 return NULL; 391 392 str = reg_get_predef_name(hkey); 393 if (str == NULL) 394 Py_RETURN_NONE; 395 return PyString_FromString(str); 396} 397 398static PyMethodDef py_registry_methods[] = { 399 { "open_samba", (PyCFunction)py_open_samba, METH_VARARGS|METH_KEYWORDS, "open_samba() -> reg" }, 400 { "open_directory", py_open_directory, METH_VARARGS, "open_dir(location) -> key" }, 401 { "create_directory", py_create_directory, METH_VARARGS, "create_dir(location) -> key" }, 402 { "open_ldb", (PyCFunction)py_open_ldb_file, METH_VARARGS|METH_KEYWORDS, "open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key" }, 403 { "str_regtype", py_str_regtype, METH_VARARGS, "str_regtype(int) -> str" }, 404 { "get_predef_name", py_get_predef_name, METH_VARARGS, "get_predef_name(hkey) -> str" }, 405 { NULL } 406}; 407 408void initregistry(void) 409{ 410 PyObject *m; 411 412 if (PyType_Ready(&PyHiveKey) < 0) 413 return; 414 415 if (PyType_Ready(&PyRegistry) < 0) 416 return; 417 418 if (PyType_Ready(&PyRegistryKey) < 0) 419 return; 420 421 m = Py_InitModule3("registry", py_registry_methods, "Registry"); 422 if (m == NULL) 423 return; 424 425 PyModule_AddObject(m, "HKEY_CLASSES_ROOT", PyInt_FromLong(HKEY_CLASSES_ROOT)); 426 PyModule_AddObject(m, "HKEY_CURRENT_USER", PyInt_FromLong(HKEY_CURRENT_USER)); 427 PyModule_AddObject(m, "HKEY_LOCAL_MACHINE", PyInt_FromLong(HKEY_LOCAL_MACHINE)); 428 PyModule_AddObject(m, "HKEY_USERS", PyInt_FromLong(HKEY_USERS)); 429 PyModule_AddObject(m, "HKEY_PERFORMANCE_DATA", PyInt_FromLong(HKEY_PERFORMANCE_DATA)); 430 PyModule_AddObject(m, "HKEY_CURRENT_CONFIG", PyInt_FromLong(HKEY_CURRENT_CONFIG)); 431 PyModule_AddObject(m, "HKEY_DYN_DATA", PyInt_FromLong(HKEY_DYN_DATA)); 432 PyModule_AddObject(m, "HKEY_PERFORMANCE_TEXT", PyInt_FromLong(HKEY_PERFORMANCE_TEXT)); 433 PyModule_AddObject(m, "HKEY_PERFORMANCE_NLSTEXT", PyInt_FromLong(HKEY_PERFORMANCE_NLSTEXT)); 434 435 Py_INCREF(&PyRegistry); 436 PyModule_AddObject(m, "Registry", (PyObject *)&PyRegistry); 437 438 Py_INCREF(&PyHiveKey); 439 PyModule_AddObject(m, "HiveKey", (PyObject *)&PyHiveKey); 440 441 Py_INCREF(&PyRegistryKey); 442 PyModule_AddObject(m, "RegistryKey", (PyObject *)&PyRegistryKey); 443} 444