2
Python wrappers for DCERPC/SMB client routines.
4
Copyright (C) Tim Potter, 2002
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 2 of the License, or
9
(at your option) any later version.
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.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include "python/py_smb.h"
23
/* Create a new cli_state python object */
25
PyObject *new_cli_state_object(struct cli_state *cli)
29
o = PyObject_New(cli_state_object, &cli_state_type);
36
static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw)
38
static char *kwlist[] = { "server", NULL };
39
struct cli_state *cli;
43
if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server))
46
if (!(cli = cli_initialise()))
51
if (!cli_connect(cli, server, &ip))
54
return new_cli_state_object(cli);
57
static PyObject *py_smb_session_request(PyObject *self, PyObject *args,
60
cli_state_object *cli = (cli_state_object *)self;
61
static char *kwlist[] = { "called", "calling", NULL };
62
char *calling_name = NULL, *called_name;
63
struct nmb_name calling, called;
66
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s", kwlist, &called_name,
71
calling_name = global_myname();
73
make_nmb_name(&calling, calling_name, 0x00);
74
make_nmb_name(&called, called_name, 0x20);
76
result = cli_session_request(cli->cli, &calling, &called);
78
return Py_BuildValue("i", result);
81
static PyObject *py_smb_negprot(PyObject *self, PyObject *args, PyObject *kw)
83
cli_state_object *cli = (cli_state_object *)self;
84
static char *kwlist[] = { NULL };
87
if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
90
result = cli_negprot(cli->cli);
92
return Py_BuildValue("i", result);
95
static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
98
cli_state_object *cli = (cli_state_object *)self;
99
static char *kwlist[] = { "creds", NULL };
101
char *username, *domain, *password, *errstr;
104
if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds))
107
if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) {
112
result = cli_session_setup(
113
cli->cli, username, password, strlen(password) + 1,
114
password, strlen(password) + 1, domain);
116
if (cli_is_error(cli->cli)) {
117
PyErr_SetString(PyExc_RuntimeError, "session setup failed");
121
return Py_BuildValue("i", result);
124
static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw)
126
cli_state_object *cli = (cli_state_object *)self;
127
static char *kwlist[] = { "service", NULL };
131
if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &service))
134
result = cli_send_tconX(
135
cli->cli, service, strequal(service, "IPC$") ? "IPC" :
138
if (cli_is_error(cli->cli)) {
139
PyErr_SetString(PyExc_RuntimeError, "tconx failed");
143
return Py_BuildValue("i", result);
146
static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args,
149
cli_state_object *cli = (cli_state_object *)self;
150
static char *kwlist[] = { "filename", "desired_access",
151
"file_attributes", "share_access",
152
"create_disposition", "create_options",
155
uint32 desired_access, file_attributes = 0,
156
share_access = FILE_SHARE_READ | FILE_SHARE_WRITE,
157
create_disposition = OPENX_FILE_EXISTS_OPEN, create_options = 0;
160
/* Parse parameters */
162
if (!PyArg_ParseTupleAndKeywords(
163
args, kw, "si|iiii", kwlist, &filename, &desired_access,
164
&file_attributes, &share_access, &create_disposition,
168
result = cli_nt_create_full(
169
cli->cli, filename, 0, desired_access, file_attributes,
170
share_access, create_disposition, create_options, 0);
172
if (cli_is_error(cli->cli)) {
173
PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed");
179
return PyInt_FromLong(result);
182
static PyObject *py_smb_open(PyObject *self, PyObject *args, PyObject *kw)
184
cli_state_object *cli = (cli_state_object *)self;
185
static char *kwlist[] = { "filename", "flags",
186
"share_mode", NULL };
188
uint32 flags, share_mode = DENY_NONE;
191
/* Parse parameters */
193
if (!PyArg_ParseTupleAndKeywords(
194
args, kw, "si|i", kwlist, &filename, &flags, &share_mode))
197
result = cli_open(cli->cli, filename, flags, share_mode);
199
if (cli_is_error(cli->cli)) {
200
PyErr_SetString(PyExc_RuntimeError, "open failed");
206
return PyInt_FromLong(result);
209
static PyObject *py_smb_read(PyObject *self, PyObject *args, PyObject *kw)
211
cli_state_object *cli = (cli_state_object *)self;
212
static char *kwlist[] = { "fnum", "offset", "size", NULL };
213
int fnum, offset=0, size=0;
219
/* Parse parameters */
221
if (!PyArg_ParseTupleAndKeywords(
222
args, kw, "i|ii", kwlist, &fnum, &offset, &size))
225
if (!cli_qfileinfo(cli->cli, fnum, NULL, &fsize, NULL, NULL,
227
!cli_getattrE(cli->cli, fnum, NULL, &fsize, NULL, NULL, NULL)) {
228
PyErr_SetString(PyExc_RuntimeError, "getattrib failed");
235
if (size < 1 || size > fsize - offset)
236
size = fsize - offset;
238
if (!(data = SMB_XMALLOC_ARRAY(char, size))) {
239
PyErr_SetString(PyExc_RuntimeError, "malloc failed");
243
result = cli_read(cli->cli, fnum, data, (off_t) offset, (size_t) size);
245
if (result==-1 || cli_is_error(cli->cli)) {
247
PyErr_SetString(PyExc_RuntimeError, "read failed");
251
/* Return a python string */
253
ret = Py_BuildValue("s#", data, result);
259
static PyObject *py_smb_close(PyObject *self, PyObject *args,
262
cli_state_object *cli = (cli_state_object *)self;
263
static char *kwlist[] = { "fnum", NULL };
267
/* Parse parameters */
269
if (!PyArg_ParseTupleAndKeywords(
270
args, kw, "i", kwlist, &fnum))
273
result = cli_close(cli->cli, fnum);
275
return PyInt_FromLong(result);
278
static PyObject *py_smb_unlink(PyObject *self, PyObject *args,
281
cli_state_object *cli = (cli_state_object *)self;
282
static char *kwlist[] = { "filename", NULL };
286
/* Parse parameters */
288
if (!PyArg_ParseTupleAndKeywords(
289
args, kw, "s", kwlist, &filename))
292
result = cli_unlink(cli->cli, filename);
294
return PyInt_FromLong(result);
297
static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
300
cli_state_object *cli = (cli_state_object *)self;
301
static char *kwlist[] = { "fnum", NULL };
302
PyObject *result = NULL;
303
SEC_DESC *secdesc = NULL;
305
TALLOC_CTX *mem_ctx = NULL;
307
/* Parse parameters */
309
if (!PyArg_ParseTupleAndKeywords(
310
args, kw, "i", kwlist, &fnum))
313
mem_ctx = talloc_init("py_smb_query_secdesc");
315
secdesc = cli_query_secdesc(cli->cli, fnum, mem_ctx);
317
if (cli_is_error(cli->cli)) {
318
PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed");
328
if (!py_from_SECDESC(&result, secdesc)) {
331
"Invalid security descriptor returned");
336
talloc_destroy(mem_ctx);
342
static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
345
cli_state_object *cli = (cli_state_object *)self;
346
static char *kwlist[] = { "fnum", "security_descriptor", NULL };
347
PyObject *result = NULL;
348
PyObject *py_secdesc;
350
TALLOC_CTX *mem_ctx = NULL;
354
/* Parse parameters */
356
if (!PyArg_ParseTupleAndKeywords(
357
args, kw, "iO", kwlist, &fnum, &py_secdesc))
360
mem_ctx = talloc_init("py_smb_set_secdesc");
362
if (!py_to_SECDESC(&secdesc, py_secdesc, mem_ctx)) {
363
PyErr_SetString(PyExc_TypeError,
364
"Invalid security descriptor");
368
err = cli_set_secdesc(cli->cli, fnum, secdesc);
370
if (cli_is_error(cli->cli)) {
371
PyErr_SetString(PyExc_RuntimeError, "set_secdesc failed");
375
result = PyInt_FromLong(err);
377
talloc_destroy(mem_ctx);
382
static PyMethodDef smb_hnd_methods[] = {
384
/* Session and connection handling */
386
{ "session_request", (PyCFunction)py_smb_session_request,
387
METH_VARARGS | METH_KEYWORDS, "Request a session" },
389
{ "negprot", (PyCFunction)py_smb_negprot,
390
METH_VARARGS | METH_KEYWORDS, "Protocol negotiation" },
392
{ "session_setup", (PyCFunction)py_smb_session_setup,
393
METH_VARARGS | METH_KEYWORDS, "Session setup" },
395
{ "tconx", (PyCFunction)py_smb_tconx,
396
METH_VARARGS | METH_KEYWORDS, "Tree connect" },
398
/* File operations */
400
{ "nt_create_andx", (PyCFunction)py_smb_nt_create_andx,
401
METH_VARARGS | METH_KEYWORDS, "NT Create&X" },
403
{ "open", (PyCFunction)py_smb_open,
404
METH_VARARGS | METH_KEYWORDS,
407
"This function returns a fnum handle to an open file. The file is\n"
408
"opened with flags and optional share mode. If unspecified, the\n"
409
"default share mode is DENY_NONE\n"
413
">>> fnum=conn.open(filename, os.O_RDONLY)" },
415
{ "read", (PyCFunction)py_smb_read,
416
METH_VARARGS | METH_KEYWORDS,
417
"Read from an open file\n"
419
"This function returns a string read from an open file starting at\n"
420
"offset for size bytes (until EOF is reached). If unspecified, the\n"
421
"default offset is 0, and default size is the remainder of the file.\n"
425
">>> conn.read(fnum) # read entire file\n"
426
">>> conn.read(fnum,5) # read entire file from offset 5\n"
427
">>> conn.read(fnum,size=64) # read 64 bytes from start of file\n"
428
">>> conn.read(fnum,4096,1024) # read 1024 bytes from offset 4096\n" },
430
{ "close", (PyCFunction)py_smb_close,
431
METH_VARARGS | METH_KEYWORDS, "Close" },
433
{ "unlink", (PyCFunction)py_smb_unlink,
434
METH_VARARGS | METH_KEYWORDS, "Unlink" },
436
/* Security descriptors */
438
{ "query_secdesc", (PyCFunction)py_smb_query_secdesc,
439
METH_VARARGS | METH_KEYWORDS, "Query security descriptor" },
441
{ "set_secdesc", (PyCFunction)py_smb_set_secdesc,
442
METH_VARARGS | METH_KEYWORDS, "Set security descriptor" },
448
* Method dispatch tables
451
static PyMethodDef smb_methods[] = {
453
{ "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS,
454
"Connect to a host" },
456
/* Other stuff - this should really go into a samba config module
457
but for the moment let's leave it here. */
459
{ "setup_logging", (PyCFunction)py_setup_logging,
460
METH_VARARGS | METH_KEYWORDS,
461
"Set up debug logging.\n"
463
"Initialises Samba's debug logging system. One argument is expected which\n"
464
"is a boolean specifying whether debugging is interactive and sent to stdout\n"
465
"or logged to a file.\n"
469
">>> smb.setup_logging(interactive = 1)" },
471
{ "get_debuglevel", (PyCFunction)get_debuglevel,
473
"Set the current debug level.\n"
477
">>> smb.get_debuglevel()\n"
480
{ "set_debuglevel", (PyCFunction)set_debuglevel,
482
"Get the current debug level.\n"
486
">>> smb.set_debuglevel(10)" },
491
static void py_cli_state_dealloc(PyObject* self)
493
cli_state_object *cli = (cli_state_object *)self;
496
cli_shutdown(cli->cli);
501
static PyObject *py_cli_state_getattr(PyObject *self, char *attrname)
503
return Py_FindMethod(smb_hnd_methods, self, attrname);
506
PyTypeObject cli_state_type = {
507
PyObject_HEAD_INIT(NULL)
509
"SMB client connection",
510
sizeof(cli_state_object),
512
py_cli_state_dealloc, /*tp_dealloc*/
514
py_cli_state_getattr, /*tp_getattr*/
519
0, /*tp_as_sequence*/
525
* Module initialisation
530
PyObject *module, *dict;
532
/* Initialise module */
534
module = Py_InitModule("smb", smb_methods);
535
dict = PyModule_GetDict(module);
537
/* Initialise policy handle object */
539
cli_state_type.ob_type = &PyType_Type;
541
/* Do samba initialisation */
545
setup_logging("smb", True);