Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/lib/ldb/pyldb.c

    r414 r745  
    66   Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
    77   Copyright (C) 2006 Simo Sorce <idra@samba.org>
    8    Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
    9    Copyright (C) 2009 Matthias Dieter Wallnöfer
    10 
    11         ** NOTE! The following LGPL license applies to the ldb
    12         ** library. This does NOT imply that all of Samba is released
    13         ** under the LGPL
     8   Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
     9   Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
     10
     11    ** NOTE! The following LGPL license applies to the ldb
     12    ** library. This does NOT imply that all of Samba is released
     13    ** under the LGPL
    1414
    1515   This library is free software; you can redistribute it and/or
     
    2727*/
    2828
    29 #include "replace.h"
     29#include <Python.h>
     30#include <pytalloc.h>
    3031#include "ldb_private.h"
    31 #include <Python.h>
    3232#include "pyldb.h"
     33
     34void initldb(void);
     35static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
     36static PyObject *PyExc_LdbError;
     37
     38staticforward PyTypeObject PyLdbControl;
     39staticforward PyTypeObject PyLdbResult;
     40staticforward PyTypeObject PyLdbMessage;
     41staticforward PyTypeObject PyLdbModule;
     42staticforward PyTypeObject PyLdbDn;
     43staticforward PyTypeObject PyLdb;
     44staticforward PyTypeObject PyLdbMessageElement;
     45staticforward PyTypeObject PyLdbTree;
     46static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
     47static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
     48static struct ldb_message_element *PyObject_AsMessageElement(
     49                                                      TALLOC_CTX *mem_ctx,
     50                                                      PyObject *set_obj,
     51                                                      int flags,
     52                                                      const char *attr_name);
    3353
    3454/* There's no Py_ssize_t in 2.4, apparently */
     
    4363#endif
    4464
     65#define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
     66
     67
     68
     69static PyObject *py_ldb_control_str(PyLdbControlObject *self)
     70{
     71        if (self->data != NULL) {
     72                char* control = ldb_control_to_string(self->mem_ctx, self->data);
     73                if (control == NULL) {
     74                        PyErr_NoMemory();
     75                        return NULL;
     76                }
     77                return PyString_FromString(control);
     78        } else {
     79                return PyString_FromFormat("ldb control");
     80        }
     81}
     82
     83static void py_ldb_control_dealloc(PyLdbControlObject *self)
     84{
     85        if (self->mem_ctx != NULL) {
     86                talloc_free(self->mem_ctx);
     87        }
     88        self->ob_type->tp_free(self);
     89}
     90
     91static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
     92{
     93        return PyString_FromString(self->data->oid);
     94}
     95
     96static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
     97{
     98        return PyBool_FromLong(self->data->critical);
     99}
     100
     101static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
     102{
     103        if (PyObject_IsTrue(value)) {
     104                self->data->critical = true;
     105        } else {
     106                self->data->critical = false;
     107        }
     108        return 0;
     109}
     110
     111static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     112{
     113        char *data = NULL;
     114        const char *array[2];
     115        const char * const kwnames[] = { "ldb", "data", NULL };
     116        struct ldb_control *parsed_controls;
     117        PyLdbControlObject *ret;
     118        PyObject *py_ldb;
     119        TALLOC_CTX *mem_ctx;
     120        struct ldb_context *ldb_ctx;
     121
     122        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
     123                                         discard_const_p(char *, kwnames),
     124                                         &py_ldb, &data))
     125                return NULL;
     126
     127        mem_ctx = talloc_new(NULL);
     128        if (mem_ctx == NULL) {
     129                PyErr_NoMemory();
     130                return NULL;
     131        }
     132
     133        ldb_ctx = PyLdb_AsLdbContext(py_ldb);
     134        parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
     135
     136        if (!parsed_controls) {
     137                talloc_free(mem_ctx);
     138                PyErr_SetString(PyExc_ValueError, "unable to parse control string");
     139                return NULL;
     140        }
     141
     142        ret = PyObject_New(PyLdbControlObject, type);
     143        if (ret == NULL) {
     144                PyErr_NoMemory();
     145                talloc_free(mem_ctx);
     146                return NULL;
     147        }
     148
     149        ret->mem_ctx = mem_ctx;
     150
     151        ret->data = talloc_steal(mem_ctx, parsed_controls);
     152        if (ret->data == NULL) {
     153                Py_DECREF(ret);
     154                PyErr_NoMemory();
     155                talloc_free(mem_ctx);
     156                return NULL;
     157        }
     158
     159        return (PyObject *)ret;
     160}
     161
     162static PyGetSetDef py_ldb_control_getset[] = {
     163        { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
     164        { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
     165        { NULL }
     166};
     167
     168static PyTypeObject PyLdbControl = {
     169        .tp_name = "ldb.control",
     170        .tp_dealloc = (destructor)py_ldb_control_dealloc,
     171        .tp_getattro = PyObject_GenericGetAttr,
     172        .tp_basicsize = sizeof(PyLdbControlObject),
     173        .tp_getset = py_ldb_control_getset,
     174        .tp_doc = "LDB control.",
     175        .tp_str = (reprfunc)py_ldb_control_str,
     176        .tp_new = py_ldb_control_new,
     177        .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
     178};
     179
    45180static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
    46181{
     
    49184
    50185        PyErr_SetObject(error,
    51                                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
    52                                   ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
    53 }
    54 
    55 static PyObject *PyExc_LdbError;
    56 
    57 PyAPI_DATA(PyTypeObject) PyLdbMessage;
    58 PyAPI_DATA(PyTypeObject) PyLdbModule;
    59 PyAPI_DATA(PyTypeObject) PyLdbDn;
    60 PyAPI_DATA(PyTypeObject) PyLdb;
    61 PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
    62 PyAPI_DATA(PyTypeObject) PyLdbTree;
    63 
    64 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
    65                                                            struct ldb_message_element *el,
    66                                                            struct ldb_val *val)
    67 {
    68         struct ldb_val new_val;
    69         TALLOC_CTX *mem_ctx = talloc_new(NULL);
    70         PyObject *ret;
    71 
    72         new_val = *val;
    73 
    74         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
    75 
    76         talloc_free(mem_ctx);
    77 
    78         return ret;
     186                        Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
     187                                      ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
     188}
     189
     190static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
     191{
     192        return PyString_FromStringAndSize((const char *)val->data, val->length);
    79193}
    80194
    81195/**
    82  * Obtain a ldb DN from a Python object.
     196 * Create a Python object from a ldb_result.
    83197 *
    84  * @param mem_ctx Memory context
    85  * @param object Python object
    86  * @param ldb_ctx LDB context
    87  * @return Whether or not the conversion succeeded
     198 * @param result LDB result to convert
     199 * @return Python object with converted result (a list object)
    88200 */
    89 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
    90                    struct ldb_context *ldb_ctx, struct ldb_dn **dn)
    91 {
    92         struct ldb_dn *odn;
    93 
    94         if (ldb_ctx != NULL && PyString_Check(object)) {
    95                 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
    96                 *dn = odn;
    97                 return true;
    98         }
    99 
    100         if (PyLdbDn_Check(object)) {
    101                 *dn = PyLdbDn_AsDn(object);
    102                 return true;
    103         }
    104 
    105         PyErr_SetString(PyExc_TypeError, "Expected DN");
    106         return false;
     201static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
     202{
     203        TALLOC_CTX *ctl_ctx = talloc_new(NULL);
     204        PyLdbControlObject *ctrl;
     205        if (ctl_ctx == NULL) {
     206                PyErr_NoMemory();
     207                return NULL;
     208        }
     209
     210        ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
     211        if (ctrl == NULL) {
     212                PyErr_NoMemory();
     213                return NULL;
     214        }
     215        ctrl->mem_ctx = ctl_ctx;
     216        ctrl->data = talloc_steal(ctrl->mem_ctx, control);
     217        if (ctrl->data == NULL) {
     218                Py_DECREF(ctrl);
     219                PyErr_NoMemory();
     220                return NULL;
     221        }
     222        return (PyObject*) ctrl;
    107223}
    108224
     
    115231static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
    116232{
    117         PyObject *ret;
    118         int i;
     233        PyLdbResultObject *ret;
     234        PyObject *list, *controls, *referals;
     235        Py_ssize_t i;
     236
    119237        if (result == NULL) {
    120238                Py_RETURN_NONE;
    121         }
    122         ret = PyList_New(result->count);
     239        }
     240
     241        ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
     242        if (ret == NULL) {
     243                PyErr_NoMemory();
     244                return NULL;
     245        }
     246
     247        list = PyList_New(result->count);
     248        if (list == NULL) {
     249                PyErr_NoMemory();
     250                Py_DECREF(ret);
     251                return NULL;
     252        }
     253
    123254        for (i = 0; i < result->count; i++) {
    124                 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
    125                 );
    126         }
    127         return ret;
     255                PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
     256        }
     257
     258        ret->mem_ctx = talloc_new(NULL);
     259        if (ret->mem_ctx == NULL) {
     260                Py_DECREF(list);
     261                Py_DECREF(ret);
     262                PyErr_NoMemory();
     263                return NULL;
     264        }
     265
     266        ret->msgs = list;
     267
     268        if (result->controls) {
     269                controls = PyList_New(1);
     270                if (controls == NULL) {
     271                        Py_DECREF(ret);
     272                        PyErr_NoMemory();
     273                        return NULL;
     274                }
     275                for (i=0; result->controls[i]; i++) {
     276                        PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
     277                        if (ctrl == NULL) {
     278                                Py_DECREF(ret);
     279                                Py_DECREF(controls);
     280                                PyErr_NoMemory();
     281                                return NULL;
     282                        }
     283                        PyList_SetItem(controls, i, ctrl);
     284                }
     285        } else {
     286                /*
     287                 * No controls so we keep an empty list
     288                 */
     289                controls = PyList_New(0);
     290                if (controls == NULL) {
     291                        Py_DECREF(ret);
     292                        PyErr_NoMemory();
     293                        return NULL;
     294                }
     295        }
     296
     297        ret->controls = controls;
     298
     299        i = 0;
     300
     301        while (result->refs && result->refs[i]) {
     302                i++;
     303        }
     304
     305        referals = PyList_New(i);
     306        if (referals == NULL) {
     307                Py_DECREF(ret);
     308                PyErr_NoMemory();
     309                return NULL;
     310        }
     311
     312        for (i = 0;result->refs && result->refs[i]; i++) {
     313                PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
     314        }
     315        ret->referals = referals;
     316        return (PyObject *)ret;
    128317}
    129318
     
    137326 */
    138327static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
    139                                                                                            PyObject *obj)
     328                                               PyObject *obj)
    140329{
    141330        struct ldb_result *res;
    142         int i;
     331        Py_ssize_t i;
    143332
    144333        if (obj == Py_None)
     
    296485                "S.canonical_ex_str() -> string\n"
    297486                "Canonical version of this DN (like a posix path, with terminating newline)." },
    298         { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,
    299                 NULL },
    300487        { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
    301488                "S.parent() -> dn\n"
     
    308495                "Add a base DN to this DN." },
    309496        { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
    310                 NULL },
     497                "S.check_special(name) -> bool\n\n"
     498                "Check if name is a special DN name"},
    311499        { NULL }
    312500};
     
    366554
    367555        ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
    368 
    369         if (ret == NULL || !ldb_dn_validate(ret)) {
     556        if (!ldb_dn_validate(ret)) {
    370557                talloc_free(mem_ctx);
    371558                PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
     
    384571}
    385572
    386 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
    387 {
    388         PyLdbDnObject *py_ret;
    389 
    390         if (dn == NULL) {
    391                 Py_RETURN_NONE;
    392         }
    393 
    394         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
    395         if (py_ret == NULL) {
    396                 PyErr_NoMemory();
    397                 return NULL;
    398         }
    399         py_ret->mem_ctx = talloc_new(NULL);
    400         py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
    401         return (PyObject *)py_ret;
    402 }
    403 
    404573static void py_ldb_dn_dealloc(PyLdbDnObject *self)
    405574{
    406575        talloc_free(self->mem_ctx);
    407         self->ob_type->tp_free(self);
    408 }
    409 
    410 PyTypeObject PyLdbDn = {
    411         .tp_name = "Dn",
     576        PyObject_Del(self);
     577}
     578
     579static PyTypeObject PyLdbDn = {
     580        .tp_name = "ldb.Dn",
    412581        .tp_methods = py_ldb_dn_methods,
    413582        .tp_str = (reprfunc)py_ldb_dn_get_linearized,
     
    418587        .tp_new = py_ldb_dn_new,
    419588        .tp_dealloc = (destructor)py_ldb_dn_dealloc,
    420         .tp_basicsize = sizeof(PyLdbObject),
     589        .tp_basicsize = sizeof(PyLdbDnObject),
    421590        .tp_flags = Py_TPFLAGS_DEFAULT,
    422591};
     
    475644{
    476645        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
     646        Py_RETURN_NONE;
     647}
     648
     649static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
     650{
     651        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
    477652        Py_RETURN_NONE;
    478653}
     
    529704
    530705static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
    531                                                                                 const char *paramname)
     706                                        const char *paramname)
    532707{
    533708        const char **ret;
    534         int i;
     709        Py_ssize_t i;
    535710        if (!PyList_Check(list)) {
    536711                PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
     
    538713        }
    539714        ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
     715        if (ret == NULL) {
     716                PyErr_NoMemory();
     717                return NULL;
     718        }
     719
    540720        for (i = 0; i < PyList_Size(list); i++) {
    541721                PyObject *item = PyList_GetItem(list, i);
     
    545725                }
    546726                ret[i] = talloc_strndup(ret, PyString_AsString(item),
    547                                                            PyString_Size(item));
     727                                        PyString_Size(item));
    548728        }
    549729        ret[i] = NULL;
     
    642822{
    643823        PyObject *py_msg;
    644         int ret;
    645         if (!PyArg_ParseTuple(args, "O", &py_msg))
    646                 return NULL;
    647 
    648         if (!PyLdbMessage_Check(py_msg)) {
    649                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
    650                 return NULL;
    651         }
    652 
    653         ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
    654         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
    655 
    656         Py_RETURN_NONE;
    657 }
    658 
    659 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
    660 {
    661         PyObject *py_msg;
    662         int ret;
    663         Py_ssize_t dict_pos, msg_pos;
    664         struct ldb_message_element *msgel;
    665         struct ldb_message *msg;
     824        PyObject *py_controls = Py_None;
    666825        struct ldb_context *ldb_ctx;
    667826        struct ldb_request *req;
    668         PyObject *key, *value;
    669         PyObject *py_controls = Py_None;
     827        struct ldb_control **parsed_controls;
     828        struct ldb_message *msg;
     829        int ret;
    670830        TALLOC_CTX *mem_ctx;
    671         struct ldb_control **parsed_controls;
    672 
    673         if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls ))
    674                 return NULL;
     831
     832        if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls))
     833                return NULL;
     834
     835        mem_ctx = talloc_new(NULL);
     836        if (mem_ctx == NULL) {
     837                PyErr_NoMemory();
     838                return NULL;
     839        }
    675840        ldb_ctx = PyLdb_AsLdbContext(self);
    676841
    677         mem_ctx = talloc_new(NULL);
    678842        if (py_controls == Py_None) {
    679843                parsed_controls = NULL;
    680844        } else {
    681                 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
    682                 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
     845                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     846                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
    683847                talloc_free(controls);
    684848        }
    685         if (PyDict_Check(py_msg)) {
    686                 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
    687                 msg = ldb_msg_new(mem_ctx);
    688                 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
    689                 msg_pos = dict_pos = 0;
    690                 if (dn_value) {
    691                         if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
    692                                 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
    693                                 talloc_free(mem_ctx);
    694                                 return NULL;
    695                         }
    696                         if (msg->dn == NULL) {
    697                                 PyErr_SetString(PyExc_TypeError, "dn set but not found");
    698                                 talloc_free(mem_ctx);
    699                                 return NULL;
    700                         }
    701                 }
    702 
    703                 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
    704                         char *key_str = PyString_AsString(key);
    705                         if (strcmp(key_str, "dn") != 0) {
    706                                 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
    707                                 if (msgel == NULL) {
    708                                         PyErr_SetString(PyExc_TypeError, "unable to import element");
    709                                         talloc_free(mem_ctx);
    710                                         return NULL;
    711                                 }
    712                                 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
    713                                 msg_pos++;
    714                         }
    715                 }
    716 
    717                 if (msg->dn == NULL) {
    718                         PyErr_SetString(PyExc_TypeError, "no dn set");
    719                         talloc_free(mem_ctx);
    720                         return NULL;
    721                 }
    722 
    723                 msg->num_elements = msg_pos;
    724         } else {
    725                 msg = PyLdbMessage_AsMessage(py_msg);
    726         }
    727        
     849
     850        if (!PyLdbMessage_Check(py_msg)) {
     851                PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
     852                talloc_free(mem_ctx);
     853                return NULL;
     854        }
     855        msg = PyLdbMessage_AsMessage(py_msg);
     856
    728857        ret = ldb_msg_sanity_check(ldb_ctx, msg);
    729         if (ret != LDB_SUCCESS) {
    730                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
     858        if (ret != LDB_SUCCESS) {
     859                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    731860                talloc_free(mem_ctx);
    732861                return NULL;
    733         }
    734 
    735         ret = ldb_build_add_req(&req, ldb_ctx, ldb_ctx,
    736                                         msg,
    737                                         parsed_controls,
    738                                         NULL,
    739                                         ldb_op_default_callback,
    740                                         NULL);
    741 
     862        }
     863
     864        ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
     865                                NULL, ldb_op_default_callback, NULL);
    742866        if (ret != LDB_SUCCESS) {
    743867                PyErr_SetString(PyExc_TypeError, "failed to build request");
     
    746870        }
    747871
    748         /* do request and autostart a transaction */
     872        /* do request and autostart a transaction */
    749873        /* Then let's LDB handle the message error in case of pb as they are meaningful */
    750874
    751         ret = ldb_transaction_start(ldb_ctx);
    752         if (ret != LDB_SUCCESS) {
    753                 talloc_free(req);
     875        ret = ldb_transaction_start(ldb_ctx);
     876        if (ret != LDB_SUCCESS) {
    754877                talloc_free(mem_ctx);
    755                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
    756         }
    757 
    758         ret = ldb_request(ldb_ctx, req);
    759         if (ret == LDB_SUCCESS) {
    760                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
    761         }
    762 
     878                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     879        }
     880
     881        ret = ldb_request(ldb_ctx, req);
    763882        if (ret == LDB_SUCCESS) {
    764                 ret = ldb_transaction_commit(ldb_ctx);
    765         } else {
    766                 ldb_transaction_cancel(ldb_ctx);
     883                        ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     884        }
     885
     886        if (ret == LDB_SUCCESS) {
     887                ret = ldb_transaction_commit(ldb_ctx);
     888        } else {
     889                ldb_transaction_cancel(ldb_ctx);
    767890                if (ldb_ctx->err_string == NULL) {
    768891                        /* no error string was setup by the backend */
     
    770893                }
    771894        }
    772         talloc_free(req);
     895
    773896        talloc_free(mem_ctx);
    774         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
     897        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     898
     899        Py_RETURN_NONE;
     900}
     901
     902
     903/**
     904 * Obtain a ldb message from a Python Dictionary object.
     905 *
     906 * @param mem_ctx Memory context
     907 * @param py_obj Python Dictionary object
     908 * @param ldb_ctx LDB context
     909 * @param mod_flags Flags to be set on every message element
     910 * @return ldb_message on success or NULL on failure
     911 */
     912static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
     913                                            PyObject *py_obj,
     914                                            struct ldb_context *ldb_ctx,
     915                                            unsigned int mod_flags)
     916{
     917        struct ldb_message *msg;
     918        unsigned int msg_pos = 0;
     919        Py_ssize_t dict_pos = 0;
     920        PyObject *key, *value;
     921        struct ldb_message_element *msg_el;
     922        PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
     923
     924        msg = ldb_msg_new(mem_ctx);
     925        msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
     926
     927        if (dn_value) {
     928                if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
     929                        PyErr_SetString(PyExc_TypeError, "unable to import dn object");
     930                        return NULL;
     931                }
     932                if (msg->dn == NULL) {
     933                        PyErr_SetString(PyExc_TypeError, "dn set but not found");
     934                        return NULL;
     935                }
     936        } else {
     937                PyErr_SetString(PyExc_TypeError, "no dn set");
     938                return NULL;
     939        }
     940
     941        while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
     942                char *key_str = PyString_AsString(key);
     943                if (strcmp(key_str, "dn") != 0) {
     944                        msg_el = PyObject_AsMessageElement(msg->elements, value,
     945                                                           mod_flags, key_str);
     946                        if (msg_el == NULL) {
     947                                PyErr_SetString(PyExc_TypeError, "unable to import element");
     948                                return NULL;
     949                        }
     950                        memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
     951                        msg_pos++;
     952                }
     953        }
     954
     955        msg->num_elements = msg_pos;
     956
     957        return msg;
     958}
     959
     960static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
     961{
     962        PyObject *py_obj;
     963        int ret;
     964        struct ldb_context *ldb_ctx;
     965        struct ldb_request *req;
     966        struct ldb_message *msg = NULL;
     967        PyObject *py_controls = Py_None;
     968        TALLOC_CTX *mem_ctx;
     969        struct ldb_control **parsed_controls;
     970
     971        if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls ))
     972                return NULL;
     973
     974        mem_ctx = talloc_new(NULL);
     975        if (mem_ctx == NULL) {
     976                PyErr_NoMemory();
     977                return NULL;
     978        }
     979        ldb_ctx = PyLdb_AsLdbContext(self);
     980
     981        if (py_controls == Py_None) {
     982                parsed_controls = NULL;
     983        } else {
     984                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     985                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
     986                talloc_free(controls);
     987        }
     988
     989        if (PyLdbMessage_Check(py_obj)) {
     990                msg = PyLdbMessage_AsMessage(py_obj);
     991        } else if (PyDict_Check(py_obj)) {
     992                msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
     993        } else {
     994                PyErr_SetString(PyExc_TypeError,
     995                                "Dictionary or LdbMessage object expected!");
     996        }
     997
     998        if (!msg) {
     999                /* we should have a PyErr already set */
     1000                talloc_free(mem_ctx);
     1001                return NULL;
     1002        }
     1003
     1004        ret = ldb_msg_sanity_check(ldb_ctx, msg);
     1005        if (ret != LDB_SUCCESS) {
     1006                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1007                talloc_free(mem_ctx);
     1008                return NULL;
     1009        }
     1010
     1011        ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
     1012                                NULL, ldb_op_default_callback, NULL);
     1013        if (ret != LDB_SUCCESS) {
     1014                PyErr_SetString(PyExc_TypeError, "failed to build request");
     1015                talloc_free(mem_ctx);
     1016                return NULL;
     1017        }
     1018
     1019        /* do request and autostart a transaction */
     1020        /* Then let's LDB handle the message error in case of pb as they are meaningful */
     1021
     1022        ret = ldb_transaction_start(ldb_ctx);
     1023        if (ret != LDB_SUCCESS) {
     1024                talloc_free(mem_ctx);
     1025                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1026        }
     1027
     1028        ret = ldb_request(ldb_ctx, req);
     1029        if (ret == LDB_SUCCESS) {
     1030                        ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     1031        }
     1032
     1033        if (ret == LDB_SUCCESS) {
     1034                        ret = ldb_transaction_commit(ldb_ctx);
     1035        } else {
     1036                ldb_transaction_cancel(ldb_ctx);
     1037                if (ldb_ctx->err_string == NULL) {
     1038                        /* no error string was setup by the backend */
     1039                        ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
     1040                }
     1041        }
     1042
     1043        talloc_free(mem_ctx);
     1044        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    7751045
    7761046        Py_RETURN_NONE;
     
    7821052        struct ldb_dn *dn;
    7831053        int ret;
    784         struct ldb_context *ldb;
    785         if (!PyArg_ParseTuple(args, "O", &py_dn))
    786                 return NULL;
    787 
    788         ldb = PyLdb_AsLdbContext(self);
    789 
    790         if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
    791                 return NULL;
    792 
    793         ret = ldb_delete(ldb, dn);
    794         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
     1054        struct ldb_context *ldb_ctx;
     1055        struct ldb_request *req;
     1056        PyObject *py_controls = Py_None;
     1057        TALLOC_CTX *mem_ctx;
     1058        struct ldb_control **parsed_controls;
     1059
     1060        if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls))
     1061                return NULL;
     1062
     1063        mem_ctx = talloc_new(NULL);
     1064        if (mem_ctx == NULL) {
     1065                PyErr_NoMemory();
     1066                return NULL;
     1067        }
     1068        ldb_ctx = PyLdb_AsLdbContext(self);
     1069
     1070        if (py_controls == Py_None) {
     1071                parsed_controls = NULL;
     1072        } else {
     1073                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     1074                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
     1075                talloc_free(controls);
     1076        }
     1077
     1078        if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
     1079                talloc_free(mem_ctx);
     1080                return NULL;
     1081        }
     1082
     1083        ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
     1084                                NULL, ldb_op_default_callback, NULL);
     1085        if (ret != LDB_SUCCESS) {
     1086                PyErr_SetString(PyExc_TypeError, "failed to build request");
     1087                talloc_free(mem_ctx);
     1088                return NULL;
     1089        }
     1090
     1091        /* do request and autostart a transaction */
     1092        /* Then let's LDB handle the message error in case of pb as they are meaningful */
     1093
     1094        ret = ldb_transaction_start(ldb_ctx);
     1095        if (ret != LDB_SUCCESS) {
     1096                talloc_free(mem_ctx);
     1097                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1098        }
     1099
     1100        ret = ldb_request(ldb_ctx, req);
     1101        if (ret == LDB_SUCCESS) {
     1102                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     1103        }
     1104
     1105        if (ret == LDB_SUCCESS) {
     1106                ret = ldb_transaction_commit(ldb_ctx);
     1107        } else {
     1108                ldb_transaction_cancel(ldb_ctx);
     1109                if (ldb_ctx->err_string == NULL) {
     1110                        /* no error string was setup by the backend */
     1111                        ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
     1112                }
     1113        }
     1114
     1115        talloc_free(mem_ctx);
     1116        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    7951117
    7961118        Py_RETURN_NONE;
     
    8041126        struct ldb_context *ldb;
    8051127        TALLOC_CTX *mem_ctx;
    806         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
    807                 return NULL;
     1128        PyObject *py_controls = Py_None;
     1129        struct ldb_control **parsed_controls;
     1130        struct ldb_context *ldb_ctx;
     1131        struct ldb_request *req;
     1132
     1133        ldb_ctx = PyLdb_AsLdbContext(self);
     1134
     1135        if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls))
     1136                return NULL;
     1137
    8081138
    8091139        mem_ctx = talloc_new(NULL);
     
    8131143        }
    8141144        ldb = PyLdb_AsLdbContext(self);
     1145
     1146        if (py_controls == Py_None) {
     1147                parsed_controls = NULL;
     1148        } else {
     1149                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     1150                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
     1151                talloc_free(controls);
     1152        }
     1153
     1154
    8151155        if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
    8161156                talloc_free(mem_ctx);
     
    8231163        }
    8241164
    825         ret = ldb_rename(ldb, dn1, dn2);
     1165        ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
     1166                                NULL, ldb_op_default_callback, NULL);
     1167        if (ret != LDB_SUCCESS) {
     1168                PyErr_SetString(PyExc_TypeError, "failed to build request");
     1169                talloc_free(mem_ctx);
     1170                return NULL;
     1171        }
     1172
     1173        /* do request and autostart a transaction */
     1174        /* Then let's LDB handle the message error in case of pb as they are meaningful */
     1175
     1176        ret = ldb_transaction_start(ldb_ctx);
     1177        if (ret != LDB_SUCCESS) {
     1178                talloc_free(mem_ctx);
     1179                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1180        }
     1181
     1182        ret = ldb_request(ldb_ctx, req);
     1183        if (ret == LDB_SUCCESS) {
     1184                ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     1185        }
     1186
     1187        if (ret == LDB_SUCCESS) {
     1188                ret = ldb_transaction_commit(ldb_ctx);
     1189        } else {
     1190                ldb_transaction_cancel(ldb_ctx);
     1191                if (ldb_ctx->err_string == NULL) {
     1192                        /* no error string was setup by the backend */
     1193                        ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
     1194                }
     1195        }
     1196
    8261197        talloc_free(mem_ctx);
    827         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
     1198        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    8281199
    8291200        Py_RETURN_NONE;
     
    8691240
    8701241
    871 static PyObject *py_ldb_write_ldif(PyLdbMessageObject *self, PyObject *args)
     1242static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
    8721243{
    8731244        int changetype;
     
    9381309static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
    9391310{
     1311        int ldb_ret;
    9401312        PyObject *py_msg_old;
    9411313        PyObject *py_msg_new;
    9421314        struct ldb_message *diff;
     1315        struct ldb_context *ldb;
    9431316        PyObject *py_ret;
    9441317
     
    9561329        }
    9571330
    958         diff = ldb_msg_diff(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg_old), PyLdbMessage_AsMessage(py_msg_new));
    959         if (diff == NULL)
    960                 return NULL;
     1331        ldb = PyLdb_AsLdbContext(self);
     1332        ldb_ret = ldb_msg_difference(ldb, ldb,
     1333                                     PyLdbMessage_AsMessage(py_msg_old),
     1334                                     PyLdbMessage_AsMessage(py_msg_new),
     1335                                     &diff);
     1336        if (ldb_ret != LDB_SUCCESS) {
     1337                PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
     1338                return NULL;
     1339        }
    9611340
    9621341        py_ret = PyLdbMessage_FromMessage(diff);
     1342
     1343        talloc_unlink(ldb, diff);
    9631344
    9641345        return py_ret;
     
    10041385{
    10051386        PyObject *py_base = Py_None;
    1006         enum ldb_scope scope = LDB_SCOPE_DEFAULT;
     1387        int scope = LDB_SCOPE_DEFAULT;
    10071388        char *expr = NULL;
    10081389        PyObject *py_attrs = Py_None;
     
    10171398        struct ldb_dn *base;
    10181399        PyObject *py_ret;
    1019 
     1400        TALLOC_CTX *mem_ctx;
     1401
     1402        /* type "int" rather than "enum" for "scope" is intentional */
    10201403        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
    10211404                                         discard_const_p(char *, kwnames),
     
    10231406                return NULL;
    10241407
     1408
     1409        mem_ctx = talloc_new(NULL);
     1410        if (mem_ctx == NULL) {
     1411                PyErr_NoMemory();
     1412                return NULL;
     1413        }
    10251414        ldb_ctx = PyLdb_AsLdbContext(self);
    10261415
     
    10281417                attrs = NULL;
    10291418        } else {
    1030                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
    1031                 if (attrs == NULL)
     1419                attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
     1420                if (attrs == NULL) {
     1421                        talloc_free(mem_ctx);
    10321422                        return NULL;
     1423                }
    10331424        }
    10341425
     
    10451436                parsed_controls = NULL;
    10461437        } else {
    1047                 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
    1048                 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
     1438                const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
     1439                parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
    10491440                talloc_free(controls);
    10501441        }
    10511442
    1052         res = talloc_zero(ldb_ctx, struct ldb_result);
     1443        res = talloc_zero(mem_ctx, struct ldb_result);
    10531444        if (res == NULL) {
    10541445                PyErr_NoMemory();
    1055                 talloc_free(attrs);
    1056                 return NULL;
    1057         }
    1058 
    1059         ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
     1446                talloc_free(mem_ctx);
     1447                return NULL;
     1448        }
     1449
     1450        ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
    10601451                                   base,
    10611452                                   scope,
     
    10671458                                   NULL);
    10681459
     1460        if (ret != LDB_SUCCESS) {
     1461                talloc_free(mem_ctx);
     1462                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
     1463                return NULL;
     1464        }
     1465
    10691466        talloc_steal(req, attrs);
    1070 
    1071         if (ret != LDB_SUCCESS) {
    1072                 talloc_free(res);
    1073                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    1074                 return NULL;
    1075         }
    10761467
    10771468        ret = ldb_request(ldb_ctx, req);
     
    10811472        }
    10821473
    1083         talloc_free(req);
    1084 
    10851474        if (ret != LDB_SUCCESS) {
    1086                 talloc_free(res);
     1475                talloc_free(mem_ctx);
    10871476                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
    10881477                return NULL;
     
    10911480        py_ret = PyLdbResult_FromResult(res);
    10921481
    1093         talloc_free(res);
     1482        talloc_free(mem_ctx);
    10941483
    10951484        return py_ret;
     
    11421531}
    11431532
     1533static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
     1534{
     1535        struct ldb_context *ldb = PyLdb_AsLdbContext(self);
     1536        int type, ret;
     1537        uint64_t value;
     1538
     1539        if (!PyArg_ParseTuple(args, "i", &type))
     1540                return NULL;
     1541
     1542        /* FIXME: More interpretation */
     1543
     1544        ret = ldb_sequence_number(ldb, type, &value);
     1545
     1546        if (ret != LDB_SUCCESS) {
     1547                PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
     1548                return NULL;
     1549        }
     1550        return PyLong_FromLongLong(value);
     1551}
    11441552static PyMethodDef py_ldb_methods[] = {
    11451553        { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
     
    11561564                "S.transaction_start() -> None\n"
    11571565                "Start a new transaction." },
     1566        { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
     1567                "S.transaction_prepare_commit() -> None\n"
     1568                "prepare to commit a new transaction (2-stage commit)." },
    11581569        { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
    11591570                "S.transaction_commit() -> None\n"
     
    12251636                "S.modules() -> list\n"
    12261637                "Return the list of modules on this LDB connection " },
     1638        { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
     1639                "S.sequence_number(type) -> value\n"
     1640                "Return the value of the sequence according to the requested type" },
    12271641        { NULL },
    12281642};
    12291643
    1230 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
     1644static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
    12311645{
    12321646        PyLdbModuleObject *ret;
     
    12571671        struct ldb_dn *dn;
    12581672        struct ldb_result *result;
     1673        unsigned int count;
    12591674        int ret;
    1260         int count;
    1261 
    1262         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
     1675
     1676        if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
    12631677                return -1;
    1264 
    1265         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
     1678        }
     1679
     1680        ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
     1681                         NULL);
    12661682        if (ret != LDB_SUCCESS) {
    12671683                PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
     
    12731689        talloc_free(result);
    12741690
     1691        if (count > 1) {
     1692                PyErr_Format(PyExc_RuntimeError,
     1693                             "Searching for [%s] dn gave %u results!",
     1694                             ldb_dn_get_linearized(dn),
     1695                             count);
     1696                return -1;
     1697        }
     1698
    12751699        return count;
    12761700}
     
    12801704};
    12811705
    1282 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
     1706static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
    12831707{
    12841708        PyLdbObject *ret;
     
    13001724}
    13011725
    1302 PyTypeObject PyLdb = {
    1303         .tp_name = "Ldb",
     1726static PyTypeObject PyLdb = {
     1727        .tp_name = "ldb.Ldb",
    13041728        .tp_methods = py_ldb_methods,
    13051729        .tp_repr = (reprfunc)py_ldb_repr,
     
    13151739};
    13161740
     1741static void py_ldb_result_dealloc(PyLdbResultObject *self)
     1742{
     1743        talloc_free(self->mem_ctx);
     1744        Py_DECREF(self->msgs);
     1745        Py_DECREF(self->referals);
     1746        Py_DECREF(self->controls);
     1747        self->ob_type->tp_free(self);
     1748}
     1749
     1750static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
     1751{
     1752        Py_INCREF(self->msgs);
     1753        return self->msgs;
     1754}
     1755
     1756static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
     1757{
     1758        Py_INCREF(self->controls);
     1759        return self->controls;
     1760}
     1761
     1762static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
     1763{
     1764        Py_INCREF(self->referals);
     1765        return self->referals;
     1766}
     1767
     1768static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
     1769{
     1770        Py_ssize_t size;
     1771        if (self->msgs == NULL) {
     1772                PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
     1773                return NULL;
     1774        }
     1775        size = PyList_Size(self->msgs);
     1776        return PyInt_FromLong(size);
     1777}
     1778
     1779static PyGetSetDef py_ldb_result_getset[] = {
     1780        { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
     1781        { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
     1782        { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
     1783        { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
     1784        { NULL }
     1785};
     1786
     1787static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
     1788{
     1789        return PyObject_GetIter(self->msgs);
     1790}
     1791
     1792static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
     1793{
     1794        return PySequence_Size(self->msgs);
     1795}
     1796
     1797static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
     1798{
     1799        return PySequence_GetItem(self->msgs, idx);
     1800}
     1801
     1802static PySequenceMethods py_ldb_result_seq = {
     1803        .sq_length = (lenfunc)py_ldb_result_len,
     1804        .sq_item = (ssizeargfunc)py_ldb_result_find,
     1805};
     1806
     1807static PyObject *py_ldb_result_repr(PyLdbObject *self)
     1808{
     1809        return PyString_FromFormat("<ldb result>");
     1810}
     1811
     1812
     1813static PyTypeObject PyLdbResult = {
     1814        .tp_name = "ldb.Result",
     1815        .tp_repr = (reprfunc)py_ldb_result_repr,
     1816        .tp_dealloc = (destructor)py_ldb_result_dealloc,
     1817        .tp_iter = (getiterfunc)py_ldb_result_iter,
     1818        .tp_getset = py_ldb_result_getset,
     1819        .tp_getattro = PyObject_GenericGetAttr,
     1820        .tp_basicsize = sizeof(PyLdbResultObject),
     1821        .tp_as_sequence = &py_ldb_result_seq,
     1822        .tp_doc = "LDB result.",
     1823        .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
     1824};
     1825
    13171826static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
    13181827{
     
    13521861        const char * const*attrs;
    13531862
     1863        /* type "int" rather than "enum" for "scope" is intentional */
    13541864        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
    13551865                                         discard_const_p(char *, kwnames),
     
    14902000{
    14912001        talloc_free(self->mem_ctx);
    1492         self->ob_type->tp_free(self);
    1493 }
    1494 
    1495 PyTypeObject PyLdbModule = {
    1496         .tp_name = "LdbModule",
     2002        PyObject_Del(self);
     2003}
     2004
     2005static PyTypeObject PyLdbModule = {
     2006        .tp_name = "ldb.LdbModule",
    14972007        .tp_methods = py_ldb_module_methods,
    14982008        .tp_repr = (reprfunc)py_ldb_module_repr,
     
    15182028 * @return New ldb_message_element, allocated as child of mem_ctx
    15192029 */
    1520 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
    1521                                                                                            PyObject *set_obj, int flags,
    1522                                                                                            const char *attr_name)
     2030static struct ldb_message_element *PyObject_AsMessageElement(
     2031                                                      TALLOC_CTX *mem_ctx,
     2032                                                      PyObject *set_obj,
     2033                                                      int flags,
     2034                                                      const char *attr_name)
    15232035{
    15242036        struct ldb_message_element *me;
    15252037
    1526         if (PyLdbMessageElement_Check(set_obj))
    1527                 return talloc_reference(mem_ctx,
    1528                                                                 PyLdbMessageElement_AsMessageElement(set_obj));
     2038        if (PyLdbMessageElement_Check(set_obj)) {
     2039                PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
     2040                /* We have to talloc_reference() the memory context, not the pointer
     2041                 * which may not actually be it's own context */
     2042                if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
     2043                        return PyLdbMessageElement_AsMessageElement(set_obj);
     2044                }
     2045                return NULL;
     2046        }
    15292047
    15302048        me = talloc(mem_ctx, struct ldb_message_element);
     2049        if (me == NULL) {
     2050                PyErr_NoMemory();
     2051                return NULL;
     2052        }
    15312053
    15322054        me->name = talloc_strdup(me, attr_name);
     
    15372059                me->values[0].length = PyString_Size(set_obj);
    15382060                me->values[0].data = talloc_memdup(me,
    1539                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length);
     2061                        (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
    15402062        } else if (PySequence_Check(set_obj)) {
    1541                 int i;
     2063                Py_ssize_t i;
    15422064                me->num_values = PySequence_Size(set_obj);
    15432065                me->values = talloc_array(me, struct ldb_val, me->num_values);
    15442066                for (i = 0; i < me->num_values; i++) {
    15452067                        PyObject *obj = PySequence_GetItem(set_obj, i);
     2068                        if (!PyString_Check(obj)) {
     2069                                PyErr_Format(PyExc_TypeError,
     2070                                             "Expected string as element %zd in list", i);
     2071                                talloc_free(me);
     2072                                return NULL;
     2073                        }
    15462074
    15472075                        me->values[i].length = PyString_Size(obj);
    15482076                        me->values[i].data = talloc_memdup(me,
    1549                                 (uint8_t *)PyString_AsString(obj), me->values[i].length);
     2077                                (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
    15502078                }
    15512079        } else {
     
    15582086
    15592087
    1560 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
    1561                                                                  struct ldb_message_element *me)
    1562 {
    1563         int i;
     2088static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
     2089                                        struct ldb_message_element *me)
     2090{
     2091        Py_ssize_t i;
    15642092        PyObject *result;
    15652093
     
    15692097        for (i = 0; i < me->num_values; i++) {
    15702098                PyList_SetItem(result, i,
    1571                         PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
     2099                        PyObject_FromLdbValue(&me->values[i]));
    15722100        }
    15732101
     
    15772105static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
    15782106{
    1579         int i;
    1580         if (!PyArg_ParseTuple(args, "i", &i))
    1581                 return NULL;
    1582         if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
     2107        unsigned int i;
     2108        if (!PyArg_ParseTuple(args, "I", &i))
     2109                return NULL;
     2110        if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
    15832111                Py_RETURN_NONE;
    15842112
    1585         return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self),
    1586                                                                  &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
     2113        return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i]));
    15872114}
    15882115
    15892116static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
    15902117{
    1591         struct ldb_message_element *el;
    1592 
    1593         el = PyLdbMessageElement_AsMessageElement(self);
     2118        struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
    15942119        return PyInt_FromLong(el->flags);
    15952120}
     
    16362161static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
    16372162{
    1638         return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
    1639                                                                    PyLdbMessageElement_AsMessageElement(other));
     2163        int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
     2164                                                                          PyLdbMessageElement_AsMessageElement(other));
     2165        return SIGN(ret);
    16402166}
    16412167
     
    16452171}
    16462172
    1647 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
     2173static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
    16482174{
    16492175        PyLdbMessageElementObject *ret;
    1650         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
     2176        ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
    16512177        if (ret == NULL) {
    16522178                PyErr_NoMemory();
     
    16842210
    16852211        el = talloc_zero(mem_ctx, struct ldb_message_element);
     2212        if (el == NULL) {
     2213                PyErr_NoMemory();
     2214                talloc_free(mem_ctx);
     2215                return NULL;
     2216        }
    16862217
    16872218        if (py_elements != NULL) {
    1688                 int i;
     2219                Py_ssize_t i;
    16892220                if (PyString_Check(py_elements)) {
    16902221                        el->num_values = 1;
    16912222                        el->values = talloc_array(el, struct ldb_val, 1);
     2223                        if (el->values == NULL) {
     2224                                talloc_free(mem_ctx);
     2225                                PyErr_NoMemory();
     2226                                return NULL;
     2227                        }
    16922228                        el->values[0].length = PyString_Size(py_elements);
    1693                         el->values[0].data = talloc_memdup(el,
    1694                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length);
     2229                        el->values[0].data = talloc_memdup(el->values,
     2230                                (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
    16952231                } else if (PySequence_Check(py_elements)) {
    16962232                        el->num_values = PySequence_Size(py_elements);
    16972233                        el->values = talloc_array(el, struct ldb_val, el->num_values);
     2234                        if (el->values == NULL) {
     2235                                talloc_free(mem_ctx);
     2236                                PyErr_NoMemory();
     2237                                return NULL;
     2238                        }
    16982239                        for (i = 0; i < el->num_values; i++) {
    16992240                                PyObject *item = PySequence_GetItem(py_elements, i);
     2241                                if (item == NULL) {
     2242                                        talloc_free(mem_ctx);
     2243                                        return NULL;
     2244                                }
    17002245                                if (!PyString_Check(item)) {
    17012246                                        PyErr_Format(PyExc_TypeError,
    1702                                                         "Expected string as element %d in list",
    1703                                                         i);
     2247                                                     "Expected string as element %zd in list", i);
    17042248                                        talloc_free(mem_ctx);
    17052249                                        return NULL;
    17062250                                }
    17072251                                el->values[i].length = PyString_Size(item);
    1708                                 el->values[i].data = talloc_memdup(el, 
    1709                                         (uint8_t *)PyString_AsString(item), el->values[i].length);
     2252                                el->values[i].data = talloc_memdup(el,
     2253                                        (uint8_t *)PyString_AsString(item), el->values[i].length+1);
    17102254                        }
    17112255                } else {
     
    17202264        el->name = talloc_strdup(el, name);
    17212265
    1722         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
     2266        ret = PyObject_New(PyLdbMessageElementObject, type);
    17232267        if (ret == NULL) {
    1724                 PyErr_NoMemory();
    17252268                talloc_free(mem_ctx);
    17262269                return NULL;
     
    17352278{
    17362279        char *element_str = NULL;
    1737         int i;
     2280        Py_ssize_t i;
    17382281        struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
    17392282        PyObject *ret;
     
    17472290        }
    17482291
    1749         ret = PyString_FromFormat("MessageElement([%s])", element_str);
    1750 
    1751         talloc_free(element_str);
     2292        if (element_str != NULL) {
     2293                ret = PyString_FromFormat("MessageElement([%s])", element_str);
     2294                talloc_free(element_str);
     2295        } else {
     2296                ret = PyString_FromString("MessageElement([])");
     2297        }
    17522298
    17532299        return ret;
     
    17602306        if (el->num_values == 1)
    17612307                return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
    1762         else 
     2308        else
    17632309                Py_RETURN_NONE;
    17642310}
     
    17672313{
    17682314        talloc_free(self->mem_ctx);
    1769         self->ob_type->tp_free(self);
    1770 }
    1771 
    1772 PyTypeObject PyLdbMessageElement = {
    1773         .tp_name = "MessageElement",
     2315        PyObject_Del(self);
     2316}
     2317
     2318static PyTypeObject PyLdbMessageElement = {
     2319        .tp_name = "ldb.MessageElement",
    17742320        .tp_basicsize = sizeof(PyLdbMessageElementObject),
    17752321        .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
     
    17842330};
    17852331
     2332
     2333static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
     2334{
     2335        PyObject *py_ldb;
     2336        PyObject *py_dict;
     2337        PyObject *py_ret;
     2338        struct ldb_message *msg;
     2339        struct ldb_context *ldb_ctx;
     2340        unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
     2341
     2342        if (!PyArg_ParseTuple(args, "O!O!|I",
     2343                              &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
     2344                              &mod_flags)) {
     2345                return NULL;
     2346        }
     2347
     2348        /* mask only flags we are going to use */
     2349        mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
     2350        if (!mod_flags) {
     2351                PyErr_SetString(PyExc_ValueError,
     2352                                "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
     2353                                " expected as mod_flag value");
     2354                return NULL;
     2355        }
     2356
     2357        ldb_ctx = PyLdb_AsLdbContext(py_ldb);
     2358
     2359        msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
     2360        if (!msg) {
     2361                return NULL;
     2362        }
     2363
     2364        py_ret = PyLdbMessage_FromMessage(msg);
     2365
     2366        talloc_unlink(ldb_ctx, msg);
     2367
     2368        return py_ret;
     2369}
     2370
    17862371static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
    17872372{
     
    17982383{
    17992384        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
    1800         int i, j = 0;
     2385        Py_ssize_t i, j = 0;
    18012386        PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
    18022387        if (msg->dn != NULL) {
     
    18272412                return NULL;
    18282413        }
    1829         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
     2414        return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
    18302415}
    18312416
     
    18582443{
    18592444        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
    1860         int i, j;
     2445        Py_ssize_t i, j = 0;
    18612446        PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
    1862         j = 0;
    18632447        if (msg->dn != NULL) {
    18642448                PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
     
    18662450        }
    18672451        for (i = 0; i < msg->num_elements; i++, j++) {
    1868                 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
     2452                PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
     2453                PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
     2454                PyList_SetItem(l, j, value);
    18692455        }
    18702456        return l;
    18712457}
    18722458
    1873 static PyMethodDef py_ldb_msg_methods[] = {
    1874         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
    1875         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
     2459static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
     2460{
     2461        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
     2462        Py_ssize_t i = 0;
     2463        PyObject *l = PyList_New(msg->num_elements);
     2464        for (i = 0; i < msg->num_elements; i++) {
     2465                PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
     2466        }
     2467        return l;
     2468}
     2469
     2470static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
     2471{
     2472        struct ldb_message *msg = PyLdbMessage_AsMessage(self);
     2473        PyLdbMessageElementObject *py_element;
     2474        int ret;
     2475        struct ldb_message_element *el;
     2476
     2477        if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
     2478                return NULL;
     2479
     2480        el = talloc_reference(msg, py_element->el);
     2481        if (el == NULL) {
     2482                PyErr_NoMemory();
     2483                return NULL;
     2484        }
     2485
     2486        ret = ldb_msg_add(msg, el, el->flags);
     2487        PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
     2488
     2489        Py_RETURN_NONE;
     2490}
     2491
     2492static PyMethodDef py_ldb_msg_methods[] = {
     2493        { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
     2494                "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
     2495                "Class method to create ldb.Message object from Dictionary.\n"
     2496                "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
     2497        { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
     2498                "S.keys() -> list\n\n"
     2499                "Return sequence of all attribute names." },
     2500        { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
     2501                "S.remove(name)\n\n"
     2502                "Remove all entries for attributes with the specified name."},
    18762503        { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
    18772504        { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
     2505        { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
     2506        { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
     2507                "S.append(element)\n\n"
     2508                "Add an element to this message." },
    18782509        { NULL },
    18792510};
     
    18972528                return -1;
    18982529        }
    1899        
     2530
    19002531        attr_name = PyString_AsString(name);
    19012532        if (value == NULL) {
     
    19042535        } else {
    19052536                struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
    1906                                                                                         value, 0, attr_name);
     2537                                                                           value, 0, attr_name);
    19072538                if (el == NULL)
    19082539                        return -1;
     
    19712602}
    19722603
    1973 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
     2604static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
    19742605{
    19752606        PyLdbMessageObject *ret;
     
    20212652{
    20222653        talloc_free(self->mem_ctx);
    2023         self->ob_type->tp_free(self);
    2024 }
    2025 
    2026 PyTypeObject PyLdbMessage = {
    2027         .tp_name = "Message",
     2654        PyObject_Del(self);
     2655}
     2656
     2657static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
     2658                              PyLdbMessageObject *py_msg2)
     2659{
     2660        struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1),
     2661                           *msg2 = PyLdbMessage_AsMessage(py_msg2);
     2662        unsigned int i;
     2663        int ret;
     2664
     2665        if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
     2666                ret = ldb_dn_compare(msg1->dn, msg2->dn);
     2667                if (ret != 0) {
     2668                        return SIGN(ret);
     2669                }
     2670        }
     2671
     2672        ret = msg1->num_elements - msg2->num_elements;
     2673        if (ret != 0) {
     2674                return SIGN(ret);
     2675        }
     2676
     2677        for (i = 0; i < msg1->num_elements; i++) {
     2678                ret = ldb_msg_element_compare_name(&msg1->elements[i],
     2679                                                   &msg2->elements[i]);
     2680                if (ret != 0) {
     2681                        return SIGN(ret);
     2682                }
     2683
     2684                ret = ldb_msg_element_compare(&msg1->elements[i],
     2685                                              &msg2->elements[i]);
     2686                if (ret != 0) {
     2687                        return SIGN(ret);
     2688                }
     2689        }
     2690
     2691        return 0;
     2692}
     2693
     2694static PyTypeObject PyLdbMessage = {
     2695        .tp_name = "ldb.Message",
    20282696        .tp_methods = py_ldb_msg_methods,
    20292697        .tp_getset = py_ldb_msg_getset,
     
    20352703        .tp_flags = Py_TPFLAGS_DEFAULT,
    20362704        .tp_iter = (getiterfunc)py_ldb_msg_iter,
     2705        .tp_compare = (cmpfunc)py_ldb_msg_compare,
    20372706};
    20382707
    2039 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
     2708static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
    20402709{
    20412710        PyLdbTreeObject *ret;
     
    20552724{
    20562725        talloc_free(self->mem_ctx);
    2057         self->ob_type->tp_free(self);
    2058 }
    2059 
    2060 PyTypeObject PyLdbTree = {
    2061         .tp_name = "Tree",
     2726        PyObject_Del(self);
     2727}
     2728
     2729static PyTypeObject PyLdbTree = {
     2730        .tp_name = "ldb.Tree",
    20622731        .tp_basicsize = sizeof(PyLdbTreeObject),
    20632732        .tp_dealloc = (destructor)py_ldb_tree_dealloc,
     
    23673036static PyObject *py_timestring(PyObject *module, PyObject *args)
    23683037{
    2369         time_t t;
     3038        /* most times "time_t" is a signed integer type with 32 or 64 bit:
     3039         * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
     3040        long int t_val;
    23703041        char *tresult;
    23713042        PyObject *ret;
    2372         if (!PyArg_ParseTuple(args, "L", &t))
    2373                 return NULL;
    2374         tresult = ldb_timestring(NULL, t);
     3043        if (!PyArg_ParseTuple(args, "l", &t_val))
     3044                return NULL;
     3045        tresult = ldb_timestring(NULL, (time_t) t_val);
    23753046        ret = PyString_FromString(tresult);
    23763047        talloc_free(tresult);
     
    24353106                return;
    24363107
     3108        if (PyType_Ready(&PyLdbResult) < 0)
     3109                return;
     3110
     3111        if (PyType_Ready(&PyLdbControl) < 0)
     3112                return;
     3113
    24373114        m = Py_InitModule3("ldb", py_ldb_global_methods,
    24383115                "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
     
    24403117                return;
    24413118
     3119        PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
     3120        PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
     3121        PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
    24423122        PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
    24433123        PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
     
    24943174        PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
    24953175
    2496         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
    2497         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
    2498         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
    2499         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
    2500 
     3176        PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
     3177        PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
     3178        PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
     3179        PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
    25013180
    25023181        PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
     
    25113190        Py_INCREF(&PyLdbMessageElement);
    25123191        Py_INCREF(&PyLdbTree);
     3192        Py_INCREF(&PyLdbResult);
     3193        Py_INCREF(&PyLdbControl);
    25133194
    25143195        PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
     
    25183199        PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
    25193200        PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
    2520 }
     3201        PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
     3202
     3203        PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
     3204}
Note: See TracChangeset for help on using the changeset viewer.