00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "python/py_smb.h"
00022
00023
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00457
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,
00513 0,
00514 py_cli_state_getattr,
00515 0,
00516 0,
00517 0,
00518 0,
00519 0,
00520 0,
00521 0,
00522 };
00523
00524
00525
00526
00527
00528 void initsmb(void)
00529 {
00530 PyObject *module, *dict;
00531
00532
00533
00534 module = Py_InitModule("smb", smb_methods);
00535 dict = PyModule_GetDict(module);
00536
00537
00538
00539 cli_state_type.ob_type = &PyType_Type;
00540
00541
00542
00543 py_samba_init();
00544
00545 setup_logging("smb", True);
00546 DEBUGLEVEL = 3;
00547 }