Sync with HEAD.
authorTim Potter <tpot@samba.org>
Mon, 4 Nov 2002 20:33:16 +0000 (20:33 +0000)
committerTim Potter <tpot@samba.org>
Mon, 4 Nov 2002 20:33:16 +0000 (20:33 +0000)
(This used to be commit 0310e539bb41f569c7ae77b2d131e966adefa27b)

source3/python/examples/tdbpack/test_tdbpack.py
source3/python/py_common.c
source3/python/py_common_proto.h
source3/python/py_lsa.c
source3/python/py_samr.c
source3/python/py_smb.c
source3/python/py_spoolss_drivers.c
source3/python/py_spoolss_ports.c
source3/python/py_spoolss_printers.c
source3/python/py_tdbpack.c
source3/python/setup.py

index 36fed881e33416466f410dc1896f0fa6d9a7f64a..659dc0efed98019c86cdcd439ee9eaee652041ac 100755 (executable)
@@ -17,13 +17,12 @@ string, with one character per field."""
 __author__ = 'Martin Pool <mbp@sourcefrog.net>'
 
 import unittest
-# import tdbutil
+import oldtdbutil
 import samba.tdbpack
 
-packer = samba.tdbpack.pack
-unpacker = samba.tdbpack.unpack
-
-
+both_unpackers = (samba.tdbpack.unpack, oldtdbutil.unpack)
+both_packers = (samba.tdbpack.pack, oldtdbutil.pack)
+    
 class PackTests(unittest.TestCase):
     symm_cases = [('B', ['hello' * 51], '\xff\0\0\0' + 'hello' * 51),
              ('w', [42], '\x2a\0'),
@@ -78,11 +77,13 @@ class PackTests(unittest.TestCase):
     def test_symmetric(self):
         """Cookbook of symmetric pack/unpack tests
         """
-        for format, values, expected in self.symm_cases:
-            self.assertEquals(packer(format, values), expected)
-            out, rest = unpacker(format, expected)
-            self.assertEquals(rest, '')
-            self.assertEquals(list(values), list(out))
+        for packer in both_packers:
+            for unpacker in both_unpackers:
+                for format, values, expected in self.symm_cases:
+                    self.assertEquals(packer(format, values), expected)
+                    out, rest = unpacker(format, expected)
+                    self.assertEquals(rest, '')
+                    self.assertEquals(list(values), list(out))
         
     
     def test_pack(self):
@@ -100,25 +101,30 @@ class PackTests(unittest.TestCase):
                  # as if you called list()
                  ]
 
-        for format, values, expected in cases:
-            self.assertEquals(packer(format, values), expected)
+        for packer in both_packers:
+            for format, values, expected in cases:
+                self.assertEquals(packer(format, values), expected)
 
     def test_unpack_extra(self):
         # Test leftover data
-        for format, values, packed in self.symm_cases:
-            out, rest = unpacker(format, packed + 'hello sailor!')
-            self.assertEquals(rest, 'hello sailor!')
-            self.assertEquals(list(values), list(out))
+        for unpacker in both_unpackers:
+            for format, values, packed in self.symm_cases:
+                out, rest = unpacker(format, packed + 'hello sailor!')
+                self.assertEquals(rest, 'hello sailor!')
+                self.assertEquals(list(values), list(out))
         
 
     def test_unpack(self):
         """Cookbook of tricky unpack tests"""
         cases = [
+                 # Apparently I couldn't think of any tests that weren't
+                 # symmetric :-/
                  ]
-        for format, values, expected in cases:
-            out, rest = unpacker(format, expected)
-            self.assertEquals(rest, '')
-            self.assertEquals(list(values), list(out))
+        for unpacker in both_unpackers:
+            for format, values, expected in cases:
+                out, rest = unpacker(format, expected)
+                self.assertEquals(rest, '')
+                self.assertEquals(list(values), list(out))
 
 
     def test_pack_failures(self):
@@ -141,7 +147,7 @@ class PackTests(unittest.TestCase):
                  ('f', [2], TypeError),
                  ('P', [None], TypeError),
                  ('P', (), IndexError),
-                 ('f', [packer], TypeError),
+                 ('f', [hex], TypeError),
                  ('fw', ['hello'], IndexError),
                  ('f', [u'hello'], TypeError),
                  ('B', [2], TypeError),
@@ -153,10 +159,11 @@ class PackTests(unittest.TestCase):
                  ('fQ', ['2'], IndexError),
                  (2, [2], TypeError),
                  ({}, {}, TypeError)]
-        for format, values, throwable_class in cases:
-            def do_pack():
-                packer(format, values)
-            self.assertRaises(throwable_class, do_pack)
+        for packer in both_packers:
+            for format, values, throwable_class in cases:
+                def do_pack():
+                    packer(format, values)
+                self.assertRaises(throwable_class, do_pack)
 
 
     def test_unpack_failures(self):
@@ -182,10 +189,11 @@ class PackTests(unittest.TestCase):
                  ('B', 'foobar', IndexError),
                  ('BB', '\x01\0\0\0a\x01', IndexError),
                  ]
-        
-        for format, values, throwable_class in cases:
-            def do_unpack():
-                unpacker(format, values)
+
+        for unpacker in both_unpackers:
+            for format, values, throwable_class in cases:
+                def do_unpack():
+                    unpacker(format, values)
             self.assertRaises(throwable_class, do_unpack)
 
         
index d15df234d17179538e110eeb5983879c99aa992f..364271d57c4aa05bf9d2563d3099808c1b78ff8f 100644 (file)
@@ -218,7 +218,7 @@ BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
    be freed by calling free(). */
 
 struct cli_state *open_pipe_creds(char *server, PyObject *creds, 
-                                 char *pipe_name, char **errstr)
+                                 int pipe_idx, char **errstr)
 {
        char *username, *password, *domain;
        struct cli_state *cli;
@@ -240,10 +240,9 @@ struct cli_state *open_pipe_creds(char *server, PyObject *creds,
                return NULL;
        }
 
-       if (!cli_nt_session_open(cli, pipe_name)) {
+       if (!cli_nt_session_open(cli, pipe_idx)) {
                cli_shutdown(cli);
-               free(cli);
-               asprintf(errstr, "error opening %s", pipe_name);
+               asprintf(errstr, "error opening pipe index %d", pipe_idx);
                return NULL;
        }
 
index 89f0f35fc936e3a8071bceccd970e855729b4106..b012c17e153d4f276132fe82ecce2cddef5b50da 100644 (file)
@@ -15,7 +15,7 @@ PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw);
 BOOL py_parse_creds(PyObject *creds, char **username, char **domain, 
                    char **password, char **errstr);
 struct cli_state *open_pipe_creds(char *server, PyObject *creds, 
-                                 char *pipe_name, char **errstr);
+                                 int pipe_idx, char **errstr);
 BOOL get_level_value(PyObject *dict, uint32 *level);
 
 /* The following definitions come from python/py_ntsec.c  */
index 0584cf716bfb162cb99689d972aa3c1fff5f3562..d54a2289ef48a48d93e618e92e4ae144b6217234 100644 (file)
@@ -78,7 +78,7 @@ static PyObject *lsa_open_policy(PyObject *self, PyObject *args,
 
        server += 2;
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_LSARPC, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_LSARPC, &errstr))) {
                PyErr_SetString(lsa_error, errstr);
                free(errstr);
                return NULL;
index 917a90a2fb33a3e5367d0ba1d5ed2994e62b3f99..92a2eaf063735d3f546410fc2697d52e9c0a0d06 100644 (file)
@@ -393,7 +393,7 @@ static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
                return NULL;
        }
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SAMR, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
                PyErr_SetString(samr_error, errstr);
                free(errstr);
                return NULL;
@@ -409,7 +409,6 @@ static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
 
        if (!NT_STATUS_IS_OK(ntstatus)) {
                cli_shutdown(cli);
-               SAFE_FREE(cli);
                PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
                goto done;
        }
index 77d7bb32fce6c019cac268462267579f48a6607d..41b8237a8a1f91198cb4ff88516e3bd85b080e2c 100644 (file)
@@ -97,12 +97,12 @@ static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
                                      PyObject *kw)
 {
        cli_state_object *cli = (cli_state_object *)self;
-       static char *kwlist[] = { "creds" };
+       static char *kwlist[] = { "creds", NULL };
        PyObject *creds;
        char *username, *domain, *password, *errstr;
        BOOL result;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kw, "O", kwlist, &creds))
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds))
                return NULL;
 
        if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) {
@@ -114,35 +114,192 @@ static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
                cli->cli, username, password, strlen(password) + 1,
                password, strlen(password) + 1, domain);
 
+       if (cli_is_error(cli->cli)) {
+               PyErr_SetString(PyExc_RuntimeError, "session setup failed");
+               return NULL;
+       }
+
        return Py_BuildValue("i", result);
 }
 
 static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw)
 {
        cli_state_object *cli = (cli_state_object *)self;
-       static char *kwlist[] = { "service", "creds" };
-       PyObject *creds;
-       char *service, *username, *domain, *password, *errstr;
+       static char *kwlist[] = { "service", NULL };
+       char *service;
        BOOL result;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kw, "sO", kwlist, &service, 
-                                        &creds))
+       if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &service))
                return NULL;
 
-       if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) {
-               free(errstr);
+       result = cli_send_tconX(
+               cli->cli, service, strequal(service, "IPC$") ? "IPC" : 
+               "?????", "", 1);
+
+       if (cli_is_error(cli->cli)) {
+               PyErr_SetString(PyExc_RuntimeError, "tconx failed");
                return NULL;
        }
 
-       result = cli_send_tconX(
-               cli->cli, service, strequal(service, "IPC$") ? "IPC" : "?????", 
-               password, strlen(password) + 1);
-
        return Py_BuildValue("i", result);
 }
 
+static PyObject *py_smb_nt_create_andx(PyObject *self, PyObject *args,
+                                      PyObject *kw)
+{
+       cli_state_object *cli = (cli_state_object *)self;
+       static char *kwlist[] = { "filename", "desired_access", 
+                                 "file_attributes", "share_access",
+                                 "create_disposition", NULL };
+       char *filename;
+       uint32 desired_access, file_attributes = 0, 
+               share_access = FILE_SHARE_READ | FILE_SHARE_WRITE,
+               create_disposition = FILE_EXISTS_OPEN, create_options = 0;
+       int result;
+
+       /* Parse parameters */
+
+       if (!PyArg_ParseTupleAndKeywords(
+                   args, kw, "si|iii", kwlist, &filename, &desired_access,
+                   &file_attributes, &share_access, &create_disposition,
+                   &create_options))
+               return NULL;
+
+       result = cli_nt_create_full(
+               cli->cli, filename, desired_access, file_attributes,
+               share_access, create_disposition, create_options);
+
+       if (cli_is_error(cli->cli)) {
+               PyErr_SetString(PyExc_RuntimeError, "nt_create_andx failed");
+               return NULL;
+       }
+
+       /* Return FID */
+
+       return PyInt_FromLong(result);
+}
+
+static PyObject *py_smb_close(PyObject *self, PyObject *args,
+                             PyObject *kw)
+{
+       cli_state_object *cli = (cli_state_object *)self;
+       static char *kwlist[] = { "fnum", NULL };
+       BOOL result;
+       int fnum;
+
+       /* Parse parameters */
+
+       if (!PyArg_ParseTupleAndKeywords(
+                   args, kw, "i", kwlist, &fnum))
+               return NULL;
+
+       result = cli_close(cli->cli, fnum);
+
+       return PyInt_FromLong(result);
+}
+
+static PyObject *py_smb_unlink(PyObject *self, PyObject *args,
+                              PyObject *kw)
+{
+       cli_state_object *cli = (cli_state_object *)self;
+       static char *kwlist[] = { "filename", NULL };
+       char *filename;
+       BOOL result;
+
+       /* Parse parameters */
+
+       if (!PyArg_ParseTupleAndKeywords(
+                   args, kw, "s", kwlist, &filename))
+               return NULL;
+
+       result = cli_unlink(cli->cli, filename);
+
+       return PyInt_FromLong(result);
+}
+
+static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
+                                     PyObject *kw)
+{
+       cli_state_object *cli = (cli_state_object *)self;
+       static char *kwlist[] = { "fnum", NULL };
+       PyObject *result;
+       SEC_DESC *secdesc = NULL;
+       int fnum;
+       TALLOC_CTX *mem_ctx;
+
+       /* Parse parameters */
+
+       if (!PyArg_ParseTupleAndKeywords(
+                   args, kw, "i", kwlist, &fnum))
+               return NULL;
+
+       mem_ctx = talloc_init();
+
+       secdesc = cli_query_secdesc(cli->cli, fnum, mem_ctx);
+
+       if (cli_is_error(cli->cli)) {
+               PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed");
+               return NULL;
+       }
+
+       if (!secdesc) {
+               Py_INCREF(Py_None);
+               result = Py_None;
+               goto done;
+       }
+
+       if (!py_from_SECDESC(&result, secdesc)) {
+               PyErr_SetString(
+                       PyExc_TypeError,
+                       "Invalid security descriptor returned");
+               result = NULL;
+               goto done;
+       }
+
+ done:
+       talloc_destroy(mem_ctx);
+
+       return result;
+       
+}
+
+static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
+                                   PyObject *kw)
+{
+       cli_state_object *cli = (cli_state_object *)self;
+       static char *kwlist[] = { "fnum", "security_descriptor", NULL };
+       PyObject *py_secdesc;
+       SEC_DESC *secdesc;
+       TALLOC_CTX *mem_ctx = talloc_init();
+       int fnum;
+       BOOL result;
+
+       /* Parse parameters */
+
+       if (!PyArg_ParseTupleAndKeywords(
+                   args, kw, "iO", kwlist, &fnum, &py_secdesc))
+               return NULL;
+
+       if (!py_to_SECDESC(&secdesc, py_secdesc, mem_ctx)) {
+               PyErr_SetString(PyExc_TypeError, 
+                               "Invalid security descriptor");
+               return NULL;
+       }
+
+       result = cli_set_secdesc(cli->cli, fnum, secdesc);
+
+       if (cli_is_error(cli->cli)) {
+               PyErr_SetString(PyExc_RuntimeError, "set_secdesc failed");
+               return NULL;
+       }
+
+       return PyInt_FromLong(result);
+}
+
 static PyMethodDef smb_hnd_methods[] = {
 
+       /* Session and connection handling */
+
        { "session_request", (PyCFunction)py_smb_session_request, 
          METH_VARARGS | METH_KEYWORDS, "Request a session" },
 
@@ -155,6 +312,25 @@ static PyMethodDef smb_hnd_methods[] = {
        { "tconx", (PyCFunction)py_smb_tconx,
          METH_VARARGS | METH_KEYWORDS, "Tree connect" },
 
+       /* File operations */
+
+       { "nt_create_andx", (PyCFunction)py_smb_nt_create_andx,
+         METH_VARARGS | METH_KEYWORDS, "NT Create&X" },
+
+       { "close", (PyCFunction)py_smb_close,
+         METH_VARARGS | METH_KEYWORDS, "Close" },
+
+       { "unlink", (PyCFunction)py_smb_unlink,
+         METH_VARARGS | METH_KEYWORDS, "Unlink" },
+
+       /* Security descriptors */
+
+       { "query_secdesc", (PyCFunction)py_smb_query_secdesc,
+         METH_VARARGS | METH_KEYWORDS, "Query security descriptor" },
+
+       { "set_secdesc", (PyCFunction)py_smb_set_secdesc,
+         METH_VARARGS | METH_KEYWORDS, "Set security descriptor" },
+
        { NULL }
 };
 
index f1cf6aca99077df96132090991aa53292c833f5b..6daa32d0f41e568ff8ac1ebf4f2ff423864dbeff 100644 (file)
@@ -57,7 +57,7 @@ PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args,
 
        /* Call rpc function */
        
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
@@ -261,7 +261,7 @@ PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args,
 
        /* Call rpc function */
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
@@ -341,7 +341,7 @@ PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
                return NULL;
        }
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
index fe6d7536d39e85b51de740d4ff0f7b4ca680d8c0..55716aca6ec45b2f8efa7c817b1145d4acc8fefa 100644 (file)
@@ -53,7 +53,7 @@ PyObject *spoolss_enumports(PyObject *self, PyObject *args, PyObject *kw)
                return NULL;
        }
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
index a300eada864eb7bc2fe3fd87e5f7c472c91aaf16..a96498dddc7127a184875c511a4867c596198440 100644 (file)
@@ -56,7 +56,7 @@ PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
                return NULL;
        }
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
@@ -304,7 +304,7 @@ PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
                return NULL;
        }
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
@@ -439,7 +439,7 @@ PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
                    &PyDict_Type, &info, &PyDict_Type, &creds))
                return NULL;
 
-       if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
+       if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
                PyErr_SetString(spoolss_error, errstr);
                free(errstr);
                goto done;
index e5044943be30186ce061760d23e338005d3022c8..06aebe61eb5ede6e9d95ae09a8ded31041c18ece 100644 (file)
@@ -329,18 +329,35 @@ pytdbpack_calc_reqd_len(char *format_str,
 }
 
 
+static PyObject *pytdbpack_bad_type(char ch,
+                                   const char *expected,
+                                   PyObject *val_obj)
+{
+       PyObject *r = PyObject_Repr(val_obj);
+       if (!r)
+               return NULL;
+       PyErr_Format(PyExc_TypeError,
+                    "tdbpack: format '%c' requires %s, not %s",
+                    ch, expected, PyString_AS_STRING(r));
+       Py_DECREF(r);
+       return val_obj;
+}
+
+
 /*
-  Calculate the number of bytes required to pack a single value.
-*/
+ * Calculate the number of bytes required to pack a single value.  While doing
+ * this, also conduct some initial checks that the argument types are
+ * reasonable.
+ *
+ * Returns -1 on exception.
+ */
 static int
 pytdbpack_calc_item_len(char ch,
                        PyObject *val_obj)
 {
        if (ch == 'd' || ch == 'w') {
                if (!PyInt_Check(val_obj)) {
-                       PyErr_Format(PyExc_TypeError,
-                                    "tdbpack: format '%c' requires an Int",
-                                    ch);
+                       pytdbpack_bad_type(ch, "Int", val_obj);
                        return -1;
                }
                if (ch == 'w')
@@ -353,10 +370,7 @@ pytdbpack_calc_item_len(char ch,
        else if (ch == 'f' || ch == 'P' || ch == 'B') {
                /* nul-terminated 8-bit string */
                if (!PyString_Check(val_obj)) {
-                       PyErr_Format(PyExc_TypeError,
-                                    "tdbpack: format '%c' requires a String",
-                                    ch);
-                       return -1;
+                       pytdbpack_bad_type(ch, "String", val_obj);
                }
                
                if (ch == 'B') {
@@ -371,7 +385,7 @@ pytdbpack_calc_item_len(char ch,
        }
        else {  
                PyErr_Format(PyExc_ValueError,
-                            __FUNCTION__ ": format character '%c' is not supported",
+                            "tdbpack: format character '%c' is not supported",
                             ch);
                
                return -1;
index 6d03ca633a7f969082147907f87794cb54f64795..bf62f3b877314ea5a0d508b844c73b5395af7f7d 100755 (executable)
@@ -157,7 +157,8 @@ setup(
 
     Extension(name = "smb",
               sources = [samba_srcdir + "python/py_smb.c",
-                         samba_srcdir + "python/py_common.c"],
+                         samba_srcdir + "python/py_common.c",
+                         samba_srcdir + "python/py_ntsec.c"],
               libraries = lib_list,
               library_dirs = ["/usr/kerberos/lib"],
               extra_compile_args = flags_list,