py3: Remove PyStr_FromString() compatability macro
[samba.git] / lib / ldb / pyldb.c
index afc86300f3dbcf536794014417a68311d1fc5c8b..6f43cca78ca5d6ad814025b1fdbdbbb737998cc3 100644 (file)
@@ -34,6 +34,9 @@
 #include "pyldb.h"
 #include "dlinklist.h"
 
+/* discard signature of 'func' in favour of 'target_sig' */
+#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
+
 struct py_ldb_search_iterator_reply;
 
 typedef struct {
@@ -82,8 +85,6 @@ static struct ldb_message_element *PyObject_AsMessageElement(
 static PyTypeObject PyLdbBytesType;
 
 #if PY_MAJOR_VERSION >= 3
-#define PyStr_Check PyUnicode_Check
-#define PyStr_FromString PyUnicode_FromString
 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
 #define PyStr_FromFormat PyUnicode_FromFormat
 #define PyStr_FromFormatV PyUnicode_FromFormatV
@@ -91,6 +92,8 @@ static PyTypeObject PyLdbBytesType;
 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
 #define PyInt_FromLong PyLong_FromLong
 
+#define PYARG_STR_UNI "es"
+
 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
 {
        PyObject* result = NULL;
@@ -101,14 +104,14 @@ static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
        return result;
 }
 #else
-#define PyStr_Check PyString_Check
-#define PyStr_FromString PyString_FromString
 #define PyStr_FromStringAndSize PyString_FromStringAndSize
 #define PyStr_FromFormat PyString_FromFormat
 #define PyStr_FromFormatV PyString_FromFormatV
 #define PyStr_AsUTF8 PyString_AsString
 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
 
+#define PYARG_STR_UNI "et"
+
 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
 const char *
 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
@@ -147,9 +150,9 @@ static PyObject *py_ldb_control_str(PyLdbControlObject *self)
                        PyErr_NoMemory();
                        return NULL;
                }
-               return PyStr_FromString(control);
+               return PyUnicode_FromString(control);
        } else {
-               return PyStr_FromString("ldb control");
+               return PyUnicode_FromString("ldb control");
        }
 }
 
@@ -185,17 +188,19 @@ static PyObject *wrap_text(const char *type, PyObject *wrapped)
        return inst;
 }
 
-static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
+static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
-       return PyStr_FromString(self->data->oid);
+       return PyUnicode_FromString(self->data->oid);
 }
 
-static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
+static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        return PyBool_FromLong(self->data->critical);
 }
 
-static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
+static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
 {
        if (PyObject_IsTrue(value)) {
                self->data->critical = true;
@@ -256,9 +261,16 @@ static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject
 }
 
 static PyGetSetDef py_ldb_control_getset[] = {
-       { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
-       { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
-       { NULL }
+       {
+               .name = discard_const_p(char, "oid"),
+               .get  = (getter)py_ldb_control_get_oid,
+       },
+       {
+               .name = discard_const_p(char, "critical"),
+               .get  = (getter)py_ldb_control_get_critical,
+               .set  = (setter)py_ldb_control_set_critical,
+       },
+       { .name = NULL },
 };
 
 static PyTypeObject PyLdbControl = {
@@ -440,7 +452,7 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
        }
 
        for (i = 0;result->refs && result->refs[i]; i++) {
-               PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
+               PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i]));
        }
        ret->referals = referals;
        return (PyObject *)ret;
@@ -476,44 +488,51 @@ static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
        return res;
 }
 
-static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_validate(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        return PyBool_FromLong(ldb_dn_validate(self->dn));
 }
 
-static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        return PyBool_FromLong(ldb_dn_is_valid(self->dn));
 }
 
-static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        return PyBool_FromLong(ldb_dn_is_special(self->dn));
 }
 
-static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        return PyBool_FromLong(ldb_dn_is_null(self->dn));
 }
  
-static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
-       return PyStr_FromString(ldb_dn_get_casefold(self->dn));
+       return PyUnicode_FromString(ldb_dn_get_casefold(self->dn));
 }
 
 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
 {
-       return PyStr_FromString(ldb_dn_get_linearized(self->dn));
+       return PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
 }
 
-static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
-       return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
+       return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn));
 }
 
-static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
-       return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
+       return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
 }
 
 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
@@ -524,7 +543,7 @@ static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyO
                                         discard_const_p(char *, kwnames),
                                         &mode))
                return NULL;
-       return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
+       return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
 }
 
 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
