~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/python/py_smb.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
25
 
PyObject *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
 
 
36
 
static 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
 
 
57
 
static 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
 
                                      
81
 
static 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
 
 
95
 
static 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
 
        BOOL 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", result);
122
 
}
123
 
 
124
 
static 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
 
 
146
 
static 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
 
 
182
 
static 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
 
 
209
 
static 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
 
 
259
 
static 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
 
 
278
 
static 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
 
 
297
 
static 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
 
 
342
 
static 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
 
 
382
 
static 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
 
 
451
 
static 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
 
 
491
 
static 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
 
 
501
 
static PyObject *py_cli_state_getattr(PyObject *self, char *attrname)
502
 
{
503
 
        return Py_FindMethod(smb_hnd_methods, self, attrname);
504
 
}
505
 
 
506
 
PyTypeObject 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
 
 
528
 
void 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
 
}