source: trunk-3.0/source/python/py_smb.c@ 102

Last change on this file since 102 was 71, checked in by Paul Smedley, 18 years ago

Update source to 3.0.26a

File size: 13.6 KB
Line 
1/*
2 Python wrappers for DCERPC/SMB client routines.
3
4 Copyright (C) Tim Potter, 2002
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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "python/py_smb.h"
22
23/* Create a new cli_state python object */
24
25PyObject *new_cli_state_object(struct cli_state *cli)
26{
27 cli_state_object *o;
28
29 o = PyObject_New(cli_state_object, &cli_state_type);
30
31 o->cli = cli;
32
33 return (PyObject*)o;
34}
35
36static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw)
37{
38 static char *kwlist[] = { "server", NULL };
39 struct cli_state *cli;
40 char *server;
41 struct in_addr ip;
42
43 if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server))
44 return NULL;
45
46 if (!(cli = cli_initialise()))
47 return NULL;
48
49 ZERO_STRUCT(ip);
50
51 if (!NT_STATUS_IS_OK(cli_connect(cli, server, &ip)))
52 return NULL;
53
54 return new_cli_state_object(cli);
55}
56
57static PyObject *py_smb_session_request(PyObject *self, PyObject *args,
58 PyObject *kw)
59{
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;
64 BOOL result;
65
66 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s", kwlist, &called_name,
67 &calling_name))
68 return NULL;
69
70 if (!calling_name)
71 calling_name = global_myname();
72
73 make_nmb_name(&calling, calling_name, 0x00);
74 make_nmb_name(&called, called_name, 0x20);
75
76 result = cli_session_request(cli->cli, &calling, &called);
77
78 return Py_BuildValue("i", result);
79}
80
81static PyObject *py_smb_negprot(PyObject *self, PyObject *args, PyObject *kw)
82{
83 cli_state_object *cli = (cli_state_object *)self;
84 static char *kwlist[] = { NULL };
85 BOOL result;
86
87 if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
88 return NULL;
89
90 result = cli_negprot(cli->cli);
91
92 return Py_BuildValue("i", result);
93}
94
95static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
96 PyObject *kw)
97{
98 cli_state_object *cli = (cli_state_object *)self;
99 static char *kwlist[] = { "creds", NULL };
100 PyObject *creds;
101 char *username, *domain, *password, *errstr;
102 NTSTATUS result;
103
104 if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds))
105 return NULL;
106
107 if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) {
108 free(errstr);
109 return NULL;
110 }
111
112 result = cli_session_setup(
113 cli->cli, username, password, strlen(password) + 1,
114 password, strlen(password) + 1, domain);
115
116 if (cli_is_error(cli->cli)) {
117 PyErr_SetString(PyExc_RuntimeError, "session setup failed");
118 return NULL;
119 }
120
121 return Py_BuildValue("i", NT_STATUS_IS_OK(result));
122}
123
124static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw)
125{
126 cli_state_object *cli = (cli_state_object *)self;
127 static char *kwlist[] = { "service", NULL };
128 char *service;
129 BOOL result;
130
131 if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &service))
132 return NULL;
133
134 result = cli_send_tconX(
135 cli->cli, service, strequal(service, "IPC$") ? "IPC" :
136 "?????", "", 1);
137
138 if (cli_is_error(cli->cli)) {
139 PyErr_SetString(PyExc_RuntimeError, "tconx failed");
140 return NULL;
141 }
142
143 return Py_BuildValue("i", result);
144}
145
146static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args,
147 PyObject *kw)
148{
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",
153 NULL };
154 char *filename;
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;
158 int result;
159
160 /* Parse parameters */
161
162 if (!PyArg_ParseTupleAndKeywords(
163 args, kw, "si|iiii", kwlist, &filename, &desired_access,
164 &file_attributes, &share_access, &create_disposition,
165 &create_options))
166 return NULL;
167
168 result = cli_nt_create_full(
169 cli->cli, filename, 0, desired_access, file_attributes,
170 share_access, create_disposition, create_options, 0);
171
172 if (cli_is_error(cli->cli)) {
173 PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed");
174 return NULL;
175 }
176
177 /* Return FID */
178
179 return PyInt_FromLong(result);
180}
181
182static PyObject *py_smb_open(PyObject *self, PyObject *args, PyObject *kw)
183{
184 cli_state_object *cli = (cli_state_object *)self;
185 static char *kwlist[] = { "filename", "flags",
186 "share_mode", NULL };
187 char *filename;
188 uint32 flags, share_mode = DENY_NONE;
189 int result;
190
191 /* Parse parameters */
192
193 if (!PyArg_ParseTupleAndKeywords(
194 args, kw, "si|i", kwlist, &filename, &flags, &share_mode))
195 return NULL;
196
197 result = cli_open(cli->cli, filename, flags, share_mode);
198
199 if (cli_is_error(cli->cli)) {
200 PyErr_SetString(PyExc_RuntimeError, "open failed");
201 return NULL;
202 }
203
204 /* Return FID */
205
206 return PyInt_FromLong(result);
207}
208
209static PyObject *py_smb_read(PyObject *self, PyObject *args, PyObject *kw)
210{
211 cli_state_object *cli = (cli_state_object *)self;
212 static char *kwlist[] = { "fnum", "offset", "size", NULL };
213 int fnum, offset=0, size=0;
214 ssize_t result;
215 SMB_OFF_T fsize;
216 char *data;
217 PyObject *ret;
218
219 /* Parse parameters */
220
221 if (!PyArg_ParseTupleAndKeywords(
222 args, kw, "i|ii", kwlist, &fnum, &offset, &size))
223 return NULL;
224
225 if (!cli_qfileinfo(cli->cli, fnum, NULL, &fsize, NULL, NULL,
226 NULL, NULL, NULL) &&
227 !cli_getattrE(cli->cli, fnum, NULL, &fsize, NULL, NULL, NULL)) {
228 PyErr_SetString(PyExc_RuntimeError, "getattrib failed");
229 return NULL;
230 }
231
232 if (offset < 0)
233 offset = 0;
234
235 if (size < 1 || size > fsize - offset)
236 size = fsize - offset;
237
238 if (!(data = SMB_XMALLOC_ARRAY(char, size))) {
239 PyErr_SetString(PyExc_RuntimeError, "malloc failed");
240 return NULL;
241 }
242
243 result = cli_read(cli->cli, fnum, data, (off_t) offset, (size_t) size);
244
245 if (result==-1 || cli_is_error(cli->cli)) {
246 SAFE_FREE(data);
247 PyErr_SetString(PyExc_RuntimeError, "read failed");
248 return NULL;
249 }
250
251 /* Return a python string */
252
253 ret = Py_BuildValue("s#", data, result);
254 SAFE_FREE(data);
255
256 return ret;
257}
258
259static PyObject *py_smb_close(PyObject *self, PyObject *args,
260 PyObject *kw)
261{
262 cli_state_object *cli = (cli_state_object *)self;
263 static char *kwlist[] = { "fnum", NULL };
264 BOOL result;
265 int fnum;
266
267 /* Parse parameters */
268
269 if (!PyArg_ParseTupleAndKeywords(
270 args, kw, "i", kwlist, &fnum))
271 return NULL;
272
273 result = cli_close(cli->cli, fnum);
274
275 return PyInt_FromLong(result);
276}
277
278static PyObject *py_smb_unlink(PyObject *self, PyObject *args,
279 PyObject *kw)
280{
281 cli_state_object *cli = (cli_state_object *)self;
282 static char *kwlist[] = { "filename", NULL };
283 char *filename;
284 BOOL result;
285
286 /* Parse parameters */
287
288 if (!PyArg_ParseTupleAndKeywords(
289 args, kw, "s", kwlist, &filename))
290 return NULL;
291
292 result = cli_unlink(cli->cli, filename);
293
294 return PyInt_FromLong(result);
295}
296
297static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
298 PyObject *kw)
299{
300 cli_state_object *cli = (cli_state_object *)self;
301 static char *kwlist[] = { "fnum", NULL };
302 PyObject *result = NULL;
303 SEC_DESC *secdesc = NULL;
304 int fnum;
305 TALLOC_CTX *mem_ctx = NULL;
306
307 /* Parse parameters */
308
309 if (!PyArg_ParseTupleAndKeywords(
310 args, kw, "i", kwlist, &fnum))
311 return NULL;
312
313 mem_ctx = talloc_init("py_smb_query_secdesc");
314
315 secdesc = cli_query_secdesc(cli->cli, fnum, mem_ctx);
316
317 if (cli_is_error(cli->cli)) {
318 PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed");
319 goto done;
320 }
321
322 if (!secdesc) {
323 Py_INCREF(Py_None);
324 result = Py_None;
325 goto done;
326 }
327
328 if (!py_from_SECDESC(&result, secdesc)) {
329 PyErr_SetString(
330 PyExc_TypeError,
331 "Invalid security descriptor returned");
332 goto done;
333 }
334
335 done:
336 talloc_destroy(mem_ctx);
337
338 return result;
339
340}
341
342static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
343 PyObject *kw)
344{
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;
349 SEC_DESC *secdesc;
350 TALLOC_CTX *mem_ctx = NULL;
351 int fnum;
352 BOOL err;
353
354 /* Parse parameters */
355
356 if (!PyArg_ParseTupleAndKeywords(
357 args, kw, "iO", kwlist, &fnum, &py_secdesc))
358 return NULL;
359
360 mem_ctx = talloc_init("py_smb_set_secdesc");
361
362 if (!py_to_SECDESC(&secdesc, py_secdesc, mem_ctx)) {
363 PyErr_SetString(PyExc_TypeError,
364 "Invalid security descriptor");
365 goto done;
366 }
367
368 err = cli_set_secdesc(cli->cli, fnum, secdesc);
369
370 if (cli_is_error(cli->cli)) {
371 PyErr_SetString(PyExc_RuntimeError, "set_secdesc failed");
372 goto done;
373 }
374
375 result = PyInt_FromLong(err);
376 done:
377 talloc_destroy(mem_ctx);
378
379 return result;
380}
381
382static PyMethodDef smb_hnd_methods[] = {
383
384 /* Session and connection handling */
385
386 { "session_request", (PyCFunction)py_smb_session_request,
387 METH_VARARGS | METH_KEYWORDS, "Request a session" },
388
389 { "negprot", (PyCFunction)py_smb_negprot,
390 METH_VARARGS | METH_KEYWORDS, "Protocol negotiation" },
391
392 { "session_setup", (PyCFunction)py_smb_session_setup,
393 METH_VARARGS | METH_KEYWORDS, "Session setup" },
394
395 { "tconx", (PyCFunction)py_smb_tconx,
396 METH_VARARGS | METH_KEYWORDS, "Tree connect" },
397
398 /* File operations */
399
400 { "nt_create_andx", (PyCFunction)py_smb_nt_create_andx,
401 METH_VARARGS | METH_KEYWORDS, "NT Create&X" },
402
403 { "open", (PyCFunction)py_smb_open,
404 METH_VARARGS | METH_KEYWORDS,
405 "Open a file\n"
406"\n"
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"
410"\n"
411"Example:\n"
412"\n"
413">>> fnum=conn.open(filename, os.O_RDONLY)" },
414
415 { "read", (PyCFunction)py_smb_read,
416 METH_VARARGS | METH_KEYWORDS,
417 "Read from an open file\n"
418"\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"
422"\n"
423"Example:\n"
424"\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" },
429
430 { "close", (PyCFunction)py_smb_close,
431 METH_VARARGS | METH_KEYWORDS, "Close" },
432
433 { "unlink", (PyCFunction)py_smb_unlink,
434 METH_VARARGS | METH_KEYWORDS, "Unlink" },
435
436 /* Security descriptors */
437
438 { "query_secdesc", (PyCFunction)py_smb_query_secdesc,
439 METH_VARARGS | METH_KEYWORDS, "Query security descriptor" },
440
441 { "set_secdesc", (PyCFunction)py_smb_set_secdesc,
442 METH_VARARGS | METH_KEYWORDS, "Set security descriptor" },
443
444 { NULL }
445};
446
447/*
448 * Method dispatch tables
449 */
450
451static PyMethodDef smb_methods[] = {
452
453 { "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS,
454 "Connect to a host" },
455
456 /* Other stuff - this should really go into a samba config module
457 but for the moment let's leave it here. */
458
459 { "setup_logging", (PyCFunction)py_setup_logging,
460 METH_VARARGS | METH_KEYWORDS,
461 "Set up debug logging.\n"
462"\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"
466"\n"
467"Example:\n"
468"\n"
469">>> smb.setup_logging(interactive = 1)" },
470
471 { "get_debuglevel", (PyCFunction)get_debuglevel,
472 METH_VARARGS,
473 "Set the current debug level.\n"
474"\n"
475"Example:\n"
476"\n"
477">>> smb.get_debuglevel()\n"
478"0" },
479
480 { "set_debuglevel", (PyCFunction)set_debuglevel,
481 METH_VARARGS,
482 "Get the current debug level.\n"
483"\n"
484"Example:\n"
485"\n"
486">>> smb.set_debuglevel(10)" },
487
488 { NULL }
489};
490
491static void py_cli_state_dealloc(PyObject* self)
492{
493 cli_state_object *cli = (cli_state_object *)self;
494
495 if (cli->cli)
496 cli_shutdown(cli->cli);
497
498 PyObject_Del(self);
499}
500
501static PyObject *py_cli_state_getattr(PyObject *self, char *attrname)
502{
503 return Py_FindMethod(smb_hnd_methods, self, attrname);
504}
505
506PyTypeObject cli_state_type = {
507 PyObject_HEAD_INIT(NULL)
508 0,
509 "SMB client connection",
510 sizeof(cli_state_object),
511 0,
512 py_cli_state_dealloc, /*tp_dealloc*/
513 0, /*tp_print*/
514 py_cli_state_getattr, /*tp_getattr*/
515 0, /*tp_setattr*/
516 0, /*tp_compare*/
517 0, /*tp_repr*/
518 0, /*tp_as_number*/
519 0, /*tp_as_sequence*/
520 0, /*tp_as_mapping*/
521 0, /*tp_hash */
522};
523
524/*
525 * Module initialisation
526 */
527
528void initsmb(void)
529{
530 PyObject *module, *dict;
531
532 /* Initialise module */
533
534 module = Py_InitModule("smb", smb_methods);
535 dict = PyModule_GetDict(module);
536
537 /* Initialise policy handle object */
538
539 cli_state_type.ob_type = &PyType_Type;
540
541 /* Do samba initialisation */
542
543 py_samba_init();
544
545 setup_logging("smb", True);
546 DEBUGLEVEL = 3;
547}
Note: See TracBrowser for help on using the repository browser.