@@ -571,7 +590,7 @@ static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject
 
 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
 {
-       PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
+       PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
        PyObject *repr, *result;
        if (str == NULL)
                return NULL;
@@ -607,7 +626,8 @@ static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
        return richcmp(ret, op);
 }
 
-static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
        struct ldb_dn *parent;
@@ -704,7 +724,7 @@ static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *arg
                Py_RETURN_NONE;
        }
 
-       return PyStr_FromString(name);
+       return PyUnicode_FromString(name);
 }
 
 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
@@ -749,7 +769,8 @@ static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn;
        const char *name;
@@ -761,10 +782,11 @@ static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
                Py_RETURN_NONE;
        }
 
-       return PyStr_FromString(name);
+       return PyUnicode_FromString(name);
 }
 
-static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
+static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn;
        const struct ldb_val *val;
@@ -792,7 +814,9 @@ static PyMethodDef py_ldb_dn_methods[] = {
                "Check whether this is a null DN." },
        { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
                NULL },
-       { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
+       { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction,
+                                               py_ldb_dn_get_linearized),
+               METH_NOARGS,
                NULL },
        { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
                "S.canonical_str() -> string\n"
@@ -802,7 +826,9 @@ static PyMethodDef py_ldb_dn_methods[] = {
        { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
                "S.canonical_ex_str() -> string\n"
                "Canonical version of this DN (like a posix path, with terminating newline)." },
-       { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
+       { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction,
+                                             py_ldb_dn_extended_str),
+               METH_VARARGS | METH_KEYWORDS,
                "S.extended_str(mode=1) -> string\n"
                "Extended version of this DN" },
        { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
@@ -893,22 +919,22 @@ static PySequenceMethods py_ldb_dn_seq = {
 
 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
-       struct ldb_dn *ret;
-       char *str;
-       PyObject *py_ldb;
-       struct ldb_context *ldb_ctx;
-       TALLOC_CTX *mem_ctx;
-       PyLdbDnObject *py_ret;
+       struct ldb_dn *ret = NULL;
+       char *str = NULL;
+       PyObject *py_ldb = NULL;
+       struct ldb_context *ldb_ctx = NULL;
+       TALLOC_CTX *mem_ctx = NULL;
+       PyLdbDnObject *py_ret = NULL;
        const char * const kwnames[] = { "ldb", "dn", NULL };
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
                                         discard_const_p(char *, kwnames),
-                                        &py_ldb, &str))
-               return NULL;
+                                        &py_ldb, "utf8", &str))
+               goto out;
 
        if (!PyLdb_Check(py_ldb)) {
                PyErr_SetString(PyExc_TypeError, "Expected Ldb");
-               return NULL;
+               goto out;
        }
 
        ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
@@ -916,24 +942,28 @@ static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwa
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
                PyErr_NoMemory();
-               return NULL;
+               goto out;
        }
 
        ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
        if (!ldb_dn_validate(ret)) {
                talloc_free(mem_ctx);
                PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
-               return NULL;
+               goto out;
        }
 
        py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
        if (py_ret == NULL) {
                talloc_free(mem_ctx);
                PyErr_NoMemory();
-               return NULL;
+               goto out;
        }
        py_ret->mem_ctx = mem_ctx;
        py_ret->dn = ret;
+out:
+       if (str != NULL) {
+               PyMem_Free(discard_const_p(char, str));
+       }
        return (PyObject *)py_ret;
 }
 
