python/py_lsa.c

説明を見る。
00001 /* 
00002    Python wrappers for DCERPC/SMB client routines.
00003 
00004    Copyright (C) Tim Potter, 2002
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "python/py_lsa.h"
00022 
00023 PyObject *new_lsa_policy_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00024                                     POLICY_HND *pol)
00025 {
00026         lsa_policy_hnd_object *o;
00027 
00028         o = PyObject_New(lsa_policy_hnd_object, &lsa_policy_hnd_type);
00029 
00030         o->cli = cli;
00031         o->mem_ctx = mem_ctx;
00032         memcpy(&o->pol, pol, sizeof(POLICY_HND));
00033 
00034         return (PyObject*)o;
00035 }
00036 
00037 /* 
00038  * Exceptions raised by this module 
00039  */
00040 
00041 PyObject *lsa_error;            /* This indicates a non-RPC related error
00042                                    such as name lookup failure */
00043 
00044 PyObject *lsa_ntstatus;         /* This exception is raised when a RPC call
00045                                    returns a status code other than
00046                                    NT_STATUS_OK */
00047 
00048 /*
00049  * Open/close lsa handles
00050  */
00051 
00052 static PyObject *lsa_open_policy(PyObject *self, PyObject *args, 
00053                                 PyObject *kw) 
00054 {
00055         static char *kwlist[] = { "servername", "creds", "access", NULL };
00056         char *server, *errstr;
00057         PyObject *creds = NULL, *result = NULL;
00058         uint32 desired_access = GENERIC_EXECUTE_ACCESS;
00059         struct cli_state *cli = NULL;
00060         NTSTATUS ntstatus;
00061         TALLOC_CTX *mem_ctx = NULL;
00062         POLICY_HND hnd;
00063 
00064         if (!PyArg_ParseTupleAndKeywords(
00065                     args, kw, "s|Oi", kwlist, &server, &creds, &desired_access))
00066                 return NULL;
00067 
00068         if (creds && creds != Py_None && !PyDict_Check(creds)) {
00069                 PyErr_SetString(PyExc_TypeError, 
00070                                 "credentials must be dictionary or None");
00071                 return NULL;
00072         }
00073 
00074         if (server[0] != '\\' || server[1] != '\\') {
00075                 PyErr_SetString(PyExc_ValueError, "UNC name required");
00076                 return NULL;
00077         }
00078 
00079         server += 2;
00080 
00081         if (!(cli = open_pipe_creds(server, creds, PI_LSARPC, &errstr))) {
00082                 PyErr_SetString(lsa_error, errstr);
00083                 free(errstr);
00084                 return NULL;
00085         }
00086 
00087         if (!(mem_ctx = talloc_init("lsa_open_policy"))) {
00088                 PyErr_SetString(lsa_error, "unable to init talloc context\n");
00089                 goto done;
00090         }
00091 
00092         ntstatus = rpccli_lsa_open_policy(
00093                 cli->pipe_list, mem_ctx, True, desired_access, &hnd);
00094 
00095         if (!NT_STATUS_IS_OK(ntstatus)) {
00096                 PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
00097                 goto done;
00098         }
00099 
00100         result = new_lsa_policy_hnd_object(cli->pipe_list, mem_ctx, &hnd);
00101 
00102 done:
00103         if (!result) {
00104                 if (cli)
00105                         cli_shutdown(cli);
00106 
00107                 talloc_destroy(mem_ctx);
00108         }
00109 
00110         return result;
00111 }
00112 
00113 static PyObject *lsa_close(PyObject *self, PyObject *args, PyObject *kw) 
00114 {
00115         PyObject *po;
00116         lsa_policy_hnd_object *hnd;
00117         NTSTATUS result;
00118 
00119         /* Parse parameters */
00120 
00121         if (!PyArg_ParseTuple(args, "O!", &lsa_policy_hnd_type, &po))
00122                 return NULL;
00123 
00124         hnd = (lsa_policy_hnd_object *)po;
00125 
00126         /* Call rpc function */
00127 
00128         result = rpccli_lsa_close(hnd->cli, hnd->mem_ctx, &hnd->pol);
00129 
00130         /* Cleanup samba stuff */
00131 
00132         cli_shutdown(hnd->cli);
00133         talloc_destroy(hnd->mem_ctx);
00134 
00135         /* Return value */
00136 
00137         Py_INCREF(Py_None);
00138         return Py_None; 
00139 }
00140 
00141 static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
00142 {
00143         PyObject *py_names, *result = NULL;
00144         NTSTATUS ntstatus;
00145         lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
00146         int num_names, i;
00147         const char **names;
00148         DOM_SID *sids;
00149         TALLOC_CTX *mem_ctx = NULL;
00150         enum lsa_SidType *name_types;
00151 
00152         if (!PyArg_ParseTuple(args, "O", &py_names))
00153                 return NULL;
00154 
00155         if (!PyList_Check(py_names) && !PyString_Check(py_names)) {
00156                 PyErr_SetString(PyExc_TypeError, "must be list or string");
00157                 return NULL;
00158         }
00159 
00160         if (!(mem_ctx = talloc_init("lsa_lookup_names"))) {
00161                 PyErr_SetString(lsa_error, "unable to init talloc context\n");
00162                 goto done;
00163         }
00164 
00165         if (PyList_Check(py_names)) {
00166 
00167                 /* Convert list to char ** array */
00168 
00169                 num_names = PyList_Size(py_names);
00170                 names = (const char **)_talloc(mem_ctx, num_names * sizeof(char *));
00171                 
00172                 for (i = 0; i < num_names; i++) {
00173                         PyObject *obj = PyList_GetItem(py_names, i);
00174                         
00175                         names[i] = talloc_strdup(mem_ctx, PyString_AsString(obj));
00176                 }
00177 
00178         } else {
00179 
00180                 /* Just a single element */
00181 
00182                 num_names = 1;
00183                 names = (const char **)_talloc(mem_ctx, sizeof(char *));
00184 
00185                 names[0] = PyString_AsString(py_names);
00186         }
00187 
00188         ntstatus = rpccli_lsa_lookup_names(
00189                 hnd->cli, mem_ctx, &hnd->pol, num_names, names, 
00190                 NULL, &sids, &name_types);
00191 
00192         if (!NT_STATUS_IS_OK(ntstatus) && NT_STATUS_V(ntstatus) != 0x107) {
00193                 PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
00194                 goto done;
00195         }
00196 
00197         result = PyList_New(num_names);
00198 
00199         for (i = 0; i < num_names; i++) {
00200                 PyObject *sid_obj, *obj;
00201 
00202                 py_from_SID(&sid_obj, &sids[i]);
00203 
00204                 obj = Py_BuildValue("(Ni)", sid_obj, name_types[i]);
00205 
00206                 PyList_SetItem(result, i, obj);
00207         }
00208 
00209  done:
00210         talloc_destroy(mem_ctx);
00211         
00212         return result;
00213 }
00214 
00215 static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, 
00216                                  PyObject *kw) 
00217 {
00218         PyObject *py_sids, *result = NULL;
00219         NTSTATUS ntstatus;
00220         int num_sids, i;
00221         char **domains, **names;
00222         uint32 *types;
00223         lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
00224         TALLOC_CTX *mem_ctx = NULL;
00225         DOM_SID *sids;
00226 
00227         if (!PyArg_ParseTuple(args, "O", &py_sids))
00228                 return NULL;
00229 
00230         if (!PyList_Check(py_sids) && !PyString_Check(py_sids)) {
00231                 PyErr_SetString(PyExc_TypeError, "must be list or string");
00232                 return NULL;
00233         }
00234 
00235         if (!(mem_ctx = talloc_init("lsa_lookup_sids"))) {
00236                 PyErr_SetString(lsa_error, "unable to init talloc context\n");
00237                 goto done;
00238         }
00239 
00240         if (PyList_Check(py_sids)) {
00241 
00242                 /* Convert dictionary to char ** array */
00243                 
00244                 num_sids = PyList_Size(py_sids);
00245                 sids = (DOM_SID *)_talloc(mem_ctx, num_sids * sizeof(DOM_SID));
00246                 
00247                 memset(sids, 0, num_sids * sizeof(DOM_SID));
00248                 
00249                 for (i = 0; i < num_sids; i++) {
00250                         PyObject *obj = PyList_GetItem(py_sids, i);
00251                         
00252                         if (!string_to_sid(&sids[i], PyString_AsString(obj))) {
00253                                 PyErr_SetString(PyExc_ValueError, "string_to_sid failed");
00254                                 goto done;
00255                         }
00256                 }
00257 
00258         } else {
00259 
00260                 /* Just a single element */
00261 
00262                 num_sids = 1;
00263                 sids = (DOM_SID *)_talloc(mem_ctx, sizeof(DOM_SID));
00264 
00265                 if (!string_to_sid(&sids[0], PyString_AsString(py_sids))) {
00266                         PyErr_SetString(PyExc_ValueError, "string_to_sid failed");
00267                         goto done;
00268                 }
00269         }
00270 
00271         ntstatus = rpccli_lsa_lookup_sids(
00272                 hnd->cli, mem_ctx, &hnd->pol, num_sids, sids, &domains, 
00273                 &names, &types);
00274 
00275         if (!NT_STATUS_IS_OK(ntstatus)) {
00276                 PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
00277                 goto done;
00278         }
00279 
00280         result = PyList_New(num_sids);
00281 
00282         for (i = 0; i < num_sids; i++) {
00283                 PyObject *obj;
00284 
00285                 obj = Py_BuildValue("{sssssi}", "username", names[i],
00286                                     "domain", domains[i], "name_type", 
00287                                     types[i]);
00288 
00289                 PyList_SetItem(result, i, obj);
00290         }
00291 
00292  done:
00293         talloc_destroy(mem_ctx);
00294 
00295         return result;
00296 }
00297 
00298 static PyObject *lsa_enum_trust_dom(PyObject *self, PyObject *args)
00299 {
00300         lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
00301         NTSTATUS ntstatus;
00302         uint32 enum_ctx = 0, num_domains, i;
00303         char **domain_names;
00304         DOM_SID *domain_sids;
00305         PyObject *result;
00306 
00307         if (!PyArg_ParseTuple(args, ""))
00308                 return NULL;
00309         
00310         ntstatus = rpccli_lsa_enum_trust_dom(
00311                 hnd->cli, hnd->mem_ctx, &hnd->pol, &enum_ctx,
00312                 &num_domains, &domain_names, &domain_sids);
00313 
00314         if (!NT_STATUS_IS_OK(ntstatus)) {
00315                 PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
00316                 return NULL;
00317         }
00318 
00319         result = PyList_New(num_domains);
00320 
00321         for (i = 0; i < num_domains; i++) {
00322                 fstring sid_str;
00323 
00324                 sid_to_string(sid_str, &domain_sids[i]);
00325                 PyList_SetItem(
00326                         result, i, 
00327                         Py_BuildValue("(ss)", domain_names[i], sid_str));
00328         }
00329 
00330         return result;
00331 }
00332 
00333 /*
00334  * Method dispatch tables
00335  */
00336 
00337 static PyMethodDef lsa_hnd_methods[] = {
00338 
00339         /* SIDs<->names */
00340 
00341         { "lookup_sids", (PyCFunction)lsa_lookup_sids, 
00342           METH_VARARGS | METH_KEYWORDS,
00343           "Convert sids to names." },
00344 
00345         { "lookup_names", (PyCFunction)lsa_lookup_names, 
00346           METH_VARARGS | METH_KEYWORDS,
00347           "Convert names to sids." },
00348 
00349         /* Trusted domains */
00350 
00351         { "enum_trusted_domains", (PyCFunction)lsa_enum_trust_dom, 
00352           METH_VARARGS, 
00353           "Enumerate trusted domains." },
00354 
00355         { NULL }
00356 };
00357 
00358 static void py_lsa_policy_hnd_dealloc(PyObject* self)
00359 {
00360         PyObject_Del(self);
00361 }
00362 
00363 static PyObject *py_lsa_policy_hnd_getattr(PyObject *self, char *attrname)
00364 {
00365         return Py_FindMethod(lsa_hnd_methods, self, attrname);
00366 }
00367 
00368 PyTypeObject lsa_policy_hnd_type = {
00369         PyObject_HEAD_INIT(NULL)
00370         0,
00371         "LSA Policy Handle",
00372         sizeof(lsa_policy_hnd_object),
00373         0,
00374         py_lsa_policy_hnd_dealloc, /*tp_dealloc*/
00375         0,          /*tp_print*/
00376         py_lsa_policy_hnd_getattr,          /*tp_getattr*/
00377         0,          /*tp_setattr*/
00378         0,          /*tp_compare*/
00379         0,          /*tp_repr*/
00380         0,          /*tp_as_number*/
00381         0,          /*tp_as_sequence*/
00382         0,          /*tp_as_mapping*/
00383         0,          /*tp_hash */
00384 };
00385 
00386 static PyMethodDef lsa_methods[] = {
00387 
00388         /* Open/close lsa handles */
00389         
00390         { "open_policy", (PyCFunction)lsa_open_policy, 
00391           METH_VARARGS | METH_KEYWORDS, 
00392           "Open a policy handle" },
00393         
00394         { "close", (PyCFunction)lsa_close, 
00395           METH_VARARGS, 
00396           "Close a policy handle" },
00397 
00398         /* Other stuff - this should really go into a samba config module
00399            but for the moment let's leave it here. */
00400 
00401         { "setup_logging", (PyCFunction)py_setup_logging, 
00402           METH_VARARGS | METH_KEYWORDS, 
00403           "Set up debug logging.\n"
00404 "\n"
00405 "Initialises Samba's debug logging system.  One argument is expected which\n"
00406 "is a boolean specifying whether debugging is interactive and sent to stdout\n"
00407 "or logged to a file.\n"
00408 "\n"
00409 "Example:\n"
00410 "\n"
00411 ">>> lsa.setup_logging(interactive = 1)" },
00412 
00413         { "get_debuglevel", (PyCFunction)get_debuglevel, 
00414           METH_VARARGS, 
00415           "Set the current debug level.\n"
00416 "\n"
00417 "Example:\n"
00418 "\n"
00419 ">>> lsa.get_debuglevel()\n"
00420 "0" },
00421 
00422         { "set_debuglevel", (PyCFunction)set_debuglevel, 
00423           METH_VARARGS, 
00424           "Get the current debug level.\n"
00425 "\n"
00426 "Example:\n"
00427 "\n"
00428 ">>> lsa.set_debuglevel(10)" },
00429 
00430         { NULL }
00431 };
00432 
00433 static struct const_vals {
00434         char *name;
00435         uint32 value;
00436 } module_const_vals[] = {
00437         { NULL }
00438 };
00439 
00440 static void const_init(PyObject *dict)
00441 {
00442         struct const_vals *tmp;
00443         PyObject *obj;
00444 
00445         for (tmp = module_const_vals; tmp->name; tmp++) {
00446                 obj = PyInt_FromLong(tmp->value);
00447                 PyDict_SetItemString(dict, tmp->name, obj);
00448                 Py_DECREF(obj);
00449         }
00450 }
00451 
00452 /*
00453  * Module initialisation 
00454  */
00455 
00456 void initlsa(void)
00457 {
00458         PyObject *module, *dict;
00459 
00460         /* Initialise module */
00461 
00462         module = Py_InitModule("lsa", lsa_methods);
00463         dict = PyModule_GetDict(module);
00464 
00465         lsa_error = PyErr_NewException("lsa.error", NULL, NULL);
00466         PyDict_SetItemString(dict, "error", lsa_error);
00467 
00468         lsa_ntstatus = PyErr_NewException("lsa.ntstatus", NULL, NULL);
00469         PyDict_SetItemString(dict, "ntstatus", lsa_ntstatus);
00470 
00471         /* Initialise policy handle object */
00472 
00473         lsa_policy_hnd_type.ob_type = &PyType_Type;
00474 
00475         /* Initialise constants */
00476 
00477         const_init(dict);
00478 
00479         /* Do samba initialisation */
00480 
00481         py_samba_init();
00482 
00483         setup_logging("lsa", True);
00484         DEBUGLEVEL = 10;
00485 }

Sambaに対してSat Aug 29 21:23:14 2009に生成されました。  doxygen 1.4.7