diff options
-rw-r--r-- | lib/smbconf/pysmbconf.c | 124 | ||||
-rw-r--r-- | python/samba/tests/smbconf.py | 26 |
2 files changed, 150 insertions, 0 deletions
diff --git a/lib/smbconf/pysmbconf.c b/lib/smbconf/pysmbconf.c index bc4035a4468..6219b6b5d3a 100644 --- a/lib/smbconf/pysmbconf.c +++ b/lib/smbconf/pysmbconf.c @@ -364,6 +364,124 @@ static PyObject *obj_delete_share(py_SMBConf_Object * self, PyObject * args) Py_RETURN_NONE; } +static char *py_get_kv_str(TALLOC_CTX * mem_ctx, PyObject * obj, Py_ssize_t idx) +{ + char *ss = NULL; + PyObject *pystr = PySequence_GetItem(obj, idx); + if (pystr == NULL) { + return NULL; + } + if (!PyUnicode_Check(pystr)) { + PyErr_SetString(PyExc_TypeError, "keys/values expect a str"); + Py_CLEAR(pystr); + return NULL; + } + ss = talloc_strdup(mem_ctx, PyUnicode_AsUTF8(pystr)); + Py_CLEAR(pystr); + return ss; +} + +static PyObject *obj_create_set_share(py_SMBConf_Object * self, PyObject * args) +{ + sbcErr err; + char *servicename = NULL; + PyObject *kvs = NULL; + Py_ssize_t size, idx; + struct smbconf_service *tmp_service = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(self->mem_ctx); + + if (!PyArg_ParseTuple(args, "sO", &servicename, &kvs)) { + talloc_free(tmp_ctx); + return NULL; + } + + if (PySequence_Check(kvs) == 0) { + PyErr_SetString(PyExc_TypeError, + "a sequence object is required"); + talloc_free(tmp_ctx); + return NULL; + } + + size = PySequence_Size(kvs); + if (size == -1) { + PyErr_SetString(PyExc_ValueError, "failed to get size"); + talloc_free(tmp_ctx); + return NULL; + } + + tmp_service = talloc_zero(tmp_ctx, struct smbconf_service); + if (tmp_service == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + + tmp_service->name = talloc_strdup(tmp_service, servicename); + if (tmp_service->name == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + tmp_service->num_params = (uint32_t) size; + tmp_service->param_names = talloc_array(tmp_ctx, char *, size); + if (tmp_service->param_names == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + tmp_service->param_values = talloc_array(tmp_ctx, char *, size); + if (tmp_service->param_values == NULL) { + PyErr_NoMemory(); + talloc_free(tmp_ctx); + return NULL; + } + + for (idx = 0; idx < size; idx++) { + char *tmp_str = NULL; + PyObject *tmp_pair = PySequence_GetItem(kvs, idx); + if (tmp_pair == NULL) { + talloc_free(tmp_ctx); + return NULL; + } + if (PySequence_Size(tmp_pair) != 2) { + PyErr_SetString(PyExc_ValueError, + "expecting two-item tuples"); + Py_CLEAR(tmp_pair); + talloc_free(tmp_ctx); + return NULL; + } + + /* fetch key */ + tmp_str = py_get_kv_str(tmp_ctx, tmp_pair, 0); + if (tmp_str == NULL) { + Py_CLEAR(tmp_pair); + talloc_free(tmp_ctx); + return NULL; + } + tmp_service->param_names[idx] = tmp_str; + + /* fetch value */ + tmp_str = py_get_kv_str(tmp_ctx, tmp_pair, 1); + if (tmp_str == NULL) { + Py_CLEAR(tmp_pair); + talloc_free(tmp_ctx); + return NULL; + } + tmp_service->param_values[idx] = tmp_str; + + Py_CLEAR(tmp_pair); + } + + err = smbconf_create_set_share(self->conf_ctx, tmp_service); + if (err != SBC_ERR_OK) { + py_raise_SMBConfError(err); + talloc_free(tmp_ctx); + return NULL; + } + talloc_free(tmp_ctx); + Py_RETURN_NONE; +} + PyDoc_STRVAR(obj_requires_messaging_doc, "requires_messaging() -> bool\n" "\n" @@ -417,6 +535,10 @@ PyDoc_STRVAR(obj_delete_share_doc, "delete_share(str) -> None\n" "Delete a service from the configuration.\n"); +PyDoc_STRVAR(obj_create_set_share_doc, +"create_set_share(str, [(str, str)...]) -> None\n" +"Create and set the definition of a service.\n"); + static PyMethodDef py_smbconf_obj_methods[] = { { "requires_messaging", (PyCFunction) obj_requires_messaging, METH_NOARGS, obj_requires_messaging_doc }, @@ -430,6 +552,8 @@ static PyMethodDef py_smbconf_obj_methods[] = { obj_get_config_doc }, { "create_share", (PyCFunction) obj_create_share, METH_VARARGS, obj_create_share_doc }, + { "create_set_share", (PyCFunction) obj_create_set_share, METH_VARARGS, + obj_create_set_share_doc }, { "drop", (PyCFunction) obj_drop, METH_NOARGS, obj_drop_doc }, { "set_parameter", (PyCFunction) obj_set_parameter, METH_VARARGS, diff --git a/python/samba/tests/smbconf.py b/python/samba/tests/smbconf.py index f3c945c1ace..76b0efd2e48 100644 --- a/python/samba/tests/smbconf.py +++ b/python/samba/tests/smbconf.py @@ -184,6 +184,32 @@ class SMBConfTests(samba.tests.TestCase): names = sconf.share_names() self.assertEqual(names, ["bob"]) + def test_create_set_share(self): + sconf = self.s3smbconf.init_reg(None) + sconf.drop() + + params = [ + ("path", "/mnt/baz"), + ("browseable", "yes"), + ("read only", "no"), + ] + sconf.create_set_share("baz", params) + self.assertEqual(sconf.get_share("baz"), ("baz", params)) + + self.assertRaises( + self.smbconf.SMBConfError, sconf.create_set_share, "baz", params + ) + self.assertRaises(TypeError, sconf.create_set_share, "baz", None) + self.assertRaises( + ValueError, sconf.create_set_share, "baz", [None, None] + ) + self.assertRaises( + TypeError, sconf.create_set_share, "baz", [("hi", None)] + ) + self.assertRaises( + ValueError, sconf.create_set_share, "baz", [("a", "b", "c")] + ) + if __name__ == "__main__": import unittest |