• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.0.25b/source/python/
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 (!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}
548