python/py_smb.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_smb.h"
00022 
00023 /* Create a new cli_state python object */
00024 
00025 PyObject *new_cli_state_object(struct cli_state *cli)
00026 {
00027         cli_state_object *o;
00028 
00029         o = PyObject_New(cli_state_object, &cli_state_type);
00030 
00031         o->cli = cli;
00032 
00033         return (PyObject*)o;
00034 }
00035 
00036 static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw)
00037 {
00038         static char *kwlist[] = { "server", NULL };
00039         struct cli_state *cli;
00040         char *server;
00041         struct in_addr ip;
00042 
00043         if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server))
00044                 return NULL;
00045 
00046         if (!(cli = cli_initialise()))
00047                 return NULL;
00048 
00049         ZERO_STRUCT(ip);
00050 
00051         if (!NT_STATUS_IS_OK(cli_connect(cli, server, &ip)))
00052                 return NULL;
00053 
00054         return new_cli_state_object(cli);
00055 }
00056 
00057 static PyObject *py_smb_session_request(PyObject *self, PyObject *args,
00058                                         PyObject *kw)
00059 {
00060         cli_state_object *cli = (cli_state_object *)self;
00061         static char *kwlist[] = { "called", "calling", NULL };
00062         char *calling_name = NULL, *called_name;
00063         struct nmb_name calling, called;
00064         BOOL result;
00065 
00066         if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s", kwlist, &called_name, 
00067                                          &calling_name))
00068                 return NULL;
00069 
00070         if (!calling_name)
00071                 calling_name = global_myname();
00072 
00073         make_nmb_name(&calling, calling_name, 0x00);
00074         make_nmb_name(&called, called_name, 0x20);
00075 
00076         result = cli_session_request(cli->cli, &calling, &called);
00077 
00078         return Py_BuildValue("i", result);
00079 }
00080                                       
00081 static PyObject *py_smb_negprot(PyObject *self, PyObject *args, PyObject *kw)
00082 {
00083         cli_state_object *cli = (cli_state_object *)self;
00084         static char *kwlist[] = { NULL };
00085         BOOL result;
00086 
00087         if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
00088                 return NULL;
00089 
00090         result = cli_negprot(cli->cli);
00091 
00092         return Py_BuildValue("i", result);
00093 }
00094 
00095 static PyObject *py_smb_session_setup(PyObject *self, PyObject *args, 
00096                                       PyObject *kw)
00097 {
00098         cli_state_object *cli = (cli_state_object *)self;
00099         static char *kwlist[] = { "creds", NULL };
00100         PyObject *creds;
00101         char *username, *domain, *password, *errstr;
00102         NTSTATUS result;
00103 
00104         if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds))
00105                 return NULL;
00106 
00107         if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) {
00108                 free(errstr);
00109                 return NULL;
00110         }
00111 
00112         result = cli_session_setup(
00113                 cli->cli, username, password, strlen(password) + 1,
00114                 password, strlen(password) + 1, domain);
00115 
00116         if (cli_is_error(cli->cli)) {
00117                 PyErr_SetString(PyExc_RuntimeError, "session setup failed");
00118                 return NULL;
00119         }
00120 
00121         return Py_BuildValue("i", NT_STATUS_IS_OK(result));
00122 }
00123 
00124 static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw)
00125 {
00126         cli_state_object *cli = (cli_state_object *)self;
00127         static char *kwlist[] = { "service", NULL };
00128         char *service;
00129         BOOL result;
00130 
00131         if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &service))
00132                 return NULL;
00133 
00134         result = cli_send_tconX(
00135                 cli->cli, service, strequal(service, "IPC$") ? "IPC" : 
00136                 "?????", "", 1);
00137 
00138         if (cli_is_error(cli->cli)) {
00139                 PyErr_SetString(PyExc_RuntimeError, "tconx failed");
00140                 return NULL;
00141         }
00142 
00143         return Py_BuildValue("i", result);
00144 }
00145 
00146 static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args,
00147                                        PyObject *kw)
00148 {
00149         cli_state_object *cli = (cli_state_object *)self;
00150         static char *kwlist[] = { "filename", "desired_access", 
00151                                   "file_attributes", "share_access",
00152                                   "create_disposition", "create_options",
00153                                   NULL };
00154         char *filename;
00155         uint32 desired_access, file_attributes = 0, 
00156                 share_access = FILE_SHARE_READ | FILE_SHARE_WRITE,
00157                 create_disposition = OPENX_FILE_EXISTS_OPEN, create_options = 0;
00158         int result;
00159 
00160         /* Parse parameters */
00161 
00162         if (!PyArg_ParseTupleAndKeywords(
00163                     args, kw, "si|iiii", kwlist, &filename, &desired_access,
00164                     &file_attributes, &share_access, &create_disposition,
00165                     &create_options))
00166                 return NULL;
00167 
00168         result = cli_nt_create_full(
00169                 cli->cli, filename, 0, desired_access, file_attributes,
00170                 share_access, create_disposition, create_options, 0);
00171 
00172         if (cli_is_error(cli->cli)) {
00173                 PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed");
00174                 return NULL;
00175         }
00176 
00177         /* Return FID */
00178 
00179         return PyInt_FromLong(result);
00180 }
00181 
00182 static PyObject *py_smb_open(PyObject *self, PyObject *args, PyObject *kw)
00183 {
00184         cli_state_object *cli = (cli_state_object *)self;
00185         static char *kwlist[] = { "filename", "flags", 
00186                                   "share_mode", NULL };
00187         char *filename;
00188         uint32 flags, share_mode = DENY_NONE;
00189         int result;
00190 
00191         /* Parse parameters */
00192 
00193         if (!PyArg_ParseTupleAndKeywords(
00194                     args, kw, "si|i", kwlist, &filename, &flags, &share_mode))
00195                 return NULL;
00196 
00197         result = cli_open(cli->cli, filename, flags, share_mode);
00198 
00199         if (cli_is_error(cli->cli)) {
00200                 PyErr_SetString(PyExc_RuntimeError, "open failed");
00201                 return NULL;
00202         }
00203 
00204         /* Return FID */
00205 
00206         return PyInt_FromLong(result);
00207 }
00208 
00209 static PyObject *py_smb_read(PyObject *self, PyObject *args, PyObject *kw)
00210 {
00211         cli_state_object *cli = (cli_state_object *)self;
00212         static char *kwlist[] = { "fnum", "offset", "size", NULL };
00213         int fnum, offset=0, size=0;
00214         ssize_t result;
00215         SMB_OFF_T fsize;
00216         char *data;
00217         PyObject *ret;
00218 
00219         /* Parse parameters */
00220 
00221         if (!PyArg_ParseTupleAndKeywords(
00222                     args, kw, "i|ii", kwlist, &fnum, &offset, &size))
00223                 return NULL;
00224 
00225         if (!cli_qfileinfo(cli->cli, fnum, NULL, &fsize, NULL, NULL,
00226                     NULL, NULL, NULL) &&
00227             !cli_getattrE(cli->cli, fnum, NULL, &fsize, NULL, NULL, NULL)) {
00228                 PyErr_SetString(PyExc_RuntimeError, "getattrib failed");
00229                 return NULL;
00230         }
00231 
00232         if (offset < 0)
00233                 offset = 0;
00234 
00235         if (size < 1 || size > fsize - offset)
00236                 size = fsize - offset;
00237 
00238         if (!(data = SMB_XMALLOC_ARRAY(char, size))) {
00239                 PyErr_SetString(PyExc_RuntimeError, "malloc failed");
00240                 return NULL;
00241         }
00242 
00243         result = cli_read(cli->cli, fnum, data, (off_t) offset, (size_t) size);
00244 
00245         if (result==-1 || cli_is_error(cli->cli)) {
00246                 SAFE_FREE(data);
00247                 PyErr_SetString(PyExc_RuntimeError, "read failed");
00248                 return NULL;
00249         }
00250 
00251         /* Return a python string */
00252 
00253         ret = Py_BuildValue("s#", data, result);
00254         SAFE_FREE(data);
00255 
00256         return ret;
00257 }
00258 
00259 static PyObject *py_smb_close(PyObject *self, PyObject *args,
00260                               PyObject *kw)
00261 {
00262         cli_state_object *cli = (cli_state_object *)self;
00263         static char *kwlist[] = { "fnum", NULL };
00264         BOOL result;
00265         int fnum;
00266 
00267         /* Parse parameters */
00268 
00269         if (!PyArg_ParseTupleAndKeywords(
00270                     args, kw, "i", kwlist, &fnum))
00271                 return NULL;
00272 
00273         result = cli_close(cli->cli, fnum);
00274 
00275         return PyInt_FromLong(result);
00276 }
00277 
00278 static PyObject *py_smb_unlink(PyObject *self, PyObject *args,
00279                                PyObject *kw)
00280 {
00281         cli_state_object *cli = (cli_state_object *)self;
00282         static char *kwlist[] = { "filename", NULL };
00283         char *filename;
00284         BOOL result;
00285 
00286         /* Parse parameters */
00287 
00288         if (!PyArg_ParseTupleAndKeywords(
00289                     args, kw, "s", kwlist, &filename))
00290                 return NULL;
00291 
00292         result = cli_unlink(cli->cli, filename);
00293 
00294         return PyInt_FromLong(result);
00295 }
00296 
00297 static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
00298                                       PyObject *kw)
00299 {
00300         cli_state_object *cli = (cli_state_object *)self;
00301         static char *kwlist[] = { "fnum", NULL };
00302         PyObject *result = NULL;
00303         SEC_DESC *secdesc = NULL;
00304         int fnum;
00305         TALLOC_CTX *mem_ctx = NULL;
00306 
00307         /* Parse parameters */
00308 
00309         if (!PyArg_ParseTupleAndKeywords(
00310                     args, kw, "i", kwlist, &fnum))
00311                 return NULL;
00312 
00313         mem_ctx = talloc_init("py_smb_query_secdesc");
00314 
00315         secdesc = cli_query_secdesc(cli->cli, fnum, mem_ctx);
00316 
00317         if (cli_is_error(cli->cli)) {
00318                 PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed");
00319                 goto done;
00320         }
00321 
00322         if (!secdesc) {
00323                 Py_INCREF(Py_None);
00324                 result = Py_None;
00325                 goto done;
00326         }
00327 
00328         if (!py_from_SECDESC(&result, secdesc)) {
00329                 PyErr_SetString(
00330                         PyExc_TypeError,
00331                         "Invalid security descriptor returned");
00332                 goto done;
00333         }
00334 
00335  done:
00336         talloc_destroy(mem_ctx);
00337 
00338         return result;
00339         
00340 }
00341 
00342 static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
00343                                     PyObject *kw)
00344 {
00345         cli_state_object *cli = (cli_state_object *)self;
00346         static char *kwlist[] = { "fnum", "security_descriptor", NULL };
00347         PyObject *result = NULL;
00348         PyObject *py_secdesc;
00349         SEC_DESC *secdesc;
00350         TALLOC_CTX *mem_ctx = NULL;
00351         int fnum;
00352         BOOL err;
00353 
00354         /* Parse parameters */
00355 
00356         if (!PyArg_ParseTupleAndKeywords(
00357                     args, kw, "iO", kwlist, &fnum, &py_secdesc))
00358                 return NULL;
00359 
00360         mem_ctx = talloc_init("py_smb_set_secdesc");
00361 
00362         if (!py_to_SECDESC(&secdesc, py_secdesc, mem_ctx)) {
00363                 PyErr_SetString(PyExc_TypeError, 
00364                                 "Invalid security descriptor");
00365                 goto done;
00366         }
00367 
00368         err = cli_set_secdesc(cli->cli, fnum, secdesc);
00369 
00370         if (cli_is_error(cli->cli)) {
00371                 PyErr_SetString(PyExc_RuntimeError, "set_secdesc failed");
00372                 goto done;
00373         }
00374 
00375         result =  PyInt_FromLong(err);
00376  done:
00377         talloc_destroy(mem_ctx);
00378 
00379         return result;
00380 }
00381 
00382 static PyMethodDef smb_hnd_methods[] = {
00383 
00384         /* Session and connection handling */
00385 
00386         { "session_request", (PyCFunction)py_smb_session_request, 
00387           METH_VARARGS | METH_KEYWORDS, "Request a session" },
00388 
00389         { "negprot", (PyCFunction)py_smb_negprot, 
00390           METH_VARARGS | METH_KEYWORDS, "Protocol negotiation" },
00391 
00392         { "session_setup", (PyCFunction)py_smb_session_setup,
00393           METH_VARARGS | METH_KEYWORDS, "Session setup" },
00394 
00395         { "tconx", (PyCFunction)py_smb_tconx,
00396           METH_VARARGS | METH_KEYWORDS, "Tree connect" },
00397 
00398         /* File operations */
00399 
00400         { "nt_create_andx", (PyCFunction)py_smb_nt_create_andx,
00401           METH_VARARGS | METH_KEYWORDS, "NT Create&X" },
00402 
00403         { "open", (PyCFunction)py_smb_open,
00404           METH_VARARGS | METH_KEYWORDS,
00405           "Open a file\n"
00406 "\n"
00407 "This function returns a fnum handle to an open file.  The file is\n"
00408 "opened with flags and optional share mode.  If unspecified, the\n"
00409 "default share mode is DENY_NONE\n"
00410 "\n"
00411 "Example:\n"
00412 "\n"
00413 ">>> fnum=conn.open(filename, os.O_RDONLY)" },
00414 
00415         { "read", (PyCFunction)py_smb_read,
00416           METH_VARARGS | METH_KEYWORDS,
00417           "Read from an open file\n"
00418 "\n"
00419 "This function returns a string read from an open file starting at\n"
00420 "offset for size bytes (until EOF is reached).  If unspecified, the\n"
00421 "default offset is 0, and default size is the remainder of the file.\n"
00422 "\n"
00423 "Example:\n"
00424 "\n"
00425 ">>> conn.read(fnum)           # read entire file\n"
00426 ">>> conn.read(fnum,5)         # read entire file from offset 5\n"
00427 ">>> conn.read(fnum,size=64)   # read 64 bytes from start of file\n"
00428 ">>> conn.read(fnum,4096,1024) # read 1024 bytes from offset 4096\n" },
00429 
00430         { "close", (PyCFunction)py_smb_close,
00431           METH_VARARGS | METH_KEYWORDS, "Close" },
00432 
00433         { "unlink", (PyCFunction)py_smb_unlink,
00434           METH_VARARGS | METH_KEYWORDS, "Unlink" },
00435 
00436         /* Security descriptors */
00437 
00438         { "query_secdesc", (PyCFunction)py_smb_query_secdesc,
00439           METH_VARARGS | METH_KEYWORDS, "Query security descriptor" },
00440 
00441         { "set_secdesc", (PyCFunction)py_smb_set_secdesc,
00442           METH_VARARGS | METH_KEYWORDS, "Set security descriptor" },
00443 
00444         { NULL }
00445 };
00446 
00447 /*
00448  * Method dispatch tables
00449  */
00450 
00451 static PyMethodDef smb_methods[] = {
00452 
00453         { "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS,
00454           "Connect to a host" },
00455 
00456         /* Other stuff - this should really go into a samba config module
00457            but for the moment let's leave it here. */
00458 
00459         { "setup_logging", (PyCFunction)py_setup_logging, 
00460           METH_VARARGS | METH_KEYWORDS, 
00461           "Set up debug logging.\n"
00462 "\n"
00463 "Initialises Samba's debug logging system.  One argument is expected which\n"
00464 "is a boolean specifying whether debugging is interactive and sent to stdout\n"
00465 "or logged to a file.\n"
00466 "\n"
00467 "Example:\n"
00468 "\n"
00469 ">>> smb.setup_logging(interactive = 1)" },
00470 
00471         { "get_debuglevel", (PyCFunction)get_debuglevel, 
00472           METH_VARARGS, 
00473           "Set the current debug level.\n"
00474 "\n"
00475 "Example:\n"
00476 "\n"
00477 ">>> smb.get_debuglevel()\n"
00478 "0" },
00479 
00480         { "set_debuglevel", (PyCFunction)set_debuglevel, 
00481           METH_VARARGS, 
00482           "Get the current debug level.\n"
00483 "\n"
00484 "Example:\n"
00485 "\n"
00486 ">>> smb.set_debuglevel(10)" },
00487 
00488         { NULL }
00489 };
00490 
00491 static void py_cli_state_dealloc(PyObject* self)
00492 {
00493         cli_state_object *cli = (cli_state_object *)self;
00494 
00495         if (cli->cli)
00496                 cli_shutdown(cli->cli);
00497 
00498         PyObject_Del(self);
00499 }
00500 
00501 static PyObject *py_cli_state_getattr(PyObject *self, char *attrname)
00502 {
00503         return Py_FindMethod(smb_hnd_methods, self, attrname);
00504 }
00505 
00506 PyTypeObject cli_state_type = {
00507         PyObject_HEAD_INIT(NULL)
00508         0,
00509         "SMB client connection",
00510         sizeof(cli_state_object),
00511         0,
00512         py_cli_state_dealloc, /*tp_dealloc*/
00513         0,          /*tp_print*/
00514         py_cli_state_getattr,          /*tp_getattr*/
00515         0,          /*tp_setattr*/
00516         0,          /*tp_compare*/
00517         0,          /*tp_repr*/
00518         0,          /*tp_as_number*/
00519         0,          /*tp_as_sequence*/
00520         0,          /*tp_as_mapping*/
00521         0,          /*tp_hash */
00522 };
00523 
00524 /*
00525  * Module initialisation 
00526  */
00527 
00528 void initsmb(void)
00529 {
00530         PyObject *module, *dict;
00531 
00532         /* Initialise module */
00533 
00534         module = Py_InitModule("smb", smb_methods);
00535         dict = PyModule_GetDict(module);
00536 
00537         /* Initialise policy handle object */
00538 
00539         cli_state_type.ob_type = &PyType_Type;
00540 
00541         /* Do samba initialisation */
00542 
00543         py_samba_init();
00544 
00545         setup_logging("smb", True);
00546         DEBUGLEVEL = 3;
00547 }

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