@@ -1012,7 +1042,8 @@ static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_transaction_start(PyLdbObject *self)
+static PyObject *py_ldb_transaction_start(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
        int ldb_err;
@@ -1021,7 +1052,8 @@ static PyObject *py_ldb_transaction_start(PyLdbObject *self)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
+static PyObject *py_ldb_transaction_commit(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
        int ldb_err;
@@ -1030,7 +1062,8 @@ static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
+static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
        int ldb_err;
@@ -1039,7 +1072,8 @@ static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
+static PyObject *py_ldb_transaction_cancel(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
        int ldb_err;
@@ -1048,7 +1082,8 @@ static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
+static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
        int ldb_err;
@@ -1059,10 +1094,11 @@ static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
 
 static PyObject *py_ldb_repr(PyLdbObject *self)
 {
-       return PyStr_FromString("<ldb connection>");
+       return PyUnicode_FromString("<ldb connection>");
 }
 
-static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
+static PyObject *py_ldb_get_root_basedn(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
        if (dn == NULL)
@@ -1071,7 +1107,8 @@ static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
 }
 
 
-static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
+static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
        if (dn == NULL)
@@ -1079,7 +1116,8 @@ static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
        return py_ldb_dn_copy(dn);
 }
 
-static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
+static PyObject *py_ldb_get_config_basedn(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
        if (dn == NULL)
@@ -1087,7 +1125,8 @@ static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
        return py_ldb_dn_copy(dn);
 }
 
-static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
+static PyObject *py_ldb_get_default_basedn(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
        if (dn == NULL)
@@ -1114,7 +1153,7 @@ static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
                const char *str = NULL;
                Py_ssize_t size;
                PyObject *item = PyList_GetItem(list, i);
-               if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
+               if (!(PyUnicode_Check(item) || PyUnicode_Check(item))) {
                        PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
                        talloc_free(ret);
                        return NULL;
@@ -1198,7 +1237,7 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa
        const char * const kwnames[] = { "url", "flags", "options", NULL };
        struct ldb_context *ldb_ctx;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
                                         discard_const_p(char *, kwnames),
                                         &url, &flags, &py_options))
                return NULL;
@@ -1352,7 +1391,7 @@ static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
        }
 
        while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
-               char *key_str = PyStr_AsUTF8(key);
+               const char *key_str = PyStr_AsUTF8(key);
                if (ldb_attr_cmp(key_str, "dn") != 0) {
                        msg_el = PyObject_AsMessageElement(msg->elements, value,
                                                           mod_flags, key_str);
@@ -1658,9 +1697,13 @@ static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
                Py_RETURN_NONE;
        } else {
        /* We don't want this attached to the 'ldb' any more */
-               return Py_BuildValue(discard_const_p(char, "(iO)"),
-                                    ldif->changetype,
-                                    PyLdbMessage_FromMessage(ldif->msg));
+               PyObject *obj = PyLdbMessage_FromMessage(ldif->msg);
+               PyObject *result =
+                       Py_BuildValue(discard_const_p(char, "(iO)"),
+                                     ldif->changetype,
+                                     obj);
+               Py_CLEAR(obj);
+               return result;
        }
 }
 
@@ -1693,7 +1736,7 @@ static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
                return NULL;
        }
 
-       ret = PyStr_FromString(string);
+       ret = PyUnicode_FromString(string);
 
        talloc_free(mem_ctx);
 
@@ -1722,7 +1765,21 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
                ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
                talloc_steal(mem_ctx, ldif);
                if (ldif) {
-                       PyList_Append(list, ldb_ldif_to_pyobject(ldif));
+                       int res = 0;
+                       PyObject *py_ldif = ldb_ldif_to_pyobject(ldif);
+                       if (py_ldif == NULL) {
+                               Py_CLEAR(list);
+                               PyErr_BadArgument();
+                               talloc_free(mem_ctx);
+                               return NULL;
+                       }
+                       res = PyList_Append(list, py_ldif);
+                       Py_CLEAR(py_ldif);
+                       if (res == -1) {
+                               Py_CLEAR(list);
+                               talloc_free(mem_ctx);
+                               return NULL;
+                       }
                        last_dn = ldif->msg->dn;
                } else {
                        const char *last_dn_str = NULL;
@@ -1731,6 +1788,7 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
                                PyErr_SetString(PyExc_ValueError,
                                                "unable to parse LDIF "
                                                "string at first chunk");
+                               Py_CLEAR(list);
                                talloc_free(mem_ctx);
                                return NULL;
                        }
@@ -1747,6 +1805,7 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
                        PyErr_SetString(PyExc_ValueError,
                                        err_string);
                        talloc_free(mem_ctx);
+                       Py_CLEAR(list);
                        return NULL;
                }
        }
@@ -2005,7 +2064,7 @@ static int py_ldb_search_iterator_callback(struct ldb_request *req,
                return LDB_SUCCESS;
 
        case LDB_REPLY_REFERRAL:
-               reply->obj = PyStr_FromString(ares->referral);
+               reply->obj = PyUnicode_FromString(ares->referral);
                if (reply->obj == NULL) {
                        TALLOC_FREE(ares);
                        return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
@@ -2176,14 +2235,31 @@ static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_modules(PyLdbObject *self)
+static PyObject *py_ldb_modules(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
        PyObject *ret = PyList_New(0);
        struct ldb_module *mod;
 
+       if (ret == NULL) {
+               return PyErr_NoMemory();
+       }
        for (mod = ldb->modules; mod; mod = mod->next) {
-               PyList_Append(ret, PyLdbModule_FromModule(mod));
+               PyObject *item = PyLdbModule_FromModule(mod);
+               int res = 0;
+               if (item == NULL) {
+                       PyErr_SetString(PyExc_RuntimeError,
+                               "Failed to load LdbModule");
+                       Py_CLEAR(ret);
+                       return NULL;
+               }
+               res = PyList_Append(ret, item);
+               Py_CLEAR(item);
+               if (res == -1) {
+                       Py_CLEAR(ret);
+                       return NULL;
+               }
        }
 
        return ret;
@@ -2215,7 +2291,8 @@ static const struct ldb_dn_extended_syntax test_dn_syntax = {
        .write_hex_fn     = ldb_handler_copy,
 };
 
-static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
+static PyObject *py_ldb_register_test_extensions(PyLdbObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
        int ret;
@@ -2261,22 +2338,28 @@ static PyMethodDef py_ldb_methods[] = {
                NULL },
        { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
                NULL },
-       { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
+       { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect),
+               METH_VARARGS|METH_KEYWORDS,
                "S.connect(url, flags=0, options=None) -> None\n"
                "Connect to a LDB URL." },
-       { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
+       { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify),
+               METH_VARARGS|METH_KEYWORDS,
                "S.modify(message, controls=None, validate=False) -> None\n"
                "Modify an entry." },
-       { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
+       { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add),
+               METH_VARARGS|METH_KEYWORDS,
                "S.add(message, controls=None) -> None\n"
                "Add an entry." },
-       { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
+       { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete),
+               METH_VARARGS|METH_KEYWORDS,
                "S.delete(dn, controls=None) -> None\n"
                "Remove an entry." },
-       { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
+       { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename),
+               METH_VARARGS|METH_KEYWORDS,
                "S.rename(old_dn, new_dn, controls=None) -> None\n"
                "Rename an entry." },
-       { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
+       { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search),
+               METH_VARARGS|METH_KEYWORDS,
                "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
                "Search in a database.\n"
                "\n"
@@ -2287,7 +2370,9 @@ static PyMethodDef py_ldb_methods[] = {
                ":param controls: Optional list of controls\n"
                ":return: ldb.Result object\n"
        },
-       { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
+       { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction,
+                                                py_ldb_search_iterator),
+               METH_VARARGS|METH_KEYWORDS,
                "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
                "Search in a database.\n"
                "\n"
@@ -2359,8 +2444,11 @@ static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
 }
 
 static PyGetSetDef py_ldb_getset[] = {
-       { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
-       { NULL }
+       {
+               .name = discard_const_p(char, "firstmodule"),
+               .get  = (getter)py_ldb_get_firstmodule,
+       },
+       { .name = NULL },
 };
 
 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
@@ -2475,11 +2563,23 @@ static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
 }
 
 static PyGetSetDef py_ldb_result_getset[] = {
-       { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
-       { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
-       { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
-       { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
-       { NULL }
+       {
+               .name = discard_const_p(char, "controls"),
+               .get  = (getter)py_ldb_result_get_controls,
+       },
+       {
+               .name = discard_const_p(char, "msgs"),
+               .get  = (getter)py_ldb_result_get_msgs,
+       },
+       {
+               .name = discard_const_p(char, "referals"),
+               .get  = (getter)py_ldb_result_get_referals,
+       },
+       {
+               .name = discard_const_p(char, "count"),
+               .get  = (getter)py_ldb_result_get_count,
+       },
+       { .name = NULL },
 };
 
 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
@@ -2504,7 +2604,7 @@ static PySequenceMethods py_ldb_result_seq = {
 
 static PyObject *py_ldb_result_repr(PyLdbObject *self)
 {
-       return PyStr_FromString("<ldb result>");
+       return PyUnicode_FromString("<ldb result>");
 }
 
 
@@ -2589,7 +2689,8 @@ static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
        return py_ret;
 }
 
-static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
+static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        PyObject *py_ret = NULL;
 
@@ -2623,7 +2724,8 @@ static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
        return py_ret;
 }
 
-static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
+static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        if (self->state.req == NULL) {
                PyErr_SetString(PyExc_RuntimeError,
@@ -2647,7 +2749,7 @@ static PyMethodDef py_ldb_search_iterator_methods[] = {
 
 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
 {
-       return PyStr_FromString("<ldb search iterator>");
+       return PyUnicode_FromString("<ldb search iterator>");
 }
 
 static PyTypeObject PyLdbSearchIterator = {
@@ -2670,22 +2772,25 @@ static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
 
 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
 {
-       return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
+       return PyUnicode_FromString(pyldb_Module_AsModule(self)->ops->name);
 }
 
-static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
+static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
+static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
+static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
        Py_RETURN_NONE;
@@ -2825,7 +2930,8 @@ static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
 }
 
 static PyMethodDef py_ldb_module_methods[] = {
-       { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
+       { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search),
+               METH_VARARGS|METH_KEYWORDS, NULL },
        { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
        { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
        { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
@@ -3205,7 +3311,7 @@ static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
                ret = PyStr_FromFormat("MessageElement([%s])", element_str);
                talloc_free(element_str);
        } else {
-               ret = PyStr_FromString("MessageElement([])");
+               ret = PyUnicode_FromString("MessageElement([])");
        }
 
        return ret;
@@ -3233,8 +3339,11 @@ static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
 }
 
 static PyGetSetDef py_ldb_msg_element_getset[] = {
-       { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
-       { NULL }
+       {
+               .name = discard_const_p(char, "text"),
+               .get  = (getter)py_ldb_msg_element_get_text,
+       },
+       { .name = NULL }
 };
 
 static PyTypeObject PyLdbMessageElement = {
@@ -3308,17 +3417,18 @@ static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args
        Py_RETURN_NONE;
 }
 
-static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
+static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_message *msg = pyldb_Message_AsMessage(self);
        Py_ssize_t i, j = 0;
        PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
        if (msg->dn != NULL) {
-               PyList_SetItem(obj, j, PyStr_FromString("dn"));
+               PyList_SetItem(obj, j, PyUnicode_FromString("dn"));
                j++;
        }
        for (i = 0; i < msg->num_elements; i++) {
-               PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
+               PyList_SetItem(obj, j, PyUnicode_FromString(msg->elements[i].name));
                j++;
        }
        return obj;
@@ -3327,7 +3437,7 @@ static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
 {
        struct ldb_message_element *el;
-       char *name;
+       const char *name;
        struct ldb_message *msg = pyldb_Message_AsMessage(self);
        name = PyStr_AsUTF8(py_name);
        if (name == NULL) {
@@ -3388,24 +3498,53 @@ static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObje
        return PyObject_FromLdbValue(&el->values[idx]);
 }
 
-static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
+static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_message *msg = pyldb_Message_AsMessage(self);
        Py_ssize_t i, j = 0;
        PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
+       if (l == NULL) {
+               return PyErr_NoMemory();
+       }
        if (msg->dn != NULL) {
-               PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
+               PyObject *value = NULL;
+               PyObject *obj = pyldb_Dn_FromDn(msg->dn);
+               int res = 0;
+               value = Py_BuildValue("(sO)", "dn", obj);
+               Py_CLEAR(obj);
+               if (value == NULL) {
+                       Py_CLEAR(l);
+                       return NULL;
+               }
+               res = PyList_SetItem(l, 0, value);
+               if (res == -1) {
+                       Py_CLEAR(l);
+                       return NULL;
+               }
                j++;
        }
        for (i = 0; i < msg->num_elements; i++, j++) {
+               PyObject *value = NULL;
                PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
-               PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
-               PyList_SetItem(l, j, value);
+               int res = 0;
+               Py_CLEAR(py_el);
+               value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
+               if (value == NULL ) {
+                       Py_CLEAR(l);
+                       return NULL;
+               }
+               res = PyList_SetItem(l, 0, value);
+               if (res == -1) {
+                       Py_CLEAR(l);
+                       return NULL;
+               }
        }
        return l;
 }
 
-static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
+static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self,
+               PyObject *Py_UNUSED(ignored))
 {
        struct ldb_message *msg = pyldb_Message_AsMessage(self);
        Py_ssize_t i = 0;
@@ -3432,7 +3571,11 @@ static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
                PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
                return NULL;
        }
-
+       if (el->name == NULL) {
+               PyErr_SetString(PyExc_ValueError,
+                               "The element has no name");
+               return NULL;
+       }
        ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
 
@@ -3461,13 +3604,14 @@ static PyMethodDef py_ldb_msg_methods[] = {
                "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
                "Class method to create ldb.Message object from Dictionary.\n"
                "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
-       { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
+       { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
                "S.keys() -> list\n\n"
                "Return sequence of all attribute names." },
        { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
                "S.remove(name)\n\n"
                "Remove all entries for attributes with the specified name."},
-       { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
+       { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get),
+               METH_VARARGS | METH_KEYWORDS,
          "msg.get(name,default=None,idx=None) -> string\n"
          "idx is the index into the values array\n"
          "if idx is None, then a list is returned\n"
@@ -3485,7 +3629,7 @@ static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
 {
        PyObject *list, *iter;
 
-       list = py_ldb_msg_keys(self);
+       list = py_ldb_msg_keys(self, NULL);
        iter = PyObject_GetIter(list);
        Py_DECREF(list);
        return iter;
@@ -3493,7 +3637,7 @@ static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
 
 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
 {
-       char *attr_name;
+       const char *attr_name;
 
        attr_name = PyStr_AsUTF8(name);
        if (attr_name == NULL) {
@@ -3617,9 +3761,16 @@ static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
 }
 
 static PyGetSetDef py_ldb_msg_getset[] = {
-       { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
-       { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
-       { NULL }
+       {
+               .name = discard_const_p(char, "dn"),
+               .get  = (getter)py_ldb_msg_get_dn,
+               .set  = (setter)py_ldb_msg_set_dn,
+       },
+       {
+               .name = discard_const_p(char, "text"),
+               .get  = (getter)py_ldb_msg_get_text,
+       },
+       { .name = NULL },
 };
 
 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
@@ -3755,7 +3906,7 @@ static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
                for (len = 0; req->op.search.attrs[len]; len++);
                py_attrs = PyList_New(len);
                for (i = 0; i < len; i++)
-                       PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
+                       PyList_SetItem(py_attrs, i, PyUnicode_FromString(req->op.search.attrs[i]));
        }
 
        py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
@@ -4003,6 +4154,7 @@ static PyObject *py_register_module(PyObject *module, PyObject *args)
        int ret;
        struct ldb_module_ops *ops;
        PyObject *input;
+       PyObject *tmp;
 
        if (!PyArg_ParseTuple(args, "O", &input))
                return NULL;
@@ -4013,8 +4165,10 @@ static PyObject *py_register_module(PyObject *module, PyObject *args)
                return NULL;
        }
 
-       ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
+       tmp = PyObject_GetAttrString(input, discard_const_p(char, "name"));
+       ops->name = talloc_strdup(ops, PyStr_AsUTF8(tmp));
 
+       Py_XDECREF(tmp);
        Py_INCREF(input);
        ops->private_data = input;
        ops->init_context = py_module_init;
@@ -4049,7 +4203,7 @@ static PyObject *py_timestring(PyObject *module, PyObject *args)
        if (!PyArg_ParseTuple(args, "l", &t_val))
                return NULL;
        tresult = ldb_timestring(NULL, (time_t) t_val);
-       ret = PyStr_FromString(tresult);
+       ret = PyUnicode_FromString(tresult);
        talloc_free(tresult);
        return ret;
 }
@@ -4091,7 +4245,7 @@ static PyObject *py_binary_encode(PyObject *self, PyObject *args)
                PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
                return NULL;
        }
-       ret = PyStr_FromString(encoded);
+       ret = PyUnicode_FromString(encoded);
        talloc_free(encoded);
        return ret;
 }
@@ -4131,7 +4285,8 @@ static PyMethodDef py_ldb_global_methods[] = {
        { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
                "S.valid_attr_name(name) -> bool\n\nn"
                "Check whether the supplied name is a valid attribute name." },
-       { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
+       { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new),
+               METH_VARARGS|METH_KEYWORDS,
                "S.open() -> Ldb\n\n"
                "Open a new LDB context." },
        { "binary_encode", py_binary_encode, METH_VARARGS,
@@ -4271,6 +4426,8 @@ static PyObject* module_init(void)
        ADD_LDB_INT(FLG_ENABLE_TRACING);
        ADD_LDB_INT(FLG_DONT_CREATE_DB);
 
+       ADD_LDB_INT(PACKING_FORMAT);
+       ADD_LDB_INT(PACKING_FORMAT_V2);
 
        /* Historical misspelling */
        PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
@@ -4304,6 +4461,7 @@ static PyObject* module_init(void)
        ADD_LDB_STRING(SYNTAX_DN);
        ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
        ADD_LDB_STRING(SYNTAX_INTEGER);
+       ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
        ADD_LDB_STRING(SYNTAX_BOOLEAN);
        ADD_LDB_STRING(SYNTAX_OCTET_STRING);
        ADD_LDB_STRING(SYNTAX_UTC_TIME);