From 722dc9eed3798db0d3795bdf70ce10e6d402705a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 20 Mar 2009 00:33:43 +0100 Subject: pyldb: Improve exception message when a list is expected. --- source4/lib/ldb/pyldb.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 81b960979f..7ff4bf4aad 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -469,19 +469,20 @@ static PyObject *py_ldb_get_default_basedn(PyLdbObject *self) return PyLdbDn_FromDn(dn); } -static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list) +static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, + const char *paramname) { const char **ret; int i; if (!PyList_Check(list)) { - PyErr_SetString(PyExc_TypeError, "options is not a list"); + PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); return NULL; } ret = talloc_array(NULL, const char *, PyList_Size(list)+1); for (i = 0; i < PyList_Size(list); i++) { PyObject *item = PyList_GetItem(list, i); if (!PyString_Check(item)) { - PyErr_SetString(PyExc_TypeError, "options should be strings"); + PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); return NULL; } ret[i] = PyString_AsString(item); @@ -510,7 +511,7 @@ static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) if (py_options == Py_None) { options = NULL; } else { - options = PyList_AsStringList(ldb, py_options); + options = PyList_AsStringList(ldb, py_options, "options"); if (options == NULL) return -1; } @@ -563,7 +564,7 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa if (py_options == Py_None) { options = NULL; } else { - options = PyList_AsStringList(NULL, py_options); + options = PyList_AsStringList(NULL, py_options, "options"); if (options == NULL) return NULL; } @@ -813,7 +814,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar if (py_attrs == Py_None) { attrs = NULL; } else { - attrs = PyList_AsStringList(ldb_ctx, py_attrs); + attrs = PyList_AsStringList(ldb_ctx, py_attrs, "attrs"); if (attrs == NULL) return NULL; } @@ -828,7 +829,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar if (py_controls == Py_None) { parsed_controls = NULL; } else { - const char **controls = PyList_AsStringList(ldb_ctx, py_controls); + const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls"); parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls); talloc_free(controls); } @@ -1129,7 +1130,7 @@ static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, P mod = self->mod; ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), - scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs), + scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs, "attrs"), NULL /* controls */, NULL, NULL, NULL); PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb); -- cgit From ec9aeeab00584f4d3dfe9afb83dc1a77b8463b81 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 20 Mar 2009 01:29:31 +0100 Subject: Fix up minschema after the conversion from JavaScript. Pair programmed over the phone with Andrew :-) --- source4/scripting/bin/minschema | 165 +++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 88 deletions(-) (limited to 'source4') diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index e7d7ed4979..f2dfdcb564 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -3,9 +3,10 @@ # work out the minimal schema for a set of objectclasses # +import base64 import optparse - -import os, sys +import os +import sys # Find right directory when running from source tree sys.path.insert(0, "bin/python") @@ -54,10 +55,10 @@ if len(args) != 2: lp_ctx = sambaopts.get_loadparm() creds = credopts.get_credentials(lp_ctx) -ldb = Ldb(url, credentials=creds) +ldb = Ldb(url, credentials=creds, lp=lp_ctx) -objectclasses = [] -attributes = [] +objectclasses = {} +attributes = {} objectclasses_expanded = set() @@ -136,24 +137,25 @@ attrib_attrs = ["objectClass", def get_object_cn(ldb, name): attrs = ["cn"] - - res = ldb.search("(ldapDisplayName=%s)" % name, rootDse["schemaNamingContext"], SCOPE_SUBTREE, attrs) + res = ldb.search(expression="(ldapDisplayName=%s)" % name, base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs) assert len(res) == 1 - return res[0]["cn"] -class Objectclass: + +class Objectclass(dict): + def __init__(self, ldb, name): """create an objectclass object""" self.name = name - self.cn = get_object_cn(ldb, name) + self["cn"] = get_object_cn(ldb, name) + +class Attribute(dict): -class Attribute: def __init__(self, ldb, name): """create an attribute object""" self.name = name - self.cn = get_object_cn(ldb, name) + self["cn"] = get_object_cn(ldb, name) syntaxmap = dict() @@ -180,36 +182,38 @@ syntaxmap['2.5.5.17'] = '1.3.6.1.4.1.1466.115.121.1.40' def map_attribute_syntax(s): """map some attribute syntaxes from some apparently MS specific syntaxes to the standard syntaxes""" - if syntaxmap.has_key(s): + if s in list(syntaxmap): return syntaxmap[s] return s def fix_dn(dn): """fix a string DN to use ${SCHEMADN}""" - return dn.replace(rootDse["schemaNamingContext"], "${SCHEMADN}") + return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}") def write_ldif_one(o, attrs): """dump an object as ldif""" - print "dn: CN=%s,${SCHEMADN}\n" % o["cn"] + print "dn: CN=%s,${SCHEMADN}" % o["cn"] for a in attrs: if not o.has_key(a): continue # special case for oMObjectClass, which is a binary object - if a == "oMObjectClass": - print "%s:: %s\n" % (a, o[a]) - continue v = o[a] - if isinstance(v, str): - v = [v] for j in v: - print "%s: %s\n" % (a, fix_dn(j)) - print "\n" + value = fix_dn(j) + if a == "oMObjectClass": + print "%s:: %s" % (a, base64.b64encode(value)) + elif a.endswith("GUID"): + print "%s: %s" % (a, ldb.schema_format_value(a, value)) + else: + print "%s: %s" % (a, value) + print "" + def write_ldif(o, attrs): """dump an array of objects as ldif""" - for i in o: + for n, i in o.items(): write_ldif_one(i, attrs) @@ -225,7 +229,7 @@ def find_objectclass_properties(ldb, o): """the properties of an objectclass""" res = ldb.search( expression="(ldapDisplayName=%s)" % o.name, - base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, attrs=class_attrs) + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=class_attrs) assert(len(res) == 1) msg = res[0] for a in msg: @@ -235,15 +239,11 @@ def find_attribute_properties(ldb, o): """find the properties of an attribute""" res = ldb.search( expression="(ldapDisplayName=%s)" % o.name, - base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrib_attrs) assert(len(res) == 1) msg = res[0] for a in msg: - # special case for oMObjectClass, which is a binary object - if a == "oMObjectClass": - o[a] = ldb.encode(msg[a]) - continue o[a] = msg[a] @@ -254,15 +254,15 @@ def find_objectclass_auto(ldb, o): return testdn = create_testdn(o.exampleDN) - print "testdn is '%s'\n" % testdn + print "testdn is '%s'" % testdn ldif = "dn: " + testdn ldif += "\nobjectClass: " + o.name try: ldb.add(ldif) except LdbError, e: - print "error adding %s: %s\n" % (o.name, e) - print "%s\n" % ldif + print "error adding %s: %s" % (o.name, e) + print "%s" % ldif return res = ldb.search(base=testdn, scope=ldb.SCOPE_BASE) @@ -280,20 +280,20 @@ def expand_objectclass(ldb, o): "subClassOf"] res = ldb.search( expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name, - base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, attrs=attrs) - print "Expanding class %s\n" % o.name + print >>sys.stderr, "Expanding class %s" % o.name assert(len(res) == 1) msg = res[0] - for a in attrs: - if not msg.has_key(aname): + for aname in attrs: + if not aname in msg: continue list = msg[aname] if isinstance(list, str): list = [msg[aname]] for name in list: if not objectclasses.has_key(name): - print "Found new objectclass '%s'\n" % name + print >>sys.stderr, "Found new objectclass '%s'" % name objectclasses[name] = Objectclass(ldb, name) @@ -320,13 +320,13 @@ def walk_dn(ldb, dn): try: res = ldb.search("objectClass=*", dn, SCOPE_BASE, attrs) except LdbError, e: - print "Unable to fetch allowedAttributes for '%s' - %r\n" % (dn, e) + print >>sys.stderr, "Unable to fetch allowedAttributes for '%s' - %r" % (dn, e) return allattrs = res[0]["allowedAttributes"] try: res = ldb.search("objectClass=*", dn, SCOPE_BASE, allattrs) except LdbError, e: - print "Unable to fetch all attributes for '%s' - %s\n" % (dn, e) + print >>sys.stderr, "Unable to fetch all attributes for '%s' - %s" % (dn, e) return msg = res[0] for a in msg: @@ -339,7 +339,7 @@ def walk_naming_context(ldb, namingContext): res = ldb.search("objectClass=*", namingContext, SCOPE_DEFAULT, ["objectClass"]) except LdbError, e: - print "Unable to fetch objectClasses for '%s' - %s\n" % (namingContext, e) + print >>sys.stderr, "Unable to fetch objectClasses for '%s' - %s" % (namingContext, e) return for msg in res: msg = res.msgs[r]["objectClass"] @@ -356,12 +356,9 @@ def trim_objectclass_attributes(ldb, objectclass): if objectclass.has_key("possibleInferiors"): possinf = objectclass["possibleInferiors"] newpossinf = [] - if isinstance(possinf, str): - possinf = [possinf] for x in possinf: if objectclasses.has_key(x): - newpossinf[n] = x - n+=1 + newpossinf.append(x) objectclass["possibleInferiors"] = newpossinf # trim systemMayContain, @@ -369,8 +366,6 @@ def trim_objectclass_attributes(ldb, objectclass): if objectclass.has_key("systemMayContain"): sysmay = objectclass["systemMayContain"] newsysmay = [] - if isinstance(sysmay, str): - sysmay = [sysmay] for x in sysmay: if not x in newsysmay: newsysmay.append(x) @@ -378,7 +373,7 @@ def trim_objectclass_attributes(ldb, objectclass): # trim mayContain, # remove duplicates - if not objectclass.has_key("mayContain"): + if objectclass.has_key("mayContain"): may = objectclass["mayContain"] newmay = [] if isinstance(may, str): @@ -388,30 +383,24 @@ def trim_objectclass_attributes(ldb, objectclass): newmay.append(x) objectclass["mayContain"] = newmay + def build_objectclass(ldb, name): """load the basic attributes of an objectClass""" attrs = ["name"] - try: - res = ldb.search( - expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name, - base=rootDse["schemaNamingContext"], scope=SCOPE_SUBTREE, - attrs=attrs) - except LdbError, e: - print "unknown class '%s'\n" % name - return None + res = ldb.search( + expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name, + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE, + attrs=attrs) if len(res) == 0: - print "unknown class '%s'\n" % name + print >>sys.stderr, "unknown class '%s'" % name return None return Objectclass(ldb, name) + def attribute_list(objectclass, attr1, attr2): """form a coalesced attribute list""" - a1 = objectclass[attr1] - a2 = objectclass[attr2] - if isinstance(a1, str): - a1 = [a1] - if isinstance(a2, str): - a2 = [a2] + a1 = list(objectclass.get(attr1, [])) + a2 = list(objectclass.get(attr2, [])) return a1 + a2 def aggregate_list(name, list): @@ -422,15 +411,15 @@ def aggregate_list(name, list): def write_aggregate_objectclass(objectclass): """write the aggregate record for an objectclass""" - print "objectClasses: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name) + print "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name), if not objectclass.has_key('subClassOf'): - print "SUP %s " % objectclass['subClassOf'] - if objectclass.objectClassCategory == 1: - print "STRUCTURAL " - elif objectclass.objectClassCategory == 2: - print "ABSTRACT " - elif objectclass.objectClassCategory == 3: - print "AUXILIARY " + print "SUP %s " % objectclass['subClassOf'], + if objectclass["objectClassCategory"] == 1: + print "STRUCTURAL ", + elif objectclass["objectClassCategory"] == 2: + print "ABSTRACT ", + elif objectclass["objectClassCategory"] == 3: + print "AUXILIARY ", list = attribute_list(objectclass, "systemMustContain", "mustContain") aggregate_list("MUST", list) @@ -438,7 +427,7 @@ def write_aggregate_objectclass(objectclass): list = attribute_list(objectclass, "systemMayContain", "mayContain") aggregate_list("MAY", list) - print ")\n" + print ")" def write_aggregate_ditcontentrule(objectclass): @@ -447,12 +436,12 @@ def write_aggregate_ditcontentrule(objectclass): if list is None: return - print "dITContentRules: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name) + print "dITContentRules: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name) aggregate_list("AUX", list) - may_list = None - must_list = None + may_list = [] + must_list = [] for c in list: list2 = attribute_list(objectclasses[c], @@ -470,11 +459,11 @@ def write_aggregate_ditcontentrule(objectclass): def write_aggregate_attribute(attrib): """write the aggregate record for an attribute""" print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % ( - attrib.attributeID, attrib.name, - map_attribute_syntax(attrib.attributeSyntax)) - if attrib['isSingleValued'] == "TRUE": + attrib["attributeID"], attrib.name, + map_attribute_syntax(attrib["attributeSyntax"])) + if attrib.get('isSingleValued') == "TRUE": print "SINGLE-VALUE " - if attrib['systemOnly'] == "TRUE": + if attrib.get('systemOnly') == "TRUE": print "NO-USER-MODIFICATION " print ")\n" @@ -490,16 +479,16 @@ objectCategory: CN=SubSchema,${SCHEMADN} if not opts.dump_subschema_auto: return - for objectclass in objectclasses: + for objectclass in objectclasses.values(): write_aggregate_objectclass(objectclass) - for attr in attributes: + for attr in attributes.values(): write_aggregate_attribute(attr) - for objectclass in objectclasses: + for objectclass in objectclasses.values(): write_aggregate_ditcontentrule(objectclass) def load_list(file): """load a list from a file""" - return open(file, 'r').readlines() + return [l.strip("\n") for l in open(file, 'r').readlines()] # get the rootDSE res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"]) @@ -523,32 +512,32 @@ expanded = 0 # than necessary to recursively expand all classes # for inf in range(500): - for n in objectclasses: + for n, o in objectclasses.items(): if not n in objectclasses_expanded: - expand_objectclass(ldb, objectclasses[i]) + expand_objectclass(ldb, o) objectclasses_expanded.add(n) # # find objectclass properties # -for objectclass in objectclasses: +for name, objectclass in objectclasses.items(): find_objectclass_properties(ldb, objectclass) # # form the full list of attributes # -for objectclass in objectclasses: +for name, objectclass in objectclasses.items(): add_objectclass_attributes(ldb, objectclass) # and attribute properties -for attr in attributes: +for name, attr in attributes.items(): find_attribute_properties(ldb, attr) # # trim the 'may' attribute lists to those really needed # -for objectclass in objectclasses: +for name, objectclass in objectclasses.items(): trim_objectclass_attributes(ldb, objectclass) # -- cgit From 1dc5b90e86fdee2978f5608f483c3b11c86fb9bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 16:26:42 +1100 Subject: s4:ldb Fix the paged_searches module This simplifies the code, removes presumptions about being the only control in the reply, and allows it to function against Windows 2008. For searches which did not require a paged result, the module was simply returning a failure when the compleated search did not include a paged result control. Andrew Bartlett --- source4/lib/ldb/modules/paged_searches.c | 109 +++++++++++++++---------------- 1 file changed, 51 insertions(+), 58 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c index 01e77cb22c..70b880e2dd 100644 --- a/source4/lib/ldb/modules/paged_searches.c +++ b/source4/lib/ldb/modules/paged_searches.c @@ -2,6 +2,7 @@ ldb database library Copyright (C) Simo Sorce 2005-2008 + Copyright (C) Andrew Bartlett 2009 ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -52,23 +53,40 @@ struct ps_context { char **saved_referrals; int num_referrals; + + struct ldb_request *down_req; }; -static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares) +static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) { - struct ps_context *ac; - struct ldb_paged_control *rep_control, *req_control; + struct ldb_context *ldb; + struct ldb_control *rep_control, *req_control; + struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; + ldb = ldb_module_get_ctx(ac->module); - ac = talloc_get_type(req->context, struct ps_context); + rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); + if (rep_control) { + paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); + } - /* look up our paged control */ - if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; + req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); + paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); + + if (!rep_control || !paged_rep_control) { + if (paged_req_control->cookie) { + /* something wrong here - why give us a control back befre, but not one now? */ + ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); + return LDB_ERR_OPERATIONS_ERROR; + } else { + /* No cookie recived yet, valid to just return the full data set */ + + /* we are done */ + ac->pending = false; + return LDB_SUCCESS; + } } - rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) { + if (paged_rep_control->cookie_len == 0) { /* we are done */ ac->pending = false; return LDB_SUCCESS; @@ -79,21 +97,14 @@ static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares /* if there's a reply control we must find a request * control matching it */ - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; - } - - req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control); - - if (req_control->cookie) { - talloc_free(req_control->cookie); + if (paged_req_control->cookie) { + talloc_free(paged_req_control->cookie); } - req_control->cookie = talloc_memdup(req_control, - rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; + paged_req_control->cookie = talloc_memdup(req_control, + paged_rep_control->cookie, + paged_rep_control->cookie_len); + paged_req_control->cookie_len = paged_rep_control->cookie_len; ac->pending = true; return LDB_SUCCESS; @@ -141,8 +152,6 @@ static int send_referrals(struct ps_context *ac) return LDB_SUCCESS; } -static int ps_next_request(struct ps_context *ac); - static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ps_context *ac; @@ -176,14 +185,15 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) case LDB_REPLY_DONE: - ret = check_ps_continuation(req, ares); + ret = check_ps_continuation(ac, req, ares); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } if (ac->pending) { - ret = ps_next_request(ac); + ret = ldb_next_request(ac->module, ac->down_req); + if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); @@ -214,6 +224,8 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req) struct ldb_context *ldb; struct private_data *private_data; struct ps_context *ac; + struct ldb_paged_control *control; + int ret; private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); ldb = ldb_module_get_ctx(module); @@ -238,30 +250,9 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req) ac->saved_referrals = NULL; ac->num_referrals = 0; - return ps_next_request(ac); -} - -static int ps_next_request(struct ps_context *ac) { - - struct ldb_context *ldb; - struct ldb_paged_control *control; - struct ldb_control **controls; - struct ldb_request *new_req; - int ret; - ldb = ldb_module_get_ctx(ac->module); - controls = talloc_array(ac, struct ldb_control *, 2); - if (!controls) { - return LDB_ERR_OPERATIONS_ERROR; - } - - controls[0] = talloc(controls, struct ldb_control); - if (!controls[0]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - control = talloc(controls[0], struct ldb_paged_control); + control = talloc(ac, struct ldb_paged_control); if (!control) { return LDB_ERR_OPERATIONS_ERROR; } @@ -270,26 +261,28 @@ static int ps_next_request(struct ps_context *ac) { control->cookie = NULL; control->cookie_len = 0; - controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID; - controls[0]->critical = 1; - controls[0]->data = control; - controls[1] = NULL; - - ret = ldb_build_search_req_ex(&new_req, ldb, ac, + ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, ac->req->op.search.base, ac->req->op.search.scope, ac->req->op.search.tree, ac->req->op.search.attrs, - controls, + ac->req->controls, ac, ps_callback, ac->req); if (ret != LDB_SUCCESS) { return ret; } - talloc_steal(new_req, controls); - return ldb_next_request(ac->module, new_req); + ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, + true, control); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(ac->down_req, control); + + return ldb_next_request(ac->module, ac->down_req); } static int check_supported_paged(struct ldb_request *req, -- cgit From 6906c01cac226db508cd56a31b751eee3ac62bc9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 16:25:01 +1100 Subject: s4:ldb Ensure to pass down options to LDB from python This is needed for things such as to load modules, like the paged_searches module. Andrew Bartlett --- source4/scripting/python/samba/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index a49e6e1ead..c5827b96e0 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -54,7 +54,7 @@ class Ldb(ldb.Ldb): functions see samdb.py. """ def __init__(self, url=None, session_info=None, credentials=None, - modules_dir=None, lp=None): + modules_dir=None, lp=None, options=None): """Open a Samba Ldb file. :param url: Optional LDB URL to open @@ -67,7 +67,7 @@ class Ldb(ldb.Ldb): modules-dir is used by default and that credentials and session_info can be passed through (required by some modules). """ - super(Ldb, self).__init__() + super(Ldb, self).__init__(options=options) if modules_dir is not None: self.set_modules_dir(modules_dir) @@ -90,7 +90,7 @@ class Ldb(ldb.Ldb): #self.set_debug(msg) if url is not None: - self.connect(url) + self.connect(url, options=options) def set_credentials(self, credentials): glue.ldb_set_credentials(self, credentials) -- cgit From 5bfed623f5115a774f47e1cdceed862c53cd40a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 13:55:43 +1100 Subject: s4:minschma Fix aggregate schema generation in minschema The conversion from EJS to python I did with Jelmer this morning was not quite complete, due mostly to the difference between print in EJS and python (python implies a newline). Andrew Bartlett --- source4/scripting/bin/minschema | 47 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'source4') diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index f2dfdcb564..4983502ba7 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -405,40 +405,40 @@ def attribute_list(objectclass, attr1, attr2): def aggregate_list(name, list): """write out a list in aggregate form""" - if list is None: - return - print "%s ( %s )" % (name, "$ ".join(list)) + if list == []: + return "" + return " %s ( %s )" % (name, " $ ".join(list)) def write_aggregate_objectclass(objectclass): """write the aggregate record for an objectclass""" - print "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name), + line = "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name) if not objectclass.has_key('subClassOf'): - print "SUP %s " % objectclass['subClassOf'], + line += "SUP %s" % objectclass['subClassOf'] if objectclass["objectClassCategory"] == 1: - print "STRUCTURAL ", + line += "STRUCTURAL" elif objectclass["objectClassCategory"] == 2: - print "ABSTRACT ", + line += "ABSTRACT" elif objectclass["objectClassCategory"] == 3: - print "AUXILIARY ", + line += "AUXILIARY" list = attribute_list(objectclass, "systemMustContain", "mustContain") - aggregate_list("MUST", list) + line += aggregate_list("MUST", list) list = attribute_list(objectclass, "systemMayContain", "mayContain") - aggregate_list("MAY", list) + line += aggregate_list("MAY", list) - print ")" + print line + " )" def write_aggregate_ditcontentrule(objectclass): """write the aggregate record for an ditcontentrule""" list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass") - if list is None: + if list == []: return - print "dITContentRules: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name) + line = "dITContentRules: ( %s NAME '%s'" % (objectclass["governsID"], objectclass.name) - aggregate_list("AUX", list) + line += aggregate_list("AUX", list) may_list = [] must_list = [] @@ -451,31 +451,30 @@ def write_aggregate_ditcontentrule(objectclass): "mustContain", "systemMustContain") must_list = must_list + list2 - aggregate_list("MUST", must_list) - aggregate_list("MAY", may_list) + line += aggregate_list("MUST", must_list) + line += aggregate_list("MAY", may_list) - print ")\n" + print line + " )" def write_aggregate_attribute(attrib): """write the aggregate record for an attribute""" - print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % ( + line = "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % ( attrib["attributeID"], attrib.name, map_attribute_syntax(attrib["attributeSyntax"])) if attrib.get('isSingleValued') == "TRUE": - print "SINGLE-VALUE " + line += "SINGLE-VALUE " if attrib.get('systemOnly') == "TRUE": - print "NO-USER-MODIFICATION " + line += "NO-USER-MODIFICATION " - print ")\n" + print line + ")" def write_aggregate(): """write the aggregate record""" - print "dn: CN=Aggregate,${SCHEMADN}\n" + print "dn: CN=Aggregate,${SCHEMADN}" print """objectClass: top objectClass: subSchema -objectCategory: CN=SubSchema,${SCHEMADN} -""" +objectCategory: CN=SubSchema,${SCHEMADN}""" if not opts.dump_subschema_auto: return -- cgit From 653dd024a630af095277f5884add9246da399eb9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 16:07:49 +1100 Subject: Add minschema like tool to extract and dump the full schema from AD --- source4/scripting/bin/fullschema | 191 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 source4/scripting/bin/fullschema (limited to 'source4') diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema new file mode 100644 index 0000000000..02e90f6973 --- /dev/null +++ b/source4/scripting/bin/fullschema @@ -0,0 +1,191 @@ +#!/usr/bin/python +# +# work out the minimal schema for a set of objectclasses +# + +import base64 +import optparse +import os +import sys + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + +import samba +from samba import getopt as options, Ldb +from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError +import sys + +parser = optparse.OptionParser("fullschema ") +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) +parser.add_option_group(options.VersionOptions(parser)) +parser.add_option("--verbose", help="Be verbose", action="store_true") +parser.add_option("--dump-classes", action="store_true") +parser.add_option("--dump-attributes", action="store_true") + +opts, args = parser.parse_args() +opts.dump_all = True + +if opts.dump_classes: + opts.dump_all = False +if opts.dump_attributes: + opts.dump_all = False +if opts.dump_all: + opts.dump_classes = True + opts.dump_attributes = True + +if len(args) != 1: + parser.print_usage() + sys.exit(1) + +url = args[0] + +lp_ctx = sambaopts.get_loadparm() + +creds = credopts.get_credentials(lp_ctx) +ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"]) + +objectclasses = {} +attributes = {} + +# the attributes we need for objectclasses +class_attrs = ["objectClass", + "cn", + "subClassOf", + "governsID", + "possSuperiors", + "possibleInferiors", + "mayContain", + "mustContain", + "auxiliaryClass", + "rDNAttID", + "showInAdvancedViewOnly", + "adminDisplayName", + "adminDescription", + "objectClassCategory", + "lDAPDisplayName", + "schemaIDGUID", + "systemOnly", + "systemPossSuperiors", + "systemMayContain", + "systemMustContain", + "systemAuxiliaryClass", + "defaultSecurityDescriptor", + "systemFlags", + "defaultHidingValue", + "defaultObjectCategory", + + # this attributes are not used by w2k3 + "schemaFlagsEx", + "msDs-IntId", + "msDs-Schema-Extensions", + "classDisplayName", + "isDefunct"] + +attrib_attrs = ["objectClass", + "cn", + "attributeID", + "attributeSyntax", + "isSingleValued", + "rangeLower", + "rangeUpper", + "mAPIID", + "linkID", + "showInAdvancedViewOnly", + "adminDisplayName", + "oMObjectClass", + "adminDescription", + "oMSyntax", + "searchFlags", + "extendedCharsAllowed", + "lDAPDisplayName", + "schemaIDGUID", + "attributeSecurityGUID", + "systemOnly", + "systemFlags", + "isMemberOfPartialAttributeSet", + + # this attributes are not used by w2k3 + "schemaFlagsEx", + "msDs-IntId", + "msDs-Schema-Extensions", + "classDisplayName", + "isEphemeral", + "isDefunct"] + +# +# notes: +# +# objectClassCategory +# 1: structural +# 2: abstract +# 3: auxiliary + +class Objectclass(dict): + + def __init__(self, ldb, name): + """create an objectclass object""" + self.name = name + + +class Attribute(dict): + + def __init__(self, ldb, name): + """create an attribute object""" + self.name = name + self["cn"] = get_object_cn(ldb, name) + + + +def fix_dn(dn): + """fix a string DN to use ${SCHEMADN}""" + return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}") + + +def write_ldif_one(o, attrs): + """dump an object as ldif""" + print "dn: CN=%s,${SCHEMADN}" % o["cn"] + for a in attrs: + if not o.has_key(a): + continue + # special case for oMObjectClass, which is a binary object + v = o[a] + for j in v: + value = fix_dn(j) + if a != "cn": + if a == "oMObjectClass": + print "%s:: %s" % (a, base64.b64encode(value)) + elif a.endswith("GUID"): + print "%s: %s" % (a, ldb.schema_format_value(a, value)) + else: + print "%s: %s" % (a, value) + print "" + + +# get the rootDSE +res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"]) +rootDse = res[0] + +if opts.dump_attributes: + res = ldb.search(expression="objectClass=attributeSchema", + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs) + + for msg in res: + o = Objectclass(ldb, msg["ldapDisplayName"]) + for a in msg: + o[a] = msg[a] + write_ldif_one(o, attrib_attrs) + +if opts.dump_classes: + res = ldb.search(expression="objectClass=classSchema", + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs) + + for msg in res: + o = Objectclass(ldb, msg["ldapDisplayName"]) + for a in msg: + o[a] = msg[a] + write_ldif_one(o, class_attrs) + -- cgit From f696bb81f8499443eee9815e7adf8dbb6810506a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 16:18:40 +1100 Subject: s4: Remove autogenerated attributes from minschema and fullschema output These attributes will be generated by Samba on import, and do not need to be in the schema file. Andrew Bartlett --- source4/scripting/bin/fullschema | 14 -------------- source4/scripting/bin/minschema | 2 -- 2 files changed, 16 deletions(-) (limited to 'source4') diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema index 02e90f6973..d3bf398e65 100644 --- a/source4/scripting/bin/fullschema +++ b/source4/scripting/bin/fullschema @@ -22,7 +22,6 @@ parser.add_option_group(sambaopts) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) parser.add_option_group(options.VersionOptions(parser)) -parser.add_option("--verbose", help="Be verbose", action="store_true") parser.add_option("--dump-classes", action="store_true") parser.add_option("--dump-attributes", action="store_true") @@ -48,9 +47,6 @@ lp_ctx = sambaopts.get_loadparm() creds = credopts.get_credentials(lp_ctx) ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"]) -objectclasses = {} -attributes = {} - # the attributes we need for objectclasses class_attrs = ["objectClass", "cn", @@ -62,7 +58,6 @@ class_attrs = ["objectClass", "mustContain", "auxiliaryClass", "rDNAttID", - "showInAdvancedViewOnly", "adminDisplayName", "adminDescription", "objectClassCategory", @@ -94,7 +89,6 @@ attrib_attrs = ["objectClass", "rangeUpper", "mAPIID", "linkID", - "showInAdvancedViewOnly", "adminDisplayName", "oMObjectClass", "adminDescription", @@ -116,14 +110,6 @@ attrib_attrs = ["objectClass", "isEphemeral", "isDefunct"] -# -# notes: -# -# objectClassCategory -# 1: structural -# 2: abstract -# 3: auxiliary - class Objectclass(dict): def __init__(self, ldb, name): diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index 4983502ba7..c860495e96 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -72,7 +72,6 @@ class_attrs = ["objectClass", "mustContain", "auxiliaryClass", "rDNAttID", - "showInAdvancedViewOnly", "adminDisplayName", "adminDescription", "objectClassCategory", @@ -104,7 +103,6 @@ attrib_attrs = ["objectClass", "rangeUpper", "mAPIID", "linkID", - "showInAdvancedViewOnly", "adminDisplayName", "oMObjectClass", "adminDescription", -- cgit From 4a45b0da5743f76f77c812d03ee625af10fb2a54 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 16:45:52 +1100 Subject: s4:ldb Allow paged_searches to be mixed with other controls I want to mix this with the server-side sort in particular. Andrew Bartlett --- source4/lib/ldb/modules/paged_searches.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c index 70b880e2dd..c5430eb9bf 100644 --- a/source4/lib/ldb/modules/paged_searches.c +++ b/source4/lib/ldb/modules/paged_searches.c @@ -230,10 +230,10 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req) private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); ldb = ldb_module_get_ctx(module); - /* check if paging is supported and if there is a any control */ - if (!private_data || !private_data->paged_supported || req->controls) { + /* check if paging is supported */ + if (!private_data || !private_data->paged_supported) { /* do not touch this request paged controls not - * supported or explicit controls have been set or we + * supported or we * are just not setup yet */ return ldb_next_request(module, req); } -- cgit From 37f130fd89d02e77bf55cbd8da731d87bb4ab1e8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 20 Mar 2009 16:47:34 +1100 Subject: s4:fullschema Use server-side sort to make the output deterministic --- source4/scripting/bin/fullschema | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema index d3bf398e65..41c45f30c8 100644 --- a/source4/scripting/bin/fullschema +++ b/source4/scripting/bin/fullschema @@ -157,7 +157,8 @@ rootDse = res[0] if opts.dump_attributes: res = ldb.search(expression="objectClass=attributeSchema", - base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs) + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs, + controls=["server_sort:1:0:cn"]) for msg in res: o = Objectclass(ldb, msg["ldapDisplayName"]) @@ -167,7 +168,8 @@ if opts.dump_attributes: if opts.dump_classes: res = ldb.search(expression="objectClass=classSchema", - base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs) + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs, + controls=["server_sort:1:0:cn"]) for msg in res: o = Objectclass(ldb, msg["ldapDisplayName"]) -- cgit From da46c371006d7cb5bceba790070d805b303ade98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Mar 2009 10:14:35 +0100 Subject: s4:build: include ../libcli/cldap/config.mk This fixes commit 84a140f18722518eb0f40737085dd3b3958a3a02, sorry! metze --- source4/main.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4') diff --git a/source4/main.mk b/source4/main.mk index a143604f33..d7db0580e9 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -46,6 +46,7 @@ mkinclude torture/config.mk mkinclude librpc/config.mk mkinclude client/config.mk mkinclude libcli/config.mk +mkinclude ../libcli/cldap/config.mk mkinclude scripting/python/config.mk mkinclude kdc/config.mk mkinclude ../lib/smbconf/config.mk -- cgit From 2de464a7658f91d2d01087080b984d52c3483426 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnoefer Date: Fri, 20 Mar 2009 16:22:02 +0100 Subject: Fix uninstallman. Signed-off-by: Jelmer Vernooij --- source4/script/uninstallman.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/script/uninstallman.sh b/source4/script/uninstallman.sh index 9b087c68bb..edc1c47e4d 100755 --- a/source4/script/uninstallman.sh +++ b/source4/script/uninstallman.sh @@ -8,7 +8,7 @@ MANPAGES=$* for I in $MANPAGES do - SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/" + SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"` FNAME=$MANDIR/man$SECTION/$I if test -f $FNAME; then echo Deleting $FNAME -- cgit From ee577ef0eef2d666504d1b78bb102b5c2e070b03 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 20 Mar 2009 22:52:57 +0100 Subject: Add more comments. --- source4/lib/ldb/pyldb.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 7ff4bf4aad..c552d68635 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -5,7 +5,7 @@ Copyright (C) 2005,2006 Tim Potter Copyright (C) 2006 Simo Sorce - Copyright (C) 2007-2008 Jelmer Vernooij + Copyright (C) 2007-2009 Jelmer Vernooij ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -84,6 +84,14 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, return ret; } +/** + * Obtain a ldb DN from a Python object. + * + * @param mem_ctx Memory context + * @param object Python object + * @param ldb_ctx LDB context + * @return Whether or not the conversion succeeded + */ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn) { @@ -104,6 +112,12 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, return false; } +/** + * Create a Python object from a ldb_result. + * + * @param result LDB result to convert + * @return Python object with converted result (a list object) + */ static PyObject *PyLdbResult_FromResult(struct ldb_result *result) { PyObject *ret; @@ -119,7 +133,16 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result) return ret; } -static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, PyObject *obj) +/** + * Create a LDB Result from a Python object. + * If conversion fails, NULL will be returned and a Python exception set. + * + * @param mem_ctx Memory context in which to allocate the LDB Result + * @param obj Python object to convert + * @return a ldb_result, or NULL if the conversion failed + */ +static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, + PyObject *obj) { struct ldb_result *res; int i; @@ -451,7 +474,6 @@ static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self) return PyLdbDn_FromDn(dn); } - static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) { struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self)); @@ -460,7 +482,6 @@ static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) return PyLdbDn_FromDn(dn); } - static PyObject *py_ldb_get_default_basedn(PyLdbObject *self) { struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self)); @@ -652,8 +673,6 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) Py_RETURN_NONE; } - - static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args) { PyObject *py_dn; -- cgit From 4fff36f618420dea2e004f87ae5a2699eabd140a Mon Sep 17 00:00:00 2001 From: zahari Date: Fri, 20 Mar 2009 12:03:29 +0200 Subject: Setting nTSecurityDescriptor via LDAP fails Fix for the problem was substitute talloc_strndup() with talloc_memdup(), allocate 1 more character and put null character ('\0') in the extra place so data copied is null terminated. Signed-off-by: Jelmer Vernooij --- source4/lib/ldb/pyldb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index c552d68635..b91f9b797f 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -1293,9 +1293,11 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, me->num_values = 1; me->values = talloc_array(me, struct ldb_val, me->num_values); me->values[0].length = PyString_Size(set_obj); - me->values[0].data = (uint8_t *)talloc_strndup(me->values, + me->values[0].data = (uint8_t *)talloc_memdup(me->values, PyString_AsString(set_obj), - me->values[0].length); + me->values[0].length + 1); + me->values[0].data[me->values[0].length] = '\0'; + } else if (PySequence_Check(set_obj)) { int i; me->num_values = PySequence_Size(set_obj); -- cgit From 8f4e4d2e3039997106f9da3dcd5b057d99802ecf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 20 Mar 2009 22:58:15 +0100 Subject: Adapt Zahari's test to the generic LDB Python tests. --- source4/lib/ldb/tests/python/api.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source4') diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index c372b8fa71..07500e2372 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -258,6 +258,19 @@ class SimpleLdb(unittest.TestCase): l = ldb.Ldb(filename()) l.set_debug(my_report_fn) + def test_zero_byte_string(self): + """Testing we do not get trapped in the \0 byte in a property string.""" + l = ldb.Ldb(filename()) + l.add({ + "dn" : "dc=somedn", + "objectclass" : "user", + "cN" : "LDAPtestUSER", + "givenname" : "ldap", + "displayname" : "foo\0bar", + }) + res = l.search(expression="(dn=dc=somedn)") + self.assertEquals("foo\0bar", res[0]["displayname"][0]) + class DnTests(unittest.TestCase): def setUp(self): -- cgit From de1e3e2cf0c666a51b062ed5395906892beb53c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Mar 2009 01:00:18 +0100 Subject: Remove unnecessary duplication of string in memory. --- source4/lib/ldb/pyldb.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index b91f9b797f..3e3aa97240 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -1276,6 +1276,21 @@ PyTypeObject PyLdbModule = { .tp_flags = Py_TPFLAGS_DEFAULT, }; + +/** + * Create a ldb_message_element from a Python object. + * + * This will accept any sequence objects that contains strings, or + * a string object. + * + * A reference to set_obj will be borrowed. + * + * @param mem_ctx Memory context + * @param set_obj Python object to convert + * @param flags ldb_message_element flags to set + * @param attr_name Name of the attribute + * @return New ldb_message_element, allocated as child of mem_ctx + */ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, PyObject *set_obj, int flags, const char *attr_name) @@ -1293,11 +1308,7 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, me->num_values = 1; me->values = talloc_array(me, struct ldb_val, me->num_values); me->values[0].length = PyString_Size(set_obj); - me->values[0].data = (uint8_t *)talloc_memdup(me->values, - PyString_AsString(set_obj), - me->values[0].length + 1); - me->values[0].data[me->values[0].length] = '\0'; - + me->values[0].data = (uint8_t *)PyString_AsString(set_obj); } else if (PySequence_Check(set_obj)) { int i; me->num_values = PySequence_Size(set_obj); -- cgit From 960b75531530c05fcaaa7400e52f2b688a6e8d88 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Mar 2009 02:19:25 +0100 Subject: pyldb: Let conversion to LDIF up to the user of the API rather than doing it implicitly. --- source4/lib/ldb/pyldb.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 3e3aa97240..bceda05e4f 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -65,18 +65,7 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, PyObject *ret; new_val = *val; - - if (ldb_ctx != NULL) { - a = ldb_schema_attribute_by_name(ldb_ctx, el->name); - - if (a != NULL) { - if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) { - talloc_free(mem_ctx); - return NULL; - } - } - } - + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); talloc_free(mem_ctx); -- cgit From 62ab39dde37f5570b336b9db5b4e3c2e4640e877 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnoefer Date: Sat, 21 Mar 2009 03:07:00 +0100 Subject: s4/provision: Use existing serverrole variable. Signed-off-by: Jelmer Vernooij --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d96857661e..896f237bd7 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1056,7 +1056,7 @@ def provision(setup_dir, message, session_info, serverrole=serverrole, ldap_backend=ldap_backend, ldap_backend_type=ldap_backend_type) - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": if paths.netlogon is None: message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.") message("Please either remove %s or see the template at %s" % -- cgit From 6ef1442360a35284e4aaaa98eea701fc2eab43c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Mar 2009 15:13:39 +0100 Subject: s4:smbd: the name of the binary is "samba" now metze --- source4/smbd/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/smbd/server.c b/source4/smbd/server.c index d576782ab1..635e84fafe 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -365,5 +365,5 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ int main(int argc, const char *argv[]) { - return binary_smbd_main("smbd", argc, argv); + return binary_smbd_main("samba", argc, argv); } -- cgit From 593ab6ac00c217f6d661b4babface40a0b0dd4ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Mar 2009 16:11:14 +0100 Subject: s4:selftest: rename SMBD_VALGRIND => SAMBA_VALGRIND metze --- source4/selftest/config.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4') diff --git a/source4/selftest/config.mk b/source4/selftest/config.mk index 324532c22a..1838a0bb38 100644 --- a/source4/selftest/config.mk +++ b/source4/selftest/config.mk @@ -59,31 +59,31 @@ test-%:: valgrindtest:: valgrindtest-all valgrindtest-quick:: all - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ $(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) valgrindtest-all:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) valgrindtest-env:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv gdbtest:: gdbtest-all gdbtest-quick:: all - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) gdbtest-all:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) gdbtest-env:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv -- cgit From 8a6f91c910c5f26eef10e959ae8a36a02099cad0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 22 Mar 2009 12:19:56 +0100 Subject: LDAP-CLDAP: remove temporary debug statements... metze --- source4/torture/ldap/cldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c index 98669288a8..814c9ac86d 100644 --- a/source4/torture/ldap/cldap.c +++ b/source4/torture/ldap/cldap.c @@ -59,8 +59,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(search); - search.in.dest_address = NULL;//dest; - search.in.dest_port = 0;//lp_cldap_port(tctx->lp_ctx); + search.in.dest_address = NULL; + search.in.dest_port = 0; search.in.acct_control = -1; search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; search.in.map_response = true; -- cgit