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(-) 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(-) 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(-) 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(-) 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(-) 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 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(-) 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(-) 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(-) 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 808928c24ba409a3fad50cbadf1db5a9dac9ad91 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Wed, 4 Mar 2009 18:10:20 +0800 Subject: Fix crash in async_smb.c --- source3/libsmb/async_smb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index e579d1c9f0..066ac7bdb8 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -861,7 +861,7 @@ static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) static void handle_incoming_pdu(struct cli_state *cli) { - struct cli_request *req; + struct cli_request *req, *next; uint16_t mid; size_t raw_pdu_len, buf_len, pdu_len, rest_len; char *pdu; @@ -978,8 +978,11 @@ static void handle_incoming_pdu(struct cli_state *cli) DEBUG(10, ("handle_incoming_pdu: Aborting with %s\n", nt_errstr(status))); - for (req = cli->outstanding_requests; req; req = req->next) { - async_req_nterror(req->async[0], status); + for (req = cli->outstanding_requests; req; req = next) { + next = req->next; + if (req->num_async) { + async_req_nterror(req->async[0], status); + } } return; } -- 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(+) 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 842edcd2b08763a35dbdea3518fcc039aa70aad4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 27 Nov 2008 17:49:25 +0100 Subject: s3-samr: try to to fix password_expired flag handling. Guenther --- source3/include/proto.h | 6 ++ source3/rpc_server/srv_samr_nt.c | 120 ++++++++++++++++++++++--------------- source3/rpc_server/srv_samr_util.c | 87 ++++++++++++++++++++++++++- 3 files changed, 161 insertions(+), 52 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 3d87f75c7b..d8154482be 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5898,6 +5898,8 @@ NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread, /* The following definitions come from rpc_server/srv_samr_util.c */ +void copy_id18_to_sam_passwd(struct samu *to, + struct samr_UserInfo18 *from); void copy_id20_to_sam_passwd(struct samu *to, struct samr_UserInfo20 *from); void copy_id21_to_sam_passwd(const char *log_prefix, @@ -5905,8 +5907,12 @@ void copy_id21_to_sam_passwd(const char *log_prefix, struct samr_UserInfo21 *from); void copy_id23_to_sam_passwd(struct samu *to, struct samr_UserInfo23 *from); +void copy_id24_to_sam_passwd(struct samu *to, + struct samr_UserInfo24 *from); void copy_id25_to_sam_passwd(struct samu *to, struct samr_UserInfo25 *from); +void copy_id26_to_sam_passwd(struct samu *to, + struct samr_UserInfo26 *from); /* The following definitions come from rpc_server/srv_spoolss_nt.c */ diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index dcbd0963c4..c60d904b18 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3636,12 +3636,7 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18, pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); } - if (id18->password_expired) { - pdb_set_pass_last_set_time(pwd, 0, PDB_CHANGED); - } else { - /* FIXME */ - pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); - } + copy_id18_to_sam_passwd(pwd, id18); return pdb_update_sam_account(pwd); } @@ -3848,23 +3843,16 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, set_user_info_pw ********************************************************************/ -static bool set_user_info_pw(uint8 *pass, struct samu *pwd, - int level) +static bool set_user_info_pw(uint8 *pass, struct samu *pwd) { uint32 len = 0; char *plaintext_buf = NULL; uint32 acct_ctrl; - time_t last_set_time; - enum pdb_value_state last_set_state; DEBUG(5, ("Attempting administrator password change for user %s\n", pdb_get_username(pwd))); acct_ctrl = pdb_get_acct_ctrl(pwd); - /* we need to know if it's expired, because this is an admin change, not a - user change, so it's still expired when we're done */ - last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET); - last_set_time = pdb_get_pass_last_set_time(pwd); if (!decode_pw_buffer(talloc_tos(), pass, @@ -3907,29 +3895,38 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd, memset(plaintext_buf, '\0', strlen(plaintext_buf)); - /* - * A level 25 change does reset the pwdlastset field, a level 24 - * change does not. I know this is probably not the full story, but - * it is needed to make XP join LDAP correctly, without it the later - * auth2 check can fail with PWD_MUST_CHANGE. - */ - if (level != 25) { - /* - * restore last set time as this is an admin change, not a - * user pw change - */ - pdb_set_pass_last_set_time (pwd, last_set_time, - last_set_state); + DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n")); + + return True; +} + +/******************************************************************* + set_user_info_24 + ********************************************************************/ + +static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx, + struct samr_UserInfo24 *id24, + struct samu *pwd) +{ + NTSTATUS status; + + if (id24 == NULL) { + DEBUG(5, ("set_user_info_24: NULL id24\n")); + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n")); + if (!set_user_info_pw(id24->password.data, pwd)) { + return NT_STATUS_WRONG_PASSWORD; + } - /* update the SAMBA password */ - if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { - return False; + copy_id24_to_sam_passwd(pwd, id24); + + status = pdb_update_sam_account(pwd); + if (!NT_STATUS_IS_OK(status)) { + return status; } - return True; + return NT_STATUS_OK; } /******************************************************************* @@ -3955,6 +3952,14 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, return NT_STATUS_ACCESS_DENIED; } + if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) || + (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) { + + if (!set_user_info_pw(id25->password.data, pwd)) { + return NT_STATUS_WRONG_PASSWORD; + } + } + copy_id25_to_sam_passwd(pwd, id25); /* write the change out */ @@ -3980,6 +3985,36 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/******************************************************************* + set_user_info_26 + ********************************************************************/ + +static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx, + struct samr_UserInfo26 *id26, + struct samu *pwd) +{ + NTSTATUS status; + + if (id26 == NULL) { + DEBUG(5, ("set_user_info_26: NULL id26\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (!set_user_info_pw(id26->password.data, pwd)) { + return NT_STATUS_WRONG_PASSWORD; + } + + copy_id26_to_sam_passwd(pwd, id26); + + status = pdb_update_sam_account(pwd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + + /******************************************************************* samr_SetUserInfo ********************************************************************/ @@ -4139,10 +4174,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, dump_data(100, info->info24.password.data, 516); - if (!set_user_info_pw(info->info24.password.data, pwd, - switch_value)) { - status = NT_STATUS_WRONG_PASSWORD; - } + status = set_user_info_24(p->mem_ctx, + &info->info24, pwd); break; case 25: @@ -4157,13 +4190,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, status = set_user_info_25(p->mem_ctx, &info->info25, pwd); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - if (!set_user_info_pw(info->info25.password.data, pwd, - switch_value)) { - status = NT_STATUS_WRONG_PASSWORD; - } break; case 26: @@ -4176,18 +4202,14 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, dump_data(100, info->info26.password.data, 516); - if (!set_user_info_pw(info->info26.password.data, pwd, - switch_value)) { - status = NT_STATUS_WRONG_PASSWORD; - } + status = set_user_info_26(p->mem_ctx, + &info->info26, pwd); break; default: status = NT_STATUS_INVALID_INFO_CLASS; } - done: - TALLOC_FREE(pwd); if (has_enough_rights) { diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index ef588aed1a..068156054f 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -35,6 +35,27 @@ (!(s1) && (s2)) ||\ ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) +/************************************************************* + Copies a struct samr_UserInfo18 to a struct samu +**************************************************************/ + +void copy_id18_to_sam_passwd(struct samu *to, + struct samr_UserInfo18 *from) +{ + struct samr_UserInfo21 i; + + if (from == NULL || to == NULL) { + return; + } + + ZERO_STRUCT(i); + + i.fields_present = SAMR_FIELD_EXPIRED_FLAG; + i.password_expired = from->password_expired; + + copy_id21_to_sam_passwd("INFO_18", to, &i); +} + /************************************************************* Copies a struct samr_UserInfo20 to a struct samu **************************************************************/ @@ -336,7 +357,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix, if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) { DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l, from->password_expired)); - if (from->password_expired == PASS_MUST_CHANGE_AT_NEXT_LOGON) { + if (from->password_expired != 0) { pdb_set_pass_last_set_time(to, 0, PDB_CHANGED); } else { /* A subtlety here: some windows commands will @@ -345,9 +366,27 @@ void copy_id21_to_sam_passwd(const char *log_prefix, in these caess. "net user /dom /active:y" for example, to clear an autolocked acct. We must check to see if it's expired first. jmcd */ + + uint32_t pwd_max_age = 0; + time_t now = time(NULL); + + pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age); + + if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) { + pwd_max_age = get_time_t_max(); + } + stored_time = pdb_get_pass_last_set_time(to); - if (stored_time == 0) - pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED); + + /* we will only *set* a pwdlastset date when + a) the last pwdlastset time was 0 (user was forced to + change password). + b) the users password has not expired. gd. */ + + if ((stored_time == 0) || + ((now - stored_time) > pwd_max_age)) { + pdb_set_pass_last_set_time(to, now, PDB_CHANGED); + } } } } @@ -367,6 +406,27 @@ void copy_id23_to_sam_passwd(struct samu *to, copy_id21_to_sam_passwd("INFO 23", to, &from->info); } +/************************************************************* + Copies a struct samr_UserInfo24 to a struct samu +**************************************************************/ + +void copy_id24_to_sam_passwd(struct samu *to, + struct samr_UserInfo24 *from) +{ + struct samr_UserInfo21 i; + + if (from == NULL || to == NULL) { + return; + } + + ZERO_STRUCT(i); + + i.fields_present = SAMR_FIELD_EXPIRED_FLAG; + i.password_expired = from->password_expired; + + copy_id21_to_sam_passwd("INFO_24", to, &i); +} + /************************************************************* Copies a struct samr_UserInfo25 to a struct samu **************************************************************/ @@ -380,3 +440,24 @@ void copy_id25_to_sam_passwd(struct samu *to, copy_id21_to_sam_passwd("INFO_25", to, &from->info); } + +/************************************************************* + Copies a struct samr_UserInfo26 to a struct samu +**************************************************************/ + +void copy_id26_to_sam_passwd(struct samu *to, + struct samr_UserInfo26 *from) +{ + struct samr_UserInfo21 i; + + if (from == NULL || to == NULL) { + return; + } + + ZERO_STRUCT(i); + + i.fields_present = SAMR_FIELD_EXPIRED_FLAG; + i.password_expired = from->password_expired; + + copy_id21_to_sam_passwd("INFO_26", to, &i); +} -- cgit From 2c186be0df33664eea980c17720be41f25f91288 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Mar 2009 16:18:29 +0100 Subject: s3-net: Fix Coverity #886 (FORWARD_NULL). Guenther --- source3/utils/net_rpc_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index b25c897770..81dfbaa5b6 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -1902,7 +1902,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, } - if (strlen(drivername) == 0) { + if (!drivername || strlen(drivername) == 0) { DEBUGADD(1,("Did not get driver for printer %s\n", printername)); goto done; -- cgit From 1524abd8bf12d82e1fb0063585fc9a465fc7bf9c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Mar 2009 16:42:54 +0100 Subject: s3-krb5: Fix Coverity #722 (RESOURCE_LEAK). Guenther --- source3/libsmb/clikrb5.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 168ca63303..4ab31374e2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -878,24 +878,30 @@ failed: bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote) { - krb5_keyblock *skey; - krb5_error_code err; - bool ret = False; + krb5_keyblock *skey = NULL; + krb5_error_code err = 0; + bool ret = false; - if (remote) + if (remote) { err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); - else + } else { err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); - if (err == 0 && skey != NULL) { - DEBUG(10, ("Got KRB5 session key of length %d\n", (int)KRB5_KEY_LENGTH(skey))); - *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + } - ret = True; + if (err || skey == NULL) { + DEBUG(10, ("KRB5 error getting session key %d\n", err)); + goto done; + } + DEBUG(10, ("Got KRB5 session key of length %d\n", (int)KRB5_KEY_LENGTH(skey))); + *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + ret = true; + + done: + if (skey) { krb5_free_keyblock(context, skey); - } else { - DEBUG(10, ("KRB5 error getting session key %d\n", err)); } return ret; -- cgit From 045151b767c62ac1343e86cb3886107226e73fda Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Mar 2009 12:53:01 +0100 Subject: s3-spoolss: pure comsetics. sorry, I just need to do that. Guenther --- source3/include/proto.h | 5 +- source3/rpc_server/srv_spoolss_nt.c | 259 ++++++++++++++++++------------------ source3/rpcclient/cmd_spoolss.c | 32 ++--- source3/utils/net_rpc_printer.c | 82 ++++++------ 4 files changed, 188 insertions(+), 190 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d8154482be..9bffa4d319 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5931,8 +5931,9 @@ void reset_all_printerdata(struct messaging_context *msg, bool convert_devicemode(const char *printername, const struct spoolss_DeviceMode *devmode, NT_DEVICEMODE **pp_nt_devmode); -WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, - uint32 type, uint8 *data, int real_len ); +WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer, + const char *key, const char *value, + uint32_t type, uint8_t *data, int real_len); void spoolss_notify_server_name(int snum, struct spoolss_Notify *data, print_queue_struct *queue, diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index ab15e5c5f6..b66f48aa29 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -66,13 +66,13 @@ typedef struct _counter_printer_0 { struct _counter_printer_0 *prev; int snum; - uint32 counter; + uint32_t counter; } counter_printer_0; static counter_printer_0 *counter_list; static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/ -static uint32 smb_connections=0; +static uint32_t smb_connections = 0; /* in printing/nt_printing.c */ @@ -186,7 +186,7 @@ static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle /* Tell the connections db we're no longer interested in * printer notify messages. */ - register_message_flags( False, FLAG_MSG_PRINT_NOTIFY ); + register_message_flags(false, FLAG_MSG_PRINT_NOTIFY); } smb_connections--; @@ -198,7 +198,7 @@ static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle static int printer_entry_destructor(Printer_entry *Printer) { - if (Printer->notify.client_connected==True) { + if (Printer->notify.client_connected == true) { int snum = -1; if ( Printer->printer_type == SPLHND_SERVER) { @@ -217,7 +217,7 @@ static int printer_entry_destructor(Printer_entry *Printer) Printer->notify.localmachine[0]='\0'; Printer->notify.printerlocal=0; TALLOC_FREE(Printer->notify.option); - Printer->notify.client_connected=False; + Printer->notify.client_connected = false; free_nt_devicemode( &Printer->nt_devmode ); free_a_printer( &Printer->printer_info, 2 ); @@ -255,12 +255,12 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd) if (!Printer) { DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); - return False; + return false; } close_policy_hnd(p, hnd); - return True; + return true; } /**************************************************************************** @@ -273,7 +273,7 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh char *command = NULL; int ret; SE_PRIV se_printop = SE_PRINT_OPERATOR; - bool is_print_op = False; + bool is_print_op = false; /* can't fail if we don't try */ @@ -315,7 +315,7 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh return WERR_BADFID; /* What to return here? */ /* go ahead and re-read the services immediately */ - reload_services( False ); + reload_services(false); if ( lp_servicenumber( sharename ) < 0 ) return WERR_ACCESS_DENIED; @@ -373,7 +373,7 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, if (!Printer) { DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); - return False; + return false; } switch (Printer->printer_type) { @@ -382,9 +382,9 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, *number = print_queue_snum(Printer->sharename); return (*number != -1); case SPLHND_SERVER: - return False; + return false; default: - return False; + return false; } } @@ -399,7 +399,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename if ( strlen(handlename) < 3 ) { DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename)); - return False; + return false; } /* it's a print server */ @@ -413,7 +413,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename Printer->printer_type = SPLHND_PRINTER; } - return True; + return true; } /**************************************************************************** @@ -430,7 +430,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) char *aprinter, *printername; const char *servername; fstring sname; - bool found=False; + bool found = false; NT_PRINTER_INFO_LEVEL *printer = NULL; WERROR result; @@ -450,15 +450,15 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) /* save the servername to fill in replies on this handle */ if ( !is_myname_or_ipaddr( servername ) ) - return False; + return false; fstrcpy( Printer->servername, servername ); if ( Printer->printer_type == SPLHND_SERVER ) - return True; + return true; if ( Printer->printer_type != SPLHND_PRINTER ) - return False; + return false; DEBUGADD(5, ("searching for [%s]\n", aprinter )); @@ -467,12 +467,12 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) { Printer->printer_type = SPLHND_PORTMON_TCP; fstrcpy(sname, SPL_XCV_MONITOR_TCPMON); - found = True; + found = true; } else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) { Printer->printer_type = SPLHND_PORTMON_LOCAL; fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON); - found = True; + found = true; } /* Search all sharenames first as this is easier than pulling @@ -490,7 +490,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) fstrcpy(sname, lp_servicename(snum)); if ( strequal( aprinter, sname ) ) { - found = True; + found = true; break; } @@ -528,7 +528,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( strequal(printername, aprinter) ) { free_a_printer( &printer, 2); - found = True; + found = true; break; } @@ -541,14 +541,14 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( !found ) { DEBUGADD(4,("Printer not found\n")); - return False; + return false; } DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); fstrcpy(Printer->sharename, sname); - return True; + return true; } /**************************************************************************** @@ -570,7 +570,7 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, if (!create_policy_hnd(p, hnd, new_printer)) { TALLOC_FREE(new_printer); - return False; + return false; } /* Add to the internal list. */ @@ -580,19 +580,19 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, if (!set_printer_hnd_printertype(new_printer, name)) { close_printer_handle(p, hnd); - return False; + return false; } if (!set_printer_hnd_name(new_printer, name)) { close_printer_handle(p, hnd); - return False; + return false; } new_printer->access_granted = access_granted; DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count )); - return True; + return true; } /*************************************************************************** @@ -600,17 +600,17 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, given by (notify_type, notify_field). **************************************************************************/ -static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type, - uint16 notify_field) +static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type, + uint16_t notify_field) { - return True; + return true; } -static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, - uint16 notify_field) +static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type, + uint16_t notify_field) { struct spoolss_NotifyOption *option = p->notify.option; - uint32 i, j; + uint32_t i, j; /* * Flags should always be zero when the change notify @@ -620,7 +620,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, */ if (!option) { - return False; + return false; } if (p->notify.flags) @@ -638,7 +638,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, for (j = 0; j < option->types[i].count; j++) { if (option->types[i].fields[j].field == notify_field) { - return True; + return true; } } } @@ -646,7 +646,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n", p->servername, p->sharename, notify_type, notify_field)); - return False; + return false; } #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \ @@ -849,7 +849,7 @@ static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr ) /*********************************************************************** **********************************************************************/ -static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) +static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx ) { if ( !ctr || !ctr->msg_groups ) return NULL; @@ -940,7 +940,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS back registered **********************************************************************/ -static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) +static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx ) { Printer_entry *p; TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr ); @@ -1113,23 +1113,23 @@ done: static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len ) { - uint32 tv_sec, tv_usec; + uint32_t tv_sec, tv_usec; size_t offset = 0; /* Unpack message */ - offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f", + offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f", msg->printer); - offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd", + offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd", &tv_sec, &tv_usec, &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags); if (msg->len == 0) - tdb_unpack((uint8 *)buf + offset, len - offset, "dd", + tdb_unpack((uint8_t *)buf + offset, len - offset, "dd", &msg->notify.value[0], &msg->notify.value[1]); else - tdb_unpack((uint8 *)buf + offset, len - offset, "B", + tdb_unpack((uint8_t *)buf + offset, len - offset, "B", &msg->len, &msg->notify.data); DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n", @@ -1142,9 +1142,9 @@ static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0], msg->notify.value[1])); else - dump_data(3, (uint8 *)msg->notify.data, msg->len); + dump_data(3, (uint8_t *)msg->notify.data, msg->len); - return True; + return true; } /******************************************************************** @@ -1233,7 +1233,8 @@ static void receive_notify2_message_list(struct messaging_context *msg, /* cleanup */ - DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count )); + DEBUG(10,("receive_notify2_message_list: processed %u messages\n", + (uint32_t)msg_count )); notify_msg_ctr_destroy( &messages ); @@ -1251,16 +1252,16 @@ static bool srv_spoolss_drv_upgrade_printer(char* drivername) int len = strlen(drivername); if (!len) - return False; + return false; DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n", drivername)); messaging_send_buf(smbd_messaging_context(), procid_self(), MSG_PRINTER_DRVUPGRADE, - (uint8 *)drivername, len+1); + (uint8_t *)drivername, len+1); - return True; + return true; } /********************************************************************** @@ -1328,7 +1329,7 @@ void update_monitored_printq_cache( void ) int snum; /* loop through all printers and update the cache where - client_connected == True */ + client_connected == true */ while ( printer ) { if ( (printer->printer_type == SPLHND_PRINTER) @@ -1354,16 +1355,16 @@ static bool srv_spoolss_reset_printerdata(char* drivername) int len = strlen(drivername); if (!len) - return False; + return false; DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n", drivername)); messaging_send_buf(smbd_messaging_context(), procid_self(), MSG_PRINTERDATA_INIT_RESET, - (uint8 *)drivername, len+1); + (uint8_t *)drivername, len+1); - return True; + return true; } /********************************************************************** @@ -1527,7 +1528,7 @@ bool convert_devicemode(const char *printername, if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) { SAFE_FREE(nt_devmode->nt_dev_private); nt_devmode->driverextra = devmode->__driverextra_length; - if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) + if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL) return false; memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra); } @@ -2017,7 +2018,7 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, if (!get_printer_snum(p, handle, &snum, NULL)) return WERR_BADFID; - Printer->document_started=False; + Printer->document_started = false; print_job_end(snum, Printer->jobid,NORMAL_CLOSE); /* error codes unhandled so far ... */ @@ -2064,7 +2065,7 @@ WERROR _spoolss_DeletePrinter(pipes_struct *p, result = delete_printer_handle(p, r->in.handle); - update_c_setprinter(False); + update_c_setprinter(false); return result; } @@ -2170,7 +2171,7 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, /* remove the Win2k driver first*/ status_win2k = delete_printer_driver( - p, info_win2k.info_3, 3, False ); + p, info_win2k.info_3, 3, false); free_a_printer_driver( info_win2k, 3 ); /* this should not have failed---if it did, report to client */ @@ -2182,7 +2183,7 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, } } - status = delete_printer_driver(p, info.info_3, version, False); + status = delete_printer_driver(p, info.info_3, version, false); /* if at least one of the deletes succeeded return OK */ @@ -2207,7 +2208,6 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; - uint32_t flags = r->in.delete_flags; bool delete_files; WERROR status; WERROR status_win2k = WERR_ACCESS_DENIED; @@ -2234,7 +2234,7 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, return WERR_INVALID_ENVIRONMENT; } - if ( flags & DPD_DELETE_SPECIFIC_VERSION ) + if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) version = r->in.version; ZERO_STRUCT(info); @@ -2250,7 +2250,7 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, * then we've failed */ - if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) + if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) goto done; /* try for Win2k driver if "Windows NT x86" */ @@ -2279,11 +2279,11 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, * Refer to MSDN docs on DeletePrinterDriverEx() for details. */ - delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); + delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ - if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { + if ( delete_files && printer_driver_files_in_use(info.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) { /* no idea of the correct error here */ status = WERR_ACCESS_DENIED; goto done; @@ -2292,11 +2292,11 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, /* also check for W32X86/3 if necessary; maybe we already have? */ - if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { + if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) { - if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { + if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) { /* no idea of the correct error here */ free_a_printer_driver( info_win2k, 3 ); status = WERR_ACCESS_DENIED; @@ -2341,8 +2341,9 @@ static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char Internal routine for storing printerdata ***************************************************************************/ -WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, - uint32 type, uint8 *data, int real_len ) +WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer, + const char *key, const char *value, + uint32_t type, uint8_t *data, int real_len) { /* the registry objects enforce uniqueness based on value name */ @@ -2409,10 +2410,10 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx, } /* REG_BINARY - * uint32 size = 0x114 - * uint32 major = 5 - * uint32 minor = [0|1] - * uint32 build = [2195|2600] + * uint32_t size = 0x114 + * uint32_t major = 5 + * uint32_t minor = [0|1] + * uint32_t build = [2195|2600] * extra unicode string = e.g. "Service Pack 3" */ if (!StrCaseCmp(value, "OSVersion")) { @@ -2596,12 +2597,12 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, if ( is_zero_addr((struct sockaddr *)client_ss) ) { if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) { DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine)); - return False; + return false; } if (ismyaddr((struct sockaddr *)&rm_addr)) { DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); - return False; + return false; } } else { char addr[INET6_ADDRSTRLEN]; @@ -2623,13 +2624,13 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, if ( !NT_STATUS_IS_OK( ret ) ) { DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n", remote_machine )); - return False; + return false; } if ( the_cli->protocol != PROTOCOL_NT1 ) { DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine)); cli_shutdown(the_cli); - return False; + return false; } /* @@ -2642,10 +2643,10 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n", remote_machine, nt_errstr(ret))); cli_shutdown(the_cli); - return False; + return false; } - return True; + return true; } /*************************************************************************** @@ -2653,7 +2654,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, ****************************************************************************/ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, - uint32 localprinter, uint32 type, + uint32_t localprinter, uint32_t type, struct policy_handle *handle, struct sockaddr_storage *client_ss) { @@ -2670,14 +2671,14 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */ if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer )) - return False; + return false; messaging_register(smbd_messaging_context(), NULL, MSG_PRINTER_NOTIFY2, receive_notify2_message_list); /* Tell the connections db we're now interested in printer * notify messages. */ - register_message_flags( True, FLAG_MSG_PRINT_NOTIFY ); + register_message_flags(true, FLAG_MSG_PRINT_NOTIFY); } /* @@ -2811,7 +2812,7 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, &Printer->notify.client_hnd, &client_ss)) return WERR_SERVER_UNAVAILABLE; - Printer->notify.client_connected=True; + Printer->notify.client_connected = true; return WERR_OK; } @@ -3296,7 +3297,7 @@ struct s_notify_info_data_table /* A table describing the various print notification constants and whether the notification data is a pointer to a variable sized - buffer, a one value uint32 or a two value uint32. */ + buffer, a one value uint32_t or a two value uint32_t. */ static const struct s_notify_info_data_table notify_info_data_table[] = { @@ -3386,11 +3387,11 @@ static bool search_notify(enum spoolss_NotifyType type, notify_info_data_table[i].field == field && notify_info_data_table[i].fn != NULL) { *value = i; - return True; + return true; } } - return False; + return false; } /**************************************************************************** @@ -3435,7 +3436,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, option_type->count, lp_servicename(snum))); if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum)))) - return False; + return false; for(field_num=0; field_num < option_type->count; field_num++) { field = option_type->fields[field_num].field; @@ -3451,7 +3452,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, if (info->notifies == NULL) { DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); free_a_printer(&printer, 2); - return False; + return false; } current_data = &info->notifies[info->count]; @@ -3468,7 +3469,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, } free_a_printer(&printer, 2); - return True; + return true; } /******************************************************************* @@ -3509,7 +3510,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, info->count + 1); if (info->notifies == NULL) { DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n")); - return False; + return false; } current_data=&(info->notifies[info->count]); @@ -3520,7 +3521,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, info->count++; } - return True; + return true; } /* @@ -3627,7 +3628,7 @@ static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd, int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); int i; - uint32 id; + uint32_t id; struct spoolss_NotifyOption *option; struct spoolss_NotifyOptionType option_type; int count,j; @@ -3747,7 +3748,7 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, /* We need to keep track of the change value to send back in RRPCN replies otherwise our updates are ignored. */ - Printer->notify.fnpcn = True; + Printer->notify.fnpcn = true; if (Printer->notify.client_connected) { DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: " @@ -3770,7 +3771,7 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, break; } - Printer->notify.fnpcn = False; + Printer->notify.fnpcn = false; done: return result; @@ -5157,7 +5158,7 @@ WERROR _spoolss_StartPagePrinter(pipes_struct *p, return WERR_BADFID; } - Printer->page_started=True; + Printer->page_started = true; return WERR_OK; } @@ -5181,7 +5182,7 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p, if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; - Printer->page_started=False; + Printer->page_started = false; print_job_endpage(snum, Printer->jobid); return WERR_OK; @@ -5194,7 +5195,6 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p, WERROR _spoolss_StartDocPrinter(pipes_struct *p, struct spoolss_StartDocPrinter *r) { - uint32_t *jobid = r->out.job_id; struct spoolss_DocumentInfo1 *info_1; int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); @@ -5222,7 +5222,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, if (info_1->datatype) { if (strcmp(info_1->datatype, "RAW") != 0) { - (*jobid)=0; + *r->out.job_id = 0; return WERR_INVALID_DATATYPE; } } @@ -5243,8 +5243,8 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, return map_werror_from_unix(errno); } - Printer->document_started=True; - (*jobid) = Printer->jobid; + Printer->document_started = true; + *r->out.job_id = Printer->jobid; return WERR_OK; } @@ -5266,9 +5266,7 @@ WERROR _spoolss_EndDocPrinter(pipes_struct *p, WERROR _spoolss_WritePrinter(pipes_struct *p, struct spoolss_WritePrinter *r) { - uint32 buffer_size = r->in._data_size; - uint8 *buffer = r->in.data.data; - uint32 *buffer_written = &r->in._data_size; + uint32_t buffer_written; int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); @@ -5282,9 +5280,11 @@ WERROR _spoolss_WritePrinter(pipes_struct *p, if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; - (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer, - (SMB_OFF_T)-1, (size_t)buffer_size); - if (*buffer_written == (uint32)-1) { + buffer_written = (uint32_t)print_job_write(snum, Printer->jobid, + (const char *)r->in.data.data, + (SMB_OFF_T)-1, + (size_t)r->in._data_size); + if (buffer_written == (uint32_t)-1) { *r->out.num_written = 0; if (errno == ENOSPC) return WERR_NO_SPOOL_SPACE; @@ -5515,7 +5515,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) - return True; + return true; } /**************************************************************************** @@ -5527,7 +5527,7 @@ WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname char *command = NULL; int ret; SE_PRIV se_printop = SE_PRINT_OPERATOR; - bool is_print_op = False; + bool is_print_op = false; if ( !*cmd ) { return WERR_ACCESS_DENIED; @@ -5579,7 +5579,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV int ret; int fd; SE_PRIV se_printop = SE_PRINT_OPERATOR; - bool is_print_op = False; + bool is_print_op = false; char *remote_machine = talloc_strdup(ctx, "%m"); if (!remote_machine) { @@ -5631,11 +5631,11 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV if ( ret != 0 ) { if (fd != -1) close(fd); - return False; + return false; } /* reload our services immediately */ - reload_services( False ); + reload_services(false); numlines = 0; /* Get lines and convert them back to dos-codepage */ @@ -5653,7 +5653,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV } TALLOC_FREE(qlines); - return True; + return true; } @@ -5782,7 +5782,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) { init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_comment(snum, printer->info_2->comment); } @@ -5790,7 +5790,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) { init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_sharename(snum, printer->info_2->sharename); } @@ -5806,7 +5806,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, init_unistr2( &buffer, pname, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_printername( snum, pname ); } @@ -5814,7 +5814,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) { init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_port(snum, printer->info_2->portname); } @@ -5822,7 +5822,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->location, old_printer->info_2->location)) { init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_location(snum, printer->info_2->location); } @@ -5832,15 +5832,15 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s", global_myname(), printer->info_2->sharename ); init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); /* Update printer info */ result = mod_a_printer(printer, 2); @@ -5942,7 +5942,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, return WERR_BADFID; } - if (Printer->notify.client_connected==True) { + if (Printer->notify.client_connected == true) { int snum = -1; if ( Printer->printer_type == SPLHND_SERVER) @@ -5959,7 +5959,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, Printer->notify.localmachine[0]='\0'; Printer->notify.printerlocal=0; TALLOC_FREE(Printer->notify.option); - Printer->notify.client_connected=False; + Printer->notify.client_connected = false; return WERR_OK; } @@ -6275,9 +6275,6 @@ WERROR _spoolss_ScheduleJob(pipes_struct *p, WERROR _spoolss_SetJob(pipes_struct *p, struct spoolss_SetJob *r) { - uint32 jobid = r->in.job_id; - uint32 command = r->in.command; - int snum; WERROR errcode = WERR_BADFUNC; @@ -6285,25 +6282,25 @@ WERROR _spoolss_SetJob(pipes_struct *p, return WERR_BADFID; } - if (!print_job_exists(lp_const_servicename(snum), jobid)) { + if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) { return WERR_INVALID_PRINTER_NAME; } - switch (command) { + switch (r->in.command) { case SPOOLSS_JOB_CONTROL_CANCEL: case SPOOLSS_JOB_CONTROL_DELETE: - if (print_job_delete(p->server_info, snum, jobid, &errcode)) { + if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) { errcode = WERR_OK; } break; case SPOOLSS_JOB_CONTROL_PAUSE: - if (print_job_pause(p->server_info, snum, jobid, &errcode)) { + if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) { errcode = WERR_OK; } break; case SPOOLSS_JOB_CONTROL_RESTART: case SPOOLSS_JOB_CONTROL_RESUME: - if (print_job_resume(p->server_info, snum, jobid, &errcode)) { + if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) { errcode = WERR_OK; } break; @@ -7209,7 +7206,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p, return WERR_ACCESS_DENIED; } - update_c_setprinter(False); + update_c_setprinter(false); free_a_printer(&printer,2); return WERR_OK; @@ -7251,7 +7248,7 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p, WERROR err = WERR_OK; NT_PRINTER_DRIVER_INFO_LEVEL driver; fstring driver_name; - uint32 version; + uint32_t version; const char *fn; switch (p->hdr_req.opnum) { diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index cd04462426..18c0790569 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -417,7 +417,7 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, struct policy_handle pol; WERROR result; NTSTATUS status; - uint32 info_level = 2; + uint32_t info_level = 2; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; @@ -493,7 +493,7 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, struct policy_handle pol; WERROR result; NTSTATUS status; - uint32 info_level = 2; + uint32_t info_level = 2; union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; @@ -644,7 +644,7 @@ static void display_reg_value(REGISTRY_VALUE value) switch(value.type) { case REG_DWORD: printf("%s: REG_DWORD: 0x%08x\n", value.valuename, - *((uint32 *) value.data_p)); + *((uint32_t *) value.data_p)); break; case REG_SZ: rpcstr_pull_talloc(talloc_tos(), @@ -673,7 +673,7 @@ static void display_reg_value(REGISTRY_VALUE value) break; } case REG_MULTI_SZ: { - uint32 i, num_values; + uint32_t i, num_values; char **values; if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, @@ -1338,7 +1338,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, { WERROR result; NTSTATUS status; - uint32 level = 3; + uint32_t level = 3; struct spoolss_AddDriverInfoCtr info_ctr; struct spoolss_AddDriverInfo3 info3; const char *arch; @@ -1467,7 +1467,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, struct policy_handle pol; WERROR result; NTSTATUS status; - uint32 level = 2; + uint32_t level = 2; const char *printername; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -2051,7 +2051,7 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, struct policy_handle handle; WERROR werror; const char *printername; - uint32 num_forms, level = 1, i; + uint32_t num_forms, level = 1, i; union spoolss_FormInfo *forms; /* Parse the command arguments */ @@ -2544,7 +2544,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, const char **argv) { WERROR result; - uint32 i; + uint32_t i; const char *printername; struct policy_handle hnd; uint32_t count; @@ -2764,7 +2764,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); - return False; + return false; } printf("ok\n"); @@ -2777,13 +2777,13 @@ static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); - return False; + return false; } printf("ok\n"); talloc_destroy(mem_ctx); - return True; + return true; } /**************************************************************************** @@ -2796,7 +2796,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc"); SEC_DESC *sd1, *sd2; - bool result = True; + bool result = true; printf("Retrieving printer security for %s...", cli1->desthost); @@ -2807,7 +2807,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); - result = False; + result = false; goto done; } printf("ok\n"); @@ -2820,7 +2820,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); - result = False; + result = false; goto done; } printf("ok\n"); @@ -2833,13 +2833,13 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) { printf("NULL secdesc!\n"); - result = False; + result = false; goto done; } if (!sec_desc_equal( sd1, sd2 ) ) { printf("Security Descriptors *not* equal!\n"); - result = False; + result = false; goto done; } diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 81dfbaa5b6..1d0e9a38be 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -84,7 +84,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value) switch(value.type) { case REG_DWORD: d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey, value.valuename, - *((uint32 *) value.data_p)); + *((uint32_t *) value.data_p)); break; case REG_SZ: @@ -105,7 +105,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value) break; case REG_MULTI_SZ: { - uint32 i, num_values; + uint32_t i, num_values; char **values; if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, @@ -158,7 +158,7 @@ NTSTATUS net_copy_fileattr(struct net_context *c, int fnum_src = 0; int fnum_dst = 0; SEC_DESC *sd = NULL; - uint16 attr; + uint16_t attr; time_t f_atime, f_ctime, f_mtime; @@ -654,9 +654,9 @@ static NTSTATUS copy_print_driver_3(struct net_context *c, static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, char *name, - uint32 flags, - uint32 level, - uint32 *num_printers, + uint32_t flags, + uint32_t level, + uint32_t *num_printers, union spoolss_PrinterInfo **info) { WERROR result; @@ -681,7 +681,7 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, const char *printername, - uint32 access_required, + uint32_t access_required, const char *username, struct policy_handle *hnd) { @@ -723,7 +723,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, struct policy_handle *hnd, - uint32 level, + uint32_t level, union spoolss_PrinterInfo *info) { WERROR result; @@ -745,7 +745,7 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, struct policy_handle *hnd, - uint32 level, + uint32_t level, union spoolss_PrinterInfo *info) { WERROR result; @@ -863,7 +863,7 @@ static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - uint32 offered, + uint32_t offered, struct policy_handle *hnd, const char *keyname, uint32_t *count, @@ -941,8 +941,8 @@ static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - uint32 level, const char *env, - uint32 *count, + uint32_t level, const char *env, + uint32_t *count, union spoolss_DriverInfo **info) { WERROR result; @@ -965,7 +965,7 @@ static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - struct policy_handle *hnd, uint32 level, + struct policy_handle *hnd, uint32_t level, const char *env, int version, union spoolss_DriverInfo *info) { @@ -999,7 +999,7 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, uint32 level, + TALLOC_CTX *mem_ctx, uint32_t level, union spoolss_DriverInfo *info) { WERROR result; @@ -1039,7 +1039,7 @@ static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, } /** - * abstraction function to get uint32 num_printers and PRINTER_INFO_CTR ctr + * abstraction function to get uint32_t num_printers and PRINTER_INFO_CTR ctr * for a single printer or for all printers depending on argc/argv **/ @@ -1048,7 +1048,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, int level, int argc, const char **argv, - uint32 *num_printers, + uint32_t *num_printers, union spoolss_PrinterInfo **info_p) { struct policy_handle hnd; @@ -1114,8 +1114,8 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, num_printers; - uint32 level = 2; + uint32_t i, num_printers; + uint32_t level = 2; const char *printername, *sharename; union spoolss_PrinterInfo *info; @@ -1166,8 +1166,8 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i; - uint32 level = 3; + uint32_t i; + uint32_t level = 3; union spoolss_DriverInfo *info; int d; @@ -1175,7 +1175,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, for (i=0; archi_table[i].long_archi!=NULL; i++) { - uint32 num_drivers; + uint32_t num_drivers; /* enum remote drivers */ if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level, @@ -1225,11 +1225,11 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ TALLOC_CTX *mem_ctx, int argc, const char **argv, - uint32 action) + uint32_t action) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, num_printers; - uint32 level = 7; + uint32_t i, num_printers; + uint32_t level = 7; const char *printername, *sharename; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; @@ -1373,8 +1373,8 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, num_printers; - uint32 level = 7; + uint32_t i, num_printers; + uint32_t level = 7; const char *printername, *sharename; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; @@ -1465,9 +1465,9 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, convince jerry that we should add clientside setacls level 3 at least */ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i = 0; - uint32 num_printers; - uint32 level = 2; + uint32_t i = 0; + uint32_t num_printers; + uint32_t level = 2; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct policy_handle hnd_src, hnd_dst; @@ -1611,9 +1611,9 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; WERROR result; - uint32 i, f; - uint32 num_printers; - uint32 level = 1; + uint32_t i, f; + uint32_t num_printers; + uint32_t level = 1; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct policy_handle hnd_src, hnd_dst; @@ -1771,9 +1771,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, p; - uint32 num_printers; - uint32 level = 3; + uint32_t i, p; + uint32_t num_printers; + uint32_t level = 3; const char *printername, *sharename; bool got_src_driver_share = false; bool got_dst_driver_share = false; @@ -1983,8 +1983,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, { WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i = 0, num_printers; - uint32 level = 2; + uint32_t i = 0, num_printers; + uint32_t level = 2; union spoolss_PrinterInfo info_dst, info_src; union spoolss_PrinterInfo *info_enum; struct cli_state *cli_dst = NULL; @@ -2139,9 +2139,9 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i = 0, p = 0, j = 0; - uint32 num_printers; - uint32 level = 2; + uint32_t i = 0, p = 0, j = 0; + uint32_t num_printers; + uint32_t level = 2; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct policy_handle hnd_src, hnd_dst; @@ -2445,7 +2445,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, value.type = REG_SZ; value.size = data.uni_str_len * 2; if (value.size) { - value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size); + value.data_p = (uint8_t *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size); } else { value.data_p = NULL; } -- cgit From d2fb6d348248cdca7e55360c77aa31b91250f885 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 11:04:59 +0100 Subject: s3-net: Fix Coverity #898 (UNINIT). Guenther --- source3/utils/net_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index d83fb44aba..8a92c85b9e 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1657,7 +1657,7 @@ static NTSTATUS get_sid_from_name(struct cli_state *cli, { DOM_SID *sids = NULL; enum lsa_SidType *types = NULL; - struct rpc_pipe_client *pipe_hnd; + struct rpc_pipe_client *pipe_hnd = NULL; struct policy_handle lsa_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; -- cgit From 73030b107d5722a2c42cd18240d45bcb256335ac Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 11:07:21 +0100 Subject: s3-net: Fix Coverity #861 (UNINIT). Guenther --- source3/utils/net_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 8a92c85b9e..21881ba6a9 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -54,7 +54,7 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_SID **domain_sid, const char **domain_name) { - struct rpc_pipe_client *lsa_pipe; + struct rpc_pipe_client *lsa_pipe = NULL; struct policy_handle pol; NTSTATUS result = NT_STATUS_OK; union lsa_PolicyInformation *info = NULL; -- cgit From 97190ae184dff6450b1390c854f7426e2ee3f980 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 11:11:04 +0100 Subject: s3-krb5: Fix Coverity #762 (REVERSE_INULL). Guenther --- source3/libads/kerberos.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 56d7b061a1..52cb975a6c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -511,13 +511,13 @@ char *kerberos_get_default_realm_from_ccache( void ) out: - if (princ) { - krb5_free_principal(ctx, princ); - } - if (cc) { - krb5_cc_close(ctx, cc); - } if (ctx) { + if (princ) { + krb5_free_principal(ctx, princ); + } + if (cc) { + krb5_cc_close(ctx, cc); + } krb5_free_context(ctx); } -- cgit From d2e348b191ada5492538b7bdae1bb7cd3f639aba Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 11:17:50 +0100 Subject: s3-netapi: Fix Coverity #776 (REVERSE_INULL). Guenther --- source3/lib/netapi/group.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 189902a78e..c09632a857 100644 --- a/source3/lib/netapi/group.c +++ b/source3/lib/netapi/group.c @@ -1276,6 +1276,7 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx, *r->out.buffer = NULL; *r->out.entries_read = 0; + *r->out.total_entries = 0; switch (r->in.level) { case 0: @@ -1364,13 +1365,8 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx, } } - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } + *r->out.entries_read = entries_read; + *r->out.total_entries = entries_read; werr = WERR_OK; -- cgit From f2243e8197aa064adea3da2a4d1c08250668943f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 11:19:59 +0100 Subject: s3-netapi: Fix Coverity #775 (REVERSE_INULL). Guenther --- source3/lib/netapi/user.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 8cc65a6e9e..b1bd27af2a 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -3242,6 +3242,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, *r->out.buffer = NULL; *r->out.entries_read = 0; + *r->out.total_entries = 0; switch (r->in.level) { case 0: @@ -3402,12 +3403,8 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, } } - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } + *r->out.entries_read = entries_read; + *r->out.total_entries = entries_read; done: if (ctx->disable_policy_handle_cache) { -- cgit From 3a6133d70202ef80ead4203740c000be5e93b288 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 11:21:36 +0100 Subject: s3-netapi: Fix Coverity #774 (REVERSE_INULL). Guenther --- source3/lib/netapi/user.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index b1bd27af2a..e760a8b1de 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -2806,6 +2806,7 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx, *r->out.buffer = NULL; *r->out.entries_read = 0; + *r->out.total_entries = 0; switch (r->in.level) { case 0: @@ -2899,12 +2900,8 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx, } } - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } + *r->out.entries_read = entries_read; + *r->out.total_entries = entries_read; done: if (ctx->disable_policy_handle_cache) { -- cgit From 1ef206524de589efeeef0544afbf7bfb37d99c15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Mar 2009 14:25:15 +0100 Subject: selftest/Samba3: use the same sequence of signals to shutdown samba3 as with the shell scripts When we kill the timelimit process with SIGKILL, it can't kill its children... metze --- selftest/target/Samba3.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index e1bea16523..2b96226355 100644 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -41,6 +41,9 @@ sub teardown_env($$) $self->stop_sig_term($smbdpid); $self->stop_sig_term($nmbdpid); $self->stop_sig_term($winbinddpid); + + sleep(2); + $self->stop_sig_kill($smbdpid); $self->stop_sig_kill($nmbdpid); $self->stop_sig_kill($winbinddpid); @@ -187,7 +190,7 @@ sub stop_sig_term($$) { sub stop_sig_kill($$) { my ($self, $pid) = @_; - kill("KILL", $pid) or warn("Unable to kill $pid: $!"); + kill("ALRM", $pid) or warn("Unable to kill $pid: $!"); } sub write_pid($$$) -- 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(-) 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 c9a388348a2d4b276448b6a7bfc8c575b99f8eb7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 14:47:13 +0100 Subject: s3-rpcclient: allow to set flags in enumprinters command. Guenther --- source3/rpcclient/cmd_spoolss.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 18c0790569..c9c457b364 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -257,9 +257,10 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli, union spoolss_PrinterInfo *info; uint32_t i, count; const char *name; + uint32_t flags = PRINTER_ENUM_LOCAL; - if (argc > 3) { - printf("Usage: %s [level] [name]\n", argv[0]); + if (argc > 4) { + printf("Usage: %s [level] [name] [flags]\n", argv[0]); return WERR_OK; } @@ -267,14 +268,18 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli, level = atoi(argv[1]); } - if (argc == 3) { + if (argc >= 3) { name = argv[2]; } else { name = cli->srv_name_slash; } + if (argc == 4) { + flags = atoi(argv[3]); + } + result = rpccli_spoolss_enumprinters(cli, mem_ctx, - PRINTER_ENUM_LOCAL, + flags, name, level, 0, -- cgit From 5a388115a944a425a774d7ec98260b7595998ee1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 15:14:09 +0100 Subject: s3-spoolss: apply some const in spoolss server. Guenther --- source3/include/proto.h | 6 ++-- source3/printing/nt_printing.c | 11 +++--- source3/rpc_server/srv_spoolss_nt.c | 70 ++++++++++++++++++------------------- 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9bffa4d319..dc26f6d6e5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4828,7 +4828,7 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ); WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level); bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level); -bool del_driver_init(char *drivername); +bool del_driver_init(const char *drivername); WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len); WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, @@ -4840,8 +4840,8 @@ WERROR get_a_printer_search( Printer_entry *print_hnd, const char *sharename); uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level); uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); -WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring drivername, const char *architecture, uint32 version); +WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level, + const char *drivername, const char *architecture, uint32_t version); uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 ); bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ); diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 8e6fe1f364..a99485d381 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2275,7 +2275,9 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version) +static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, + const char *drivername, const char *arch, + uint32_t version) { NT_PRINTER_DRIVER_INFO_LEVEL_3 driver; TDB_DATA dbuf; @@ -4448,7 +4450,7 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) Delete driver init data stored for a specified driver ****************************************************************************/ -bool del_driver_init(char *drivername) +bool del_driver_init(const char *drivername) { char *key; bool ret; @@ -4837,8 +4839,9 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) /**************************************************************************** ****************************************************************************/ -WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring drivername, const char *architecture, uint32 version) +WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level, + const char *drivername, const char *architecture, + uint32_t version) { WERROR result; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index b66f48aa29..01438fc7d6 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -393,7 +393,7 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, Check if it's \\server or \\server\printer ****************************************************************************/ -static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename) +static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename) { DEBUG(3,("Setting printer type=%s\n", handlename)); @@ -423,7 +423,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename XcvDataPort() interface. ****************************************************************************/ -static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) +static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename) { int snum; int n_services=lp_numservices(); @@ -434,9 +434,10 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) NT_PRINTER_INFO_LEVEL *printer = NULL; WERROR result; - DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); + DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, + (unsigned long)strlen(handlename))); - aprinter = handlename; + aprinter = CONST_DISCARD(char *, handlename); if ( *handlename == '\\' ) { servername = canon_servername(handlename); if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) { @@ -556,7 +557,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) ****************************************************************************/ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, - char *name, uint32_t access_granted) + const char *name, uint32_t access_granted) { Printer_entry *new_printer; @@ -1247,7 +1248,7 @@ static void receive_notify2_message_list(struct messaging_context *msg, driver ********************************************************************/ -static bool srv_spoolss_drv_upgrade_printer(char* drivername) +static bool srv_spoolss_drv_upgrade_printer(const char *drivername) { int len = strlen(drivername); @@ -1545,20 +1546,19 @@ bool convert_devicemode(const char *printername, WERROR _spoolss_OpenPrinterEx(pipes_struct *p, struct spoolss_OpenPrinterEx *r) { - char *name = CONST_DISCARD(char *, r->in.printername); int snum; Printer_entry *Printer=NULL; - if (!name) { + if (!r->in.printername) { return WERR_INVALID_PARAM; } /* some sanity check because you can open a printer or a print server */ /* aka: \\server\printer or \\server */ - DEBUGADD(3,("checking name: %s\n",name)); + DEBUGADD(3,("checking name: %s\n", r->in.printername)); - if (!open_printer_hnd(p, r->out.handle, name, 0)) { + if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) { ZERO_STRUCTP(r->out.handle); return WERR_INVALID_PARAM; } @@ -1566,7 +1566,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, Printer = find_printer_index_by_hnd(p, r->out.handle); if ( !Printer ) { DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer " - "handle we created for printer %s\n", name )); + "handle we created for printer %s\n", r->in.printername)); close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_INVALID_PARAM; @@ -2075,7 +2075,7 @@ WERROR _spoolss_DeletePrinter(pipes_struct *p, * long architecture string ******************************************************************/ -static int get_version_id (char * arch) +static int get_version_id(const char *arch) { int i; struct table_node archi_table[]= { @@ -2106,8 +2106,6 @@ static int get_version_id (char * arch) WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, struct spoolss_DeletePrinterDriver *r) { - char *driver; - char *arch; NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; @@ -2128,24 +2126,26 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, return WERR_ACCESS_DENIED; } - driver = CONST_DISCARD(char *, r->in.driver); - arch = CONST_DISCARD(char *, r->in.architecture); - /* check that we have a valid driver name first */ - if ((version=get_version_id(arch)) == -1) + if ((version = get_version_id(r->in.architecture)) == -1) return WERR_INVALID_ENVIRONMENT; ZERO_STRUCT(info); ZERO_STRUCT(info_win2k); - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, r->in.driver, + r->in.architecture, + version))) { /* try for Win2k driver if "Windows NT x86" */ if ( version == 2 ) { version = 3; - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, + r->in.driver, + r->in.architecture, + version))) { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } @@ -2165,7 +2165,9 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, if ( version == 2 ) { - if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) + if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, + r->in.driver, + r->in.architecture, 3))) { /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ @@ -2203,8 +2205,6 @@ done: WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, struct spoolss_DeletePrinterDriverEx *r) { - char *driver; - char *arch; NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; @@ -2225,11 +2225,8 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, return WERR_ACCESS_DENIED; } - driver = CONST_DISCARD(char *, r->in.driver); - arch = CONST_DISCARD(char *, r->in.architecture); - /* check that we have a valid driver name first */ - if ((version=get_version_id(arch)) == -1) { + if ((version = get_version_id(r->in.architecture)) == -1) { /* this is what NT returns */ return WERR_INVALID_ENVIRONMENT; } @@ -2240,7 +2237,8 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, ZERO_STRUCT(info); ZERO_STRUCT(info_win2k); - status = get_a_printer_driver(&info, 3, driver, arch, version); + status = get_a_printer_driver(&info, 3, r->in.driver, + r->in.architecture, version); if ( !W_ERROR_IS_OK(status) ) { @@ -2256,7 +2254,9 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, /* try for Win2k driver if "Windows NT x86" */ version = 3; - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, r->in.driver, + r->in.architecture, + version))) { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } @@ -2293,7 +2293,9 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, /* also check for W32X86/3 if necessary; maybe we already have? */ if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { - if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) + if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, + r->in.driver, + r->in.architecture, 3))) { if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) { @@ -7247,7 +7249,7 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p, struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr; WERROR err = WERR_OK; NT_PRINTER_DRIVER_INFO_LEVEL driver; - fstring driver_name; + const char *driver_name = NULL; uint32_t version; const char *fn; @@ -7297,12 +7299,10 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p, switch(level) { case 3: - fstrcpy(driver_name, - driver.info_3->name ? driver.info_3->name : ""); + driver_name = driver.info_3->name ? driver.info_3->name : ""; break; case 6: - fstrcpy(driver_name, - driver.info_6->name ? driver.info_6->name : ""); + driver_name = driver.info_6->name ? driver.info_6->name : ""; break; } -- cgit From 95f2913c7de2ac69421911ec2cb0fcbb8c4e8e93 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 15:44:31 +0100 Subject: s3-spoolss: add enum_all_printers_info_level(). Guenther --- source3/rpc_server/srv_spoolss_nt.c | 77 +++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 01438fc7d6..6c8c942c05 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4204,6 +4204,83 @@ static bool snum_is_shared_printer(int snum) Spoolss_enumprinters. ********************************************************************/ +static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, + uint32_t level, + uint32_t flags, + union spoolss_PrinterInfo **info_p, + uint32_t *count_p) +{ + int snum; + int n_services = lp_numservices(); + union spoolss_PrinterInfo *info = NULL; + uint32_t count = 0; + WERROR result = WERR_OK; + + *count_p = 0; + *info_p = NULL; + + for (snum = 0; snum < n_services; snum++) { + + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; + + if (!snum_is_shared_printer(snum)) { + continue; + } + + DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", + lp_servicename(snum), snum)); + + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_PrinterInfo, + count + 1); + if (!info) { + result = WERR_NOMEM; + goto out; + } + + result = get_a_printer(NULL, &ntprinter, 2, + lp_const_servicename(snum)); + if (!W_ERROR_IS_OK(result)) { + goto out; + } + + switch (level) { + case 1: + result = construct_printer_info1(info, ntprinter, flags, + &info[count].info1, snum); + break; + case 2: + result = construct_printer_info2(info, ntprinter, + &info[count].info2, snum); + break; + default: + result = WERR_UNKNOWN_LEVEL; + free_a_printer(&ntprinter, 2); + goto out; + } + + free_a_printer(&ntprinter, 2); + if (!W_ERROR_IS_OK(result)) { + goto out; + } + + count++; + } + + *count_p = count; + *info_p = info; + + out: + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(info); + return result; + } + + *info_p = info; + + return WERR_OK; +} + static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx, uint32_t flags, union spoolss_PrinterInfo **info_p, -- cgit From 6713244d465b0cf69f1bba15744e05795ec2fda9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 15:48:10 +0100 Subject: s3-spoolss: use enum_all_printers_info_level for level 1 and 2. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 118 +++--------------------------------- 1 file changed, 8 insertions(+), 110 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 6c8c942c05..61d4e69506 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4281,67 +4281,17 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, return WERR_OK; } +/******************************************************************** +********************************************************************/ + static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx, uint32_t flags, - union spoolss_PrinterInfo **info_p, + union spoolss_PrinterInfo **info, uint32_t *count) { - int snum; - int n_services = lp_numservices(); - union spoolss_PrinterInfo *info = NULL; - WERROR result = WERR_OK; - DEBUG(4,("enum_all_printers_info_1\n")); - *count = 0; - - for (snum=0; snum Date: Fri, 20 Mar 2009 15:49:57 +0100 Subject: s3-spoolss: implement enumprinters_level5. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 61d4e69506..ebb5ec4671 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4253,6 +4253,11 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, result = construct_printer_info2(info, ntprinter, &info[count].info2, snum); break; + case 5: + result = construct_printer_info5(info, ntprinter, + &info[count].info5, snum); + break; + default: result = WERR_UNKNOWN_LEVEL; free_a_printer(&ntprinter, 2); @@ -4444,8 +4449,9 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx, union spoolss_PrinterInfo **info, uint32_t *count) { -/* return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/ - return WERR_OK; + DEBUG(4,("enum_all_printers_info_5\n")); + + return enum_all_printers_info_level(mem_ctx, 5, flags, info, count); } /**************************************************************** -- cgit From d2de9b068c19a8eaac64f9cf4ea4aae153cffcd4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 15:53:17 +0100 Subject: s3-spoolss: implement enumprinters_level4. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index ebb5ec4671..0d649e8cbf 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4253,6 +4253,10 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, result = construct_printer_info2(info, ntprinter, &info[count].info2, snum); break; + case 4: + result = construct_printer_info4(info, ntprinter, + &info[count].info4, snum); + break; case 5: result = construct_printer_info5(info, ntprinter, &info[count].info5, snum); @@ -4439,6 +4443,22 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx, return WERR_OK; } +/******************************************************************** + * handle enumeration of printers at level 4 + ********************************************************************/ + +static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *servername, + union spoolss_PrinterInfo **info, + uint32_t *count) +{ + DEBUG(4,("enum_all_printers_info_4\n")); + + return enum_all_printers_info_level(mem_ctx, 4, flags, info, count); +} + + /******************************************************************** * handle enumeration of printers at level 5 ********************************************************************/ @@ -4501,12 +4521,15 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p, result = enumprinters_level2(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); break; + case 4: + result = enumprinters_level4(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 5: result = enumprinters_level5(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); break; case 3: - case 4: result = WERR_OK; /* ??? */ break; default: -- cgit From 19de802c171f70ec4de102452afac52e2c0e548f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 16:03:54 +0100 Subject: s3-spoolss: _spoolss_EnumPrinters level 3 always returns WERR_UNKNOWN_LEVEL. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 0d649e8cbf..a8d414b85e 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4529,9 +4529,6 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p, result = enumprinters_level5(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); break; - case 3: - result = WERR_OK; /* ??? */ - break; default: return WERR_UNKNOWN_LEVEL; } -- 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(-) 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(-) 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(+) 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(-) 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(-) 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(-) 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 66dc53ee017d74a6f610bbe04337f064901fe2a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Mar 2009 16:27:17 +0100 Subject: socket_wrapper: fix connect() for dgram sockets, if the destination isn't there yet metze --- lib/socket_wrapper/socket_wrapper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 44082e78a1..1d35c8d20c 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -1686,10 +1686,14 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); + if (si->type == SOCK_DGRAM) { + ret = 0; + } else { + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); - ret = real_connect(s, (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + } /* to give better errors */ if (ret == -1 && errno == ENOENT) { -- 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(-) 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 --- selftest/target/Samba4.pm | 8 ++++---- source3/samba4.mk | 12 ++++++------ source4/selftest/config.mk | 12 ++++++------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 71dddf6939..1058ac66e0 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -103,8 +103,8 @@ sub check_or_start($$$) SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE}); my $valgrind = ""; - if (defined($ENV{SMBD_VALGRIND})) { - $valgrind = $ENV{SMBD_VALGRIND}; + if (defined($ENV{SAMBA_VALGRIND})) { + $valgrind = $ENV{SAMBA_VALGRIND}; } $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG}; @@ -122,8 +122,8 @@ sub check_or_start($$$) if (defined($max_time)) { $optarg = "--maximum-runtime=$max_time "; } - if (defined($ENV{SMBD_OPTIONS})) { - $optarg.= " $ENV{SMBD_OPTIONS}"; + if (defined($ENV{SAMBA_OPTIONS})) { + $optarg.= " $ENV{SAMBA_OPTIONS}"; } my $samba = $self->bindir_path("samba"); my $ret = system("$valgrind $samba $optarg $env_vars->{CONFIGURATION} -M single -i --leak-report-full"); diff --git a/source3/samba4.mk b/source3/samba4.mk index 7e7690aadf..3f661bdd14 100644 --- a/source3/samba4.mk +++ b/source3/samba4.mk @@ -225,32 +225,32 @@ test4-%:: valgrindtest4:: valgrindtest-all valgrindtest4-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" \ $(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) valgrindtest4-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" \ $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) valgrindtest4-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" \ $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv gdbtest4:: gdbtest4-all gdbtest4-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)" \ $(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) gdbtest4-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)" \ $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) gdbtest4-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)" \ $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv plugins: $(PLUGINS) 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 431fc718c13d259748ac20019997241981639c95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Mar 2009 16:18:47 +0100 Subject: selftest/Samba3: always use the same timeout for all servers metze --- selftest/target/Samba3.pm | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 2b96226355..78aafa7533 100644 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -126,9 +126,8 @@ sub setup_dc($$) $dc_options); $self->check_or_start($vars, - ($ENV{NMBD_MAXTIME} or 2700), - ($ENV{WINBINDD_MAXTIME} or 2700), - ($ENV{SMBD_MAXTIME} or 2700)); + ($ENV{SMBD_MAXTIME} or 2700), + "yes", "yes", "yes"); $self->wait_for_start($vars); @@ -163,9 +162,8 @@ sub setup_member($$$) system($cmd) == 0 or die("Join failed\n$cmd"); $self->check_or_start($ret, - ($ENV{NMBD_MAXTIME} or 2700), - ($ENV{WINBINDD_MAXTIME} or 2700), - ($ENV{SMBD_MAXTIME} or 2700)); + ($ENV{SMBD_MAXTIME} or 2700), + "yes", "yes", "yes"); $self->wait_for_start($ret); @@ -212,8 +210,8 @@ sub read_pid($$) return $pid; } -sub check_or_start($$$$) { - my ($self, $env_vars, $nmbd_maxtime, $winbindd_maxtime, $smbd_maxtime) = @_; +sub check_or_start($$$$$) { + my ($self, $env_vars, $maxtime, $nmbd, $winbindd, $smbd) = @_; unlink($env_vars->{NMBD_TEST_LOG}); print "STARTING NMBD..."; @@ -229,13 +227,13 @@ sub check_or_start($$$$) { $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; - if ($nmbd_maxtime eq "skip") { + if ($nmbd ne "yes") { $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { my $signame = shift; print("Skip nmbd received signal $signame"); exit 0; }; - sleep(999999); + sleep($maxtime); exit 0; } @@ -246,7 +244,7 @@ sub check_or_start($$$$) { $ENV{MAKE_TEST_BINARY} = $self->binpath("nmbd"); - my @preargs = ($self->binpath("timelimit"), $nmbd_maxtime); + my @preargs = ($self->binpath("timelimit"), $maxtime); if(defined($ENV{NMBD_VALGRIND})) { @preargs = split(/ /, $ENV{NMBD_VALGRIND}); } @@ -270,13 +268,13 @@ sub check_or_start($$$$) { $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; - if ($winbindd_maxtime eq "skip") { + if ($winbindd ne "yes") { $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { my $signame = shift; print("Skip winbindd received signal $signame"); exit 0; }; - sleep(999999); + sleep($maxtime); exit 0; } @@ -287,7 +285,7 @@ sub check_or_start($$$$) { $ENV{MAKE_TEST_BINARY} = $self->binpath("winbindd"); - my @preargs = ($self->binpath("timelimit"), $winbindd_maxtime); + my @preargs = ($self->binpath("timelimit"), $maxtime); if(defined($ENV{WINBINDD_VALGRIND})) { @preargs = split(/ /, $ENV{WINBINDD_VALGRIND}); } @@ -311,13 +309,13 @@ sub check_or_start($$$$) { $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; - if ($smbd_maxtime eq "skip") { + if ($smbd ne "yes") { $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { my $signame = shift; print("Skip smbd received signal $signame"); exit 0; }; - sleep(999999); + sleep($maxtime); exit 0; } @@ -326,7 +324,7 @@ sub check_or_start($$$$) { if (defined($ENV{SMBD_OPTIONS})) { @optargs = split(/ /, $ENV{SMBD_OPTIONS}); } - my @preargs = ($self->binpath("timelimit"), $smbd_maxtime); + my @preargs = ($self->binpath("timelimit"), $maxtime); if(defined($ENV{SMBD_VALGRIND})) { @preargs = split(/ /,$ENV{SMBD_VALGRIND}); } -- cgit From 3b73cdb41201dd545e019e8e8313f6b8c51c7226 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Jan 2009 10:10:12 +0100 Subject: s3:nmbd: implement a MAILSLOT => CLDAP proxy for NETLOGON_SAMLOGON requests This will be used as part a the franky setup, where nmbd will forward the MAILSLOT requests to the local samba4 CLDAP server. "nmbd_proxy_logon:cldap_server = 127.0.0.1" would configure and activate this feature. metze --- source3/include/proto.h | 2 + source3/nmbd/nmbd.c | 6 + source3/nmbd/nmbd_processlogon.c | 238 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index dc26f6d6e5..c84b1cb9ac 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3779,6 +3779,8 @@ bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len, /* The following definitions come from nmbd/nmbd_processlogon.c */ +bool initialize_nmbd_proxy_logon(void); + void process_logon_packet(struct packet_struct *p, char *buf,int len, const char *mailslot); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 3279466602..daf4c295a6 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -988,6 +988,12 @@ static bool open_sockets(bool isdaemon, int port) exit(1); } + if (!initialize_nmbd_proxy_logon()) { + DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n")); + kill_async_dns_child(); + exit(1); + } + TALLOC_FREE(frame); process(); diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 59a2ca405e..8173337da0 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -24,6 +24,9 @@ */ #include "includes.h" +#include "../libcli/netlogon.h" +#include "../libcli/cldap/cldap.h" +#include "../lib/tsocket/tsocket.h" struct sam_database_info { uint32 index; @@ -65,6 +68,235 @@ static void delayed_init_logon_handler(struct event_context *event_ctx, TALLOC_FREE(te); } +struct nmbd_proxy_logon_context { + struct cldap_socket *cldap_sock; +}; + +static struct nmbd_proxy_logon_context *global_nmbd_proxy_logon; + +bool initialize_nmbd_proxy_logon(void) +{ + const char *cldap_server = lp_parm_const_string(-1, "nmbd_proxy_logon", + "cldap_server", NULL); + struct nmbd_proxy_logon_context *ctx; + NTSTATUS status; + struct in_addr addr; + char addrstr[INET_ADDRSTRLEN]; + const char *server_str; + int ret; + struct tsocket_address *server_addr; + + if (!cldap_server) { + return true; + } + + addr = interpret_addr2(cldap_server); + server_str = inet_ntop(AF_INET, &addr, + addrstr, sizeof(addrstr)); + if (!server_str || strcmp("0.0.0.0", server_str) == 0) { + DEBUG(0,("Failed to resolve[%s] for nmbd_proxy_logon\n", + cldap_server)); + return false; + } + + ctx = talloc_zero(nmbd_event_context(), + struct nmbd_proxy_logon_context); + if (!ctx) { + return false; + } + + ret = tsocket_address_inet_from_strings(ctx, "ipv4", + server_str, LDAP_PORT, + &server_addr); + if (ret != 0) { + TALLOC_FREE(ctx); + status = map_nt_error_from_unix(errno); + DEBUG(0,("Failed to create cldap tsocket_address for %s - %s\n", + server_str, nt_errstr(status))); + return false; + } + + /* we create a connected udp socket */ + status = cldap_socket_init(ctx, nmbd_event_context(), NULL, + server_addr, &ctx->cldap_sock); + TALLOC_FREE(server_addr); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(ctx); + DEBUG(0,("failed to create cldap socket for %s: %s\n", + server_str, nt_errstr(status))); + return false; + } + + global_nmbd_proxy_logon = ctx; + return true; +} + +struct nmbd_proxy_logon_state { + struct in_addr local_ip; + struct packet_struct *p; + const char *remote_name; + uint8_t remote_name_type; + const char *remote_mailslot; + struct nbt_netlogon_packet req; + struct nbt_netlogon_response resp; + struct cldap_netlogon io; +}; + +static int nmbd_proxy_logon_state_destructor(struct nmbd_proxy_logon_state *s) +{ + s->p->locked = false; + free_packet(s->p); + return 0; +} + +static void nmbd_proxy_logon_done(struct tevent_req *subreq); + +static void nmbd_proxy_logon(struct nmbd_proxy_logon_context *ctx, + struct in_addr local_ip, + struct packet_struct *p, + uint8_t *buf, + uint32_t len) +{ + struct nmbd_proxy_logon_state *state; + enum ndr_err_code ndr_err; + DATA_BLOB blob = data_blob_const(buf, len); + const char *computer_name = NULL; + const char *mailslot_name = NULL; + const char *user_name = NULL; + const char *domain_sid = NULL; + uint32_t acct_control = 0; + uint32_t nt_version = 0; + struct tevent_req *subreq; + fstring source_name; + struct dgram_packet *dgram = &p->packet.dgram; + + state = TALLOC_ZERO_P(ctx, struct nmbd_proxy_logon_state); + if (!state) { + DEBUG(0,("failed to allocate nmbd_proxy_logon_state\n")); + return; + } + + pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); + state->remote_name = talloc_strdup(state, source_name); + state->remote_name_type = dgram->source_name.name_type, + state->local_ip = local_ip; + state->p = p; + + ndr_err = ndr_pull_struct_blob( + &blob, state, NULL, &state->req, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("failed parse nbt_letlogon_packet: %s\n", + nt_errstr(status))); + TALLOC_FREE(state); + return; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10, ("nmbd_proxy_logon:\n")); + NDR_PRINT_DEBUG(nbt_netlogon_packet, &state->req); + } + + switch (state->req.command) { + case LOGON_SAM_LOGON_REQUEST: + computer_name = state->req.req.logon.computer_name; + user_name = state->req.req.logon.user_name; + mailslot_name = state->req.req.logon.mailslot_name; + acct_control = state->req.req.logon.acct_control; + if (state->req.req.logon.sid_size > 0) { + domain_sid = dom_sid_string(state, + &state->req.req.logon.sid); + if (!domain_sid) { + DEBUG(0,("failed to get a string for sid\n")); + TALLOC_FREE(state); + return; + } + } + nt_version = state->req.req.logon.nt_version; + break; + + default: + /* this can't happen as the caller already checks the command */ + break; + } + + state->remote_mailslot = mailslot_name; + + if (user_name && strlen(user_name) == 0) { + user_name = NULL; + } + + if (computer_name && strlen(computer_name) == 0) { + computer_name = NULL; + } + + /* + * as the socket is connected, + * we don't need to specify the destination + */ + state->io.in.dest_address = NULL; + state->io.in.dest_port = 0; + state->io.in.realm = NULL; + state->io.in.host = computer_name; + state->io.in.user = user_name; + state->io.in.domain_guid = NULL; + state->io.in.domain_sid = domain_sid; + state->io.in.acct_control = acct_control; + state->io.in.version = nt_version; + state->io.in.map_response = false; + + subreq = cldap_netlogon_send(state, + ctx->cldap_sock, + &state->io); + if (!subreq) { + DEBUG(0,("failed to send cldap netlogon call\n")); + TALLOC_FREE(state); + return; + } + tevent_req_set_callback(subreq, nmbd_proxy_logon_done, state); + + /* we reply async */ + state->p->locked = true; + talloc_set_destructor(state, nmbd_proxy_logon_state_destructor); +} + +static void nmbd_proxy_logon_done(struct tevent_req *subreq) +{ + struct nmbd_proxy_logon_state *state = + tevent_req_callback_data(subreq, + struct nmbd_proxy_logon_state); + NTSTATUS status; + DATA_BLOB response; + + status = cldap_netlogon_recv(subreq, NULL, state, &state->io); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("failed to recv cldap netlogon call: %s\n", + nt_errstr(status))); + TALLOC_FREE(state); + return; + } + + status = push_netlogon_samlogon_response(&response, state, NULL, + &state->io.out.netlogon); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("failed to push netlogon_samlogon_response: %s\n", + nt_errstr(status))); + TALLOC_FREE(state); + return; + } + + send_mailslot(true, state->remote_mailslot, + (char *)response.data, response.length, + global_myname(), 0x0, + state->remote_name, + state->remote_name_type, + state->p->ip, + state->local_ip, + state->p->port); + TALLOC_FREE(state); +} + /**************************************************************************** Process a domain logon packet **************************************************************************/ @@ -318,6 +550,12 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", char *q = buf + 2; fstring asccomp; + if (global_nmbd_proxy_logon) { + nmbd_proxy_logon(global_nmbd_proxy_logon, + ip, p, (uint8_t *)buf, len); + return; + } + q += 2; if (PTR_DIFF(q, buf) >= len) { -- cgit From f55e84e904173bed8dc9099ad523ca1e7be12355 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 10:17:24 +0100 Subject: Add a basic Doxyfile for talloc --- lib/talloc/Doxyfile | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/talloc/Doxyfile diff --git a/lib/talloc/Doxyfile b/lib/talloc/Doxyfile new file mode 100644 index 0000000000..0ccf563d75 --- /dev/null +++ b/lib/talloc/Doxyfile @@ -0,0 +1,8 @@ +OUTPUT_DIRECTORY = doc +PROJECT_NAME = Talloc +OPTIMIZE_OUTPUT_FOR_C = YES +GENERATE_LATEX = NO +GENERATE_MAN = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +PREDEFINED = PRINTF_ATTRIBUTE(x,y)= -- cgit From d21212c9192b41a3fdc7e96cb9bf0125a1dc6c2d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 12:43:08 +0100 Subject: Convert the contents of talloc_guide.txt to doxygen-style talloc.h comments talloc_guide.txt was partly outdated, and as going through talloc.h now shows it was incomplete. --- lib/talloc/talloc.h | 1024 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1023 insertions(+), 1 deletion(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 5c8d5c5fe2..4b50ba99c2 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -29,7 +29,119 @@ #include #include -/* this is only needed for compatibility with the old talloc */ +/** \mainpage + * + * \section intro_sec Introduction + * + * Talloc is a hierarchical, reference counted memory pool system with + * destructors. Quite a mouthful really, but not too bad once you get used to + * it. + * + * Perhaps the biggest difference from other memory pool systems is that there + * is no distinction between a "talloc context" and a "talloc pointer". Any + * pointer returned from talloc() is itself a valid talloc context. This means + * you can do this: + * + * \code + * struct foo *X = talloc(mem_ctx, struct foo); + * X->name = talloc_strdup(X, "foo"); + * \endcode + * + * and the pointer X->name would be a "child" of the talloc context "X" which + * is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) then it is + * all destroyed, whereas if you do talloc_free(X) then just X and X->name are + * destroyed, and if you do talloc_free(X->name) then just the name element of + * X is destroyed. + * + * If you think about this, then what this effectively gives you is an n-ary + * tree, where you can free any part of the tree with talloc_free(). + * + * \section named_blocks Named blocks + * + * Every talloc chunk has a name that can be used as a dynamic type-checking + * system. If for some reason like a callback function you had to cast a + * "struct foo *" to a "void *" variable, later you can safely reassign the + * "void *" pointer to a "struct foo *" by using the talloc_get_type() or + * talloc_get_type_abort() macros. + * + * \code + * struct foo *X = talloc_get_type_abort(ptr, struct foo); + * \endcode + * + * This will abort if "ptr" does not contain a pointer that has been created + * with talloc(mem_ctx, struct foo). + * + * \section multi_threading Multi-Threading + * + * talloc itself does not deal with threads. It is thread-safe (assuming the + * underlying "malloc" is), as long as each thread uses different memory + * contexts. + * + * If two threads uses the same context then they need to synchronize in order + * to be safe. In particular: + * + * + * - when using talloc_enable_leak_report(), giving directly NULL as a + * parent context implicitly refers to a hidden "null context" global + * variable, so this should not be used in a multi-threaded environment + * without proper synchronization + * - the context returned by talloc_autofree_context() is also global so + * shouldn't be used by several threads simultaneously without + * synchronization. + */ + +/** \defgroup talloc_basic Basic Talloc Routines + * + * This module contains the basic talloc routines that are used in everyday + * programming. + */ + +/** \defgroup talloc_ref Talloc References + * + * This module contains the definitions around talloc references + */ + +/** \defgroup talloc_array Array routines + * + * Talloc contains some handy helpers for handling Arrays conveniently + */ + +/** \defgroup talloc_string String handling routines + * + * Talloc contains some handy string handling functions + */ + +/** \defgroup talloc_debug Debugging support routines + * + * To aid memory debugging, talloc contains routines to inspect the currently + * allocated memory hierarchy. + */ + +/** + * \typedef TALLOC_CTX + * \brief Define a talloc parent type + * \ingroup talloc_basic + * + * As talloc is a hierarchial memory allocator, every talloc chunk is a + * potential parent to other talloc chunks. So defining a separate type for a + * talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless, + * as it provides an indicator for function arguments. You will frequently + * write code like + * + * \code + * struct foo *foo_create(TALLOC_CTX *mem_ctx) + * { + * struct foo *result; + * result = talloc(mem_ctx, struct foo); + * if (result == NULL) return NULL; + * ... initialize foo ... + * return result; + * } + * \endcode + * + * In this type of allocating functions it is handy to have a general + * TALLOC_CTX type to indicate which parent to put allocated structures on. + */ typedef void TALLOC_CTX; /* @@ -58,6 +170,62 @@ typedef void TALLOC_CTX; #endif #endif +/** + * \def talloc_set_destructor + * \brief Assign a function to be called when a chunk is freed + * \param ptr The talloc chunk to add a destructor to + * \param function The destructor function to be called + * \ingroup talloc_basic + * + * The function talloc_set_destructor() sets the "destructor" for the pointer + * "ptr". A destructor is a function that is called when the memory used by a + * pointer is about to be released. The destructor receives the pointer as an + * argument, and should return 0 for success and -1 for failure. + * + * The destructor can do anything it wants to, including freeing other pieces + * of memory. A common use for destructors is to clean up operating system + * resources (such as open file descriptors) contained in the structure the + * destructor is placed on. + * + * You can only place one destructor on a pointer. If you need more than one + * destructor then you can create a zero-length child of the pointer and place + * an additional destructor on that. + * + * To remove a destructor call talloc_set_destructor() with NULL for the + * destructor. + * + * If your destructor attempts to talloc_free() the pointer that it is the + * destructor for then talloc_free() will return -1 and the free will be + * ignored. This would be a pointless operation anyway, as the destructor is + * only called when the memory is just about to go away. + */ + +/** + * \def talloc_steal(ctx, ptr) + * \brief Change a talloc chunk's parent + * \param ctx The new parent context + * \param ptr The talloc chunk to move + * \return ptr + * \ingroup talloc_basic + * + * The talloc_steal() function changes the parent context of a talloc + * pointer. It is typically used when the context that the pointer is + * currently a child of is going to be freed and you wish to keep the + * memory for a longer time. + * + * The talloc_steal() function returns the pointer that you pass it. It + * does not have any failure modes. + * + * NOTE: It is possible to produce loops in the parent/child relationship + * if you are not careful with talloc_steal(). No guarantees are provided + * as to your sanity or the safety of your data if you do this. + * + * To make the changed hierarchy less error-prone, you might consider to use + * talloc_move(). + * + * talloc_steal (ctx, NULL) will return NULL with no sideeffects. + */ + /* try to make talloc_set_destructor() and talloc_steal() type safe, if we have a recent gcc */ #if (__GNUC__ >= 3) @@ -77,34 +245,359 @@ typedef void TALLOC_CTX; #define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)) #endif +/** + * \def talloc_reference(ctx, ptr) + * \brief Create an additional talloc parent to a pointer + * \param ctx The additional parent + * \param ptr The pointer you want to create an additional parent for + * \return ptr + * \ingroup talloc_ref + * + * The talloc_reference() function makes "context" an additional parent of + * "ptr". + * + * The return value of talloc_reference() is always the original pointer + * "ptr", unless talloc ran out of memory in creating the reference in which + * case it will return NULL (each additional reference consumes around 48 + * bytes of memory on intel x86 platforms). + * + * If "ptr" is NULL, then the function is a no-op, and simply returns NULL. + * + * After creating a reference you can free it in one of the following ways: + * + * - you can talloc_free() any parent of the original pointer. That + * will reduce the number of parents of this pointer by 1, and will + * cause this pointer to be freed if it runs out of parents. + * + * - you can talloc_free() the pointer itself. That will destroy the + * most recently established parent to the pointer and leave the + * pointer as a child of its current parent. + * + * For more control on which parent to remove, see talloc_unlink() + */ #define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr)) + + +/** + * \def talloc_move(ctx, ptr) + * \brief Change a talloc chunk's parent + * \param ctx The new parent context + * \param ptr Pointer to the talloc chunk to move + * \return ptr + * \ingroup talloc_basic + * + * talloc_move() has the same effect as talloc_steal(), and additionally sets + * the source pointer to NULL. You would use it like this: + * + * \code + * struct foo *X = talloc(tmp_ctx, struct foo); + * struct foo *Y; + * Y = talloc_move(new_ctx, &X); + * \endcode + */ #define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr)) /* useful macros for creating type checked pointers */ + +/** + * \def talloc(ctx, type) + * \brief Main entry point to allocate structures + * \param ctx The talloc context to hang the result off + * \param type The type that we want to allocate + * \return Pointer to a piece of memory, properly cast to "type *" + * \ingroup talloc_basic + * + * The talloc() macro is the core of the talloc library. It takes a memory + * context and a type, and returns a pointer to a new area of memory of the + * given type. + * + * The returned pointer is itself a talloc context, so you can use it as the + * context argument to more calls to talloc if you wish. + * + * The returned pointer is a "child" of the supplied context. This means that + * if you talloc_free() the context then the new child disappears as + * well. Alternatively you can free just the child. + * + * The context argument to talloc() can be NULL, in which case a new top + * level context is created. + */ #define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) + +/** + * \def talloc_size(ctx, size) + * \brief Untyped allocation + * \param ctx The talloc context to hang the result off + * \param size Number of char's that you want to allocate + * \return The allocated memory chunk + * \ingroup talloc_basic + * + * The function talloc_size() should be used when you don't have a convenient + * type to pass to talloc(). Unlike talloc(), it is not type safe (as it + * returns a void *), so you are on your own for type checking. + */ #define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) + +/** + * \def talloc_ptrtype(ctx, ptr) + * \brief Allocate into a typed pointer + * \param ctx The talloc context to hang the result off + * \param ptr The pointer you want to assign the result to + * \result The allocated memory chunk, properly cast + * \ingroup talloc_basic + * + * The talloc_ptrtype() macro should be used when you have a pointer and + * want to allocate memory to point at with this pointer. When compiling + * with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() + * and talloc_get_name() will return the current location in the source file. + * and not the type. + */ #define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) +/** + * \def talloc_new(ctx) + * \brief Allocate a new 0-sized talloc chunk + * \param ctx The talloc parent context + * \return A new talloc chunk + * \ingroup talloc_basic + * + * This is a utility macro that creates a new memory context hanging off an + * exiting context, automatically naming it "talloc_new: __location__" where + * __location__ is the source line it is called from. It is particularly + * useful for creating a new temporary working context. + */ #define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) +/** + * \def talloc_zero(ctx, type) + * \brief Allocate a 0-initizialized structure + * \param ctx The talloc context to hang the result off + * \param type The type that we want to allocate + * \return Pointer to a piece of memory, properly cast to "type *" + * \ingroup talloc_basic + * + * The talloc_zero() macro is equivalent to: + * + * \code + * ptr = talloc(ctx, type); + * if (ptr) memset(ptr, 0, sizeof(type)); + * \endcode + */ #define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) + +/** + * \def talloc_zero_size(ctx, size) + * \brief Untyped, 0-initialized allocation + * \param ctx The talloc context to hang the result off + * \param size Number of char's that you want to allocate + * \return The allocated memory chunk + * \ingroup talloc_basic + * + * The talloc_zero_size() macro is equivalent to: + * + * \code + * ptr = talloc_size(ctx, size); + * if (ptr) memset(ptr, 0, size); + * \endcode + */ + #define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) #define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) + +/** + * \def talloc_array(ctx, type, count) + * \brief Allocate an array + * \param ctx The talloc context to hang the result off + * \param type The type that we want to allocate + * \param count The number of "type" elements you want to allocate + * \return The allocated result, properly cast to "type *" + * \ingroup talloc_array + * + * The talloc_array() macro is equivalent to:: + * + * \code + * (type *)talloc_size(ctx, sizeof(type) * count); + * \endcode + * + * except that it provides integer overflow protection for the multiply, + * returning NULL if the multiply overflows. + */ #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) + +/** + * \def talloc_array_size(ctx, size, count) + * \brief Allocate an array + * \param ctx The talloc context to hang the result off + * \param size The size of an array element + * \param count The number of "type" elements you want to allocate + * \return The allocated result, properly cast to "type *" + * \ingroup talloc_array + * + * The talloc_array_size() function is useful when the type is not + * known. It operates in the same way as talloc_array(), but takes a size + * instead of a type. + */ #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) + +/** + * \def talloc_array_ptrtype(ctx, ptr, count) + * \brief Allocate an array into a typed pointer + * \param ctx The talloc context to hang the result off + * \param ptr The pointer you want to assign the result to + * \param count The number of elements you want to allocate + * \result The allocated memory chunk, properly cast + * \ingroup talloc_array + * + * The talloc_array_ptrtype() macro should be used when you have a pointer to + * an array and want to allocate memory of an array to point at with this + * pointer. When compiling with gcc >= 3 it is typesafe. Note this is a + * wrapper of talloc_array_size() and talloc_get_name() will return the + * current location in the source file. and not the type. + */ #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) + +/** + * \def talloc_array_length(ctx) + * \brief Return the number of elements in a talloc'ed array + * \param ctx The talloc'ed array + * \return The number of elements in ctx + * \ingroup talloc_array + * + * A talloc chunk carries its own size, so for talloc'ed arrays it is not + * necessary to store the number of elements explicitly. + */ #define talloc_array_length(ctx) ((ctx) ? talloc_get_size(ctx)/sizeof(*ctx) : 0) +/** + * \def talloc_realloc(ctx, p, type, count) + * \brief Change the size of a talloc array + * \param ctx The parent context used if "p" is NULL + * \param p The chunk to be resized + * \param type The type of the array element inside p + * \param count The intended number of array elements + * \return The new array + * \ingroup talloc_array + * + * The talloc_realloc() macro changes the size of a talloc + * pointer. The "count" argument is the number of elements of type "type" + * that you want the resulting pointer to hold. + * + * talloc_realloc() has the following equivalences:: + * + * \code + * talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); + * talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); + * talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); + * \endcode + * + * The "context" argument is only used if "ptr" is NULL, otherwise it is + * ignored. + * + * talloc_realloc() returns the new pointer, or NULL on failure. The call + * will fail either due to a lack of memory, or because the pointer has + * more than one parent (see talloc_reference()). + */ #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) + +/** + * \def talloc_realloc_size(ctx, ptr, size) + * \brief Untyped realloc + * \param ctx The parent context used if "ptr" is NULL + * \param ptr The chunk to be resized + * \param size The new chunk size + * \return The new chunk + * \ingroup talloc_array + * + * The talloc_realloc_size() function is useful when the type is not known so + * the typesafe talloc_realloc() cannot be used. + */ #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) +/** + * \def talloc_memdup(t, p, size) + * \brief Duplicate a memory area into a talloc chunk + * \param t The talloc context to hang the result off + * \param p The memory chunk you want to duplicate + * \param size Number of char's that you want copy + * \return The allocated memory chunk + * \ingroup talloc_basic + * + * The talloc_memdup() function is equivalent to:: + * + * \code + * ptr = talloc_size(ctx, size); + * if (ptr) memcpy(ptr, p, size); + * \endcode + */ #define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) +/** + * \def talloc_set_type(ptr, type) + * \brief Assign a type to a talloc chunk + * \param ptr The talloc chunk to assign the type to + * \param type The type to assign + * \ingroup talloc_basic + * + * This macro allows you to force the name of a pointer to be a + * particular type. This can be used in conjunction with + * talloc_get_type() to do type checking on void* pointers. + * + * It is equivalent to this:: + * + * \code + * talloc_set_name_const(ptr, #type) + * \endcode + */ #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) + +/** + * \def talloc_get_type(ptr, type) + * \brief Get a typed pointer out of a talloc pointer + * \param ptr The talloc pointer to check + * \param type The type to check against + * \return ptr, properly cast, or NULL + * \ingroup talloc_basic + * + * This macro allows you to do type checking on talloc pointers. It is + * particularly useful for void* private pointers. It is equivalent to + * this: + * + * \code + * (type *)talloc_check_name(ptr, #type) + * \endcode + */ + #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) + +/** + * \def talloc_get_type_abort(ptr, type) + * \brief Helper macro to safely turn a void * into a typed pointer + * \param ptr The void * to convert + * \param type The type that this chunk contains + * \return Same value as ptr, type-checked and properly cast + * \ingroup talloc_basic + * + * This macro is used together with talloc(mem_ctx, struct foo). If you had to + * assing the talloc chunk pointer to some void * variable, + * talloc_get_type_abort() is the recommended way to get the convert the void + * pointer back to a typed pointer. + */ #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) +/** + * \def talloc_find_parent_bytype(ptr, type) + * \brief Find a parent context by type + * \param ptr The talloc chunk to start from + * \param type The type of the parent to look for + * \ingroup talloc_basic + * + * Find a parent memory context of the current context that has the given + * name. This can be very useful in complex programs where it may be + * difficult to pass all information down to the level you need, but you + * know the structure you want is a parent of another context. + * + * Like talloc_find_parent_byname() but takes a type, making it typesafe. + */ #define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) #if TALLOC_DEPRECATED @@ -122,67 +615,596 @@ typedef void TALLOC_CTX; void *_talloc(const void *context, size_t size); void *talloc_pool(const void *context, size_t size); void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + +/** + * \brief Increase the reference count of a talloc chunk + * \param ptr + * \return success? + * \ingroup talloc_ref + * + * The talloc_increase_ref_count(ptr) function is exactly equivalent to: + * + * \code + * talloc_reference(NULL, ptr); + * \endcode + * + * You can use either syntax, depending on which you think is clearer in + * your code. + * + * It returns 0 on success and -1 on failure. + */ int talloc_increase_ref_count(const void *ptr); + +/** + * \brief Return the number of references to a talloc chunk + * \param ptr The chunk you are interested in + * \return Number of refs + * \ingroup talloc_ref + */ size_t talloc_reference_count(const void *ptr); void *_talloc_reference(const void *context, const void *ptr); + +/** + * \brief Remove a specific parent from a talloc chunk + * \param context The talloc parent to remove + * \param ptr The talloc ptr you want to remove the parent from + * \ingroup talloc_ref + * + * The talloc_unlink() function removes a specific parent from ptr. The + * context passed must either be a context used in talloc_reference() with + * this pointer, or must be a direct parent of ptr. + * + * Note that if the parent has already been removed using talloc_free() then + * this function will fail and will return -1. Likewise, if "ptr" is NULL, + * then the function will make no modifications and return -1. + * + * Usually you can just use talloc_free() instead of talloc_unlink(), but + * sometimes it is useful to have the additional control on which parent is + * removed. + */ int talloc_unlink(const void *context, void *ptr); + +/** + * \brief Assign a name to a talloc chunk + * \param ptr The talloc chunk to assign a name to + * \param fmt Format string for the name + * \param ... printf-style additional arguments + * \return The assigned name + * \ingroup talloc_basic + * + * Each talloc pointer has a "name". The name is used principally for + * debugging purposes, although it is also possible to set and get the name on + * a pointer in as a way of "marking" pointers in your code. + * + * The main use for names on pointer is for "talloc reports". See + * talloc_report() and talloc_report_full() for details. Also see + * talloc_enable_leak_report() and talloc_enable_leak_report_full(). + * + * The talloc_set_name() function allocates memory as a child of the + * pointer. It is logically equivalent to: + * + * \code + * talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + * \endcode + * + * Note that multiple calls to talloc_set_name() will allocate more memory + * without releasing the name. All of the memory is released when the ptr is + * freed using talloc_free(). + */ const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/** + * \brief Assign a name to a talloc chunk + * \param ptr The talloc chunk to assign a name to + * \param name Format string for the name + * \ingroup talloc_basic + * + * The function talloc_set_name_const() is just like talloc_set_name(), but it + * takes a string constant, and is much faster. It is extensively used by the + * "auto naming" macros, such as talloc_p(). + * + * This function does not allocate any memory. It just copies the supplied + * pointer into the internal representation of the talloc ptr. This means you + * must not pass a name pointer to memory that will disappear before the ptr + * is freed with talloc_free(). + */ void talloc_set_name_const(const void *ptr, const char *name); + +/** + * \brief Create a named talloc chunk + * \param context The talloc context to hang the result off + * \param size Number of char's that you want to allocate + * \param fmt Format string for the name + * \param ... printf-style additional arguments + * \return The allocated memory chunk + * \ingroup talloc_basic + * + * The talloc_named() function creates a named talloc pointer. It is + * equivalent to: + * + * \code + * ptr = talloc_size(context, size); + * talloc_set_name(ptr, fmt, ....); + * \endcode + * + */ void *talloc_named(const void *context, size_t size, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +/** + * \brief Basic routine to allocate a chunk of memory + * \param context The parent context + * \param size The number of char's that we want to allocate + * \param name The name the talloc block has + * \return The allocated chunk + * \ingroup talloc_basic + * + * This is equivalent to: + * + * \code + * ptr = talloc_size(context, size); + * talloc_set_name_const(ptr, name); + * \endcode + */ void *talloc_named_const(const void *context, size_t size, const char *name); + +/** + * \brief Return the name of a talloc chunk + * \param ptr The talloc chunk + * \return The name + * \ingroup talloc_basic + * + * This returns the current name for the given talloc pointer. See + * talloc_set_name() for details. + */ const char *talloc_get_name(const void *ptr); + +/** + * \brief Verify that a talloc chunk carries a specified name + * \param ptr The talloc chunk to check + * \param name The name to check agains + * \ingroup talloc_basic + * + * This function checks if a pointer has the specified name. If it does + * then the pointer is returned. It it doesn't then NULL is returned. + */ void *talloc_check_name(const void *ptr, const char *name); + void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); void *talloc_parent(const void *ptr); const char *talloc_parent_name(const void *ptr); + +/** + * \brief Create a new top level talloc context + * \param fmt Format string for the name + * \param ... printf-style additional arguments + * \return The allocated memory chunk + * \ingroup talloc_basic + * + * This function creates a zero length named talloc context as a top level + * context. It is equivalent to: + * + * \code + * talloc_named(NULL, 0, fmt, ...); + * \endcode + */ void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); + +/** + * \brief Free a chunk of talloc memory + * \param ptr The chunk to be freed + * \return success? + * \ingroup talloc_basic + * + * The talloc_free() function frees a piece of talloc memory, and all its + * children. You can call talloc_free() on any pointer returned by talloc(). + * + * The return value of talloc_free() indicates success or failure, with 0 + * returned for success and -1 for failure. The only possible failure + * condition is if the pointer had a destructor attached to it and the + * destructor returned -1. See talloc_set_destructor() for details on + * destructors. + * + * If this pointer has an additional parent when talloc_free() is called + * then the memory is not actually released, but instead the most + * recently established parent is destroyed. See talloc_reference() for + * details on establishing additional parents. + * + * For more control on which parent is removed, see talloc_unlink() + * + * talloc_free() operates recursively on its children. + */ int talloc_free(void *ptr); + +/** + * \brief Free a talloc chunk's children + * \param ptr The chunk that you want to free the children of + * \return success? + * \ingroup talloc_basic + * + * The talloc_free_children() walks along the list of all children of a talloc + * context and talloc_free()s only the children, not the context itself. + */ void talloc_free_children(void *ptr); void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); void *_talloc_steal(const void *new_ctx, const void *ptr); void *_talloc_move(const void *new_ctx, const void *pptr); + +/** + * \brief Return the total size of a talloc chunk including its children + * \param ptr The talloc chunk + * \return The total size + * \ingroup talloc_basic + * + * The talloc_total_size() function returns the total size in bytes used + * by this pointer and all child pointers. Mostly useful for debugging. + * + * Passing NULL is allowed, but it will only give a meaningful result if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + */ size_t talloc_total_size(const void *ptr); + +/** + * \brief Return the number of talloc chunks hanging off a chunk + * \param ptr The talloc chunk + * \return The total size + * \ingroup talloc_basic + * + * The talloc_total_blocks() function returns the total memory block + * count used by this pointer and all child pointers. Mostly useful for + * debugging. + * + * Passing NULL is allowed, but it will only give a meaningful result if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + */ size_t talloc_total_blocks(const void *ptr); + +/** + * \brief Walk a complete talloc hierarchy + * \param ptr The talloc chunk + * \param depth Internal parameter to control recursion. Call with 0. + * \param max_depth Maximum recursion level. + * \param callback Function to be called on every chunk + * \param private_data Private pointer passed to callback + * \ingroup talloc_debug + * + * This provides a more flexible reports than talloc_report(). It + * will recursively call the callback for the entire tree of memory + * referenced by the pointer. References in the tree are passed with + * is_ref = 1 and the pointer that is referenced. + * + * You can pass NULL for the pointer, in which case a report is + * printed for the top level memory context, but only if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() + * has been called. + * + * The recursion is stopped when depth >= max_depth. + * max_depth = -1 means only stop at leaf nodes. + */ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *private_data), void *private_data); + +/** + * \brief Print a talloc hierarchy + * \param ptr The talloc chunk + * \param depth Internal parameter to control recursion. Call with 0. + * \param max_depth Maximum recursion level. + * \param f The file handle to print to + * \ingroup talloc_debug + * + * This provides a more flexible reports than talloc_report(). It + * will let you specify the depth and max_depth. + */ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); + +/** + * \brief Print a summary report of all memory used by ptr + * \param ptr The talloc chunk + * \param f The file handle to print to + * \ingroup talloc_debug + * + * This provides a more detailed report than talloc_report(). It will + * recursively print the ensire tree of memory referenced by the + * pointer. References in the tree are shown by giving the name of the + * pointer that is referenced. + * + * You can pass NULL for the pointer, in which case a report is printed + * for the top level memory context, but only if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + */ void talloc_report_full(const void *ptr, FILE *f); + +/** + * \brief Print a summary report of all memory used by ptr + * \param ptr The talloc chunk + * \param f The file handle to print to + * \ingroup talloc_debug + * + * The talloc_report() function prints a summary report of all memory + * used by ptr. One line of report is printed for each immediate child of + * ptr, showing the total memory and number of blocks used by that child. + * + * You can pass NULL for the pointer, in which case a report is printed + * for the top level memory context, but only if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + */ void talloc_report(const void *ptr, FILE *f); + +/** + * \brief Enable tracking the use of NULL memory contexts + * \ingroup talloc_debug + * + * This enables tracking of the NULL memory context without enabling leak + * reporting on exit. Useful for when you want to do your own leak + * reporting call via talloc_report_null_full(); + */ void talloc_enable_null_tracking(void); + +/** + * \brief Disable tracking of the NULL memory context + * \ingroup talloc_debug + * + * This disables tracking of the NULL memory context. + */ + void talloc_disable_null_tracking(void); + +/** + * \brief Enable calling of talloc_report(NULL, stderr) when a program exits + * \ingroup talloc_debug + * + * This enables calling of talloc_report(NULL, stderr) when the program + * exits. In Samba4 this is enabled by using the --leak-report command + * line option. + * + * For it to be useful, this function must be called before any other + * talloc function as it establishes a "null context" that acts as the + * top of the tree. If you don't call this function first then passing + * NULL to talloc_report() or talloc_report_full() won't give you the + * full tree printout. + * + * Here is a typical talloc report: + * +\verbatim +talloc report on 'null_context' (total 267 bytes in 15 blocks) + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(UTF8,CP850) contains 42 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(CP850,UTF8) contains 42 bytes in 2 blocks + iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks + iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks +\endverbatim + */ void talloc_enable_leak_report(void); + +/** + * \brief Enable calling of talloc_report(NULL, stderr) when a program exits + * \ingroup talloc_debug + * + * This enables calling of talloc_report_full(NULL, stderr) when the + * program exits. In Samba4 this is enabled by using the + * --leak-report-full command line option. + * + * For it to be useful, this function must be called before any other + * talloc function as it establishes a "null context" that acts as the + * top of the tree. If you don't call this function first then passing + * NULL to talloc_report() or talloc_report_full() won't give you the + * full tree printout. + * + * Here is a typical full report: +\verbatim +full talloc report on 'root' (total 18 bytes in 8 blocks) + p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) +\endverbatim +*/ void talloc_enable_leak_report_full(void); void *_talloc_zero(const void *ctx, size_t size, const char *name); void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); + +/** + * \brief Provide a function version of talloc_realloc_size + * \param context The parent context used if "ptr" is NULL + * \param ptr The chunk to be resized + * \param size The new chunk size + * \return The new chunk + * \ingroup talloc_array + * + * This is a non-macro version of talloc_realloc(), which is useful as + * libraries sometimes want a ralloc function pointer. A realloc() + * implementation encapsulates the functionality of malloc(), free() and + * realloc() in one call, which is why it is useful to be able to pass around + * a single function pointer. +*/ void *talloc_realloc_fn(const void *context, void *ptr, size_t size); + +/** + * \brief Provide a talloc context that is freed at program exit + * \return A talloc context + * \ingroup talloc_basic + * + * This is a handy utility function that returns a talloc context + * which will be automatically freed on program exit. This can be used + * to reduce the noise in memory leak reports. + */ void *talloc_autofree_context(void); + +/** + * \brief Get the size of a talloc chunk + * \param ctx The talloc chunk + * \return The size + * \ingroup talloc_basic + * + * This function lets you know the amount of memory alloced so far by + * this context. It does NOT account for subcontext memory. + * This can be used to calculate the size of an array. + */ size_t talloc_get_size(const void *ctx); + +/** + * \brief Find a parent context by name + * \param ctx The talloc chunk to start from + * \param name The name of the parent we look for + * \ingroup talloc_basic + * + * Find a parent memory context of the current context that has the given + * name. This can be very useful in complex programs where it may be + * difficult to pass all information down to the level you need, but you + * know the structure you want is a parent of another context. + */ void *talloc_find_parent_byname(const void *ctx, const char *name); void talloc_show_parents(const void *context, FILE *file); int talloc_is_parent(const void *context, const void *ptr); +/** + * \brief Duplicate a string into a talloc chunk + * \param t The talloc context to hang the result off + * \param p The string you want to duplicate + * \return The duplicated string + * \ingroup talloc_string + * + * The talloc_strdup() function is equivalent to: + * + * \code + * ptr = talloc_size(ctx, strlen(p)+1); + * if (ptr) memcpy(ptr, p, strlen(p)+1); + * \endcode + * + * This functions sets the name of the new pointer to the passed + * string. This is equivalent to: + * + * \code + * talloc_set_name_const(ptr, ptr) + * \endcode + */ char *talloc_strdup(const void *t, const char *p); char *talloc_strdup_append(char *s, const char *a); char *talloc_strdup_append_buffer(char *s, const char *a); +/** + * \brief Duplicate a length-limited string into a talloc chunk + * \param t The talloc context to hang the result off + * \param p The string you want to duplicate + * \param n The maximum string length to duplicate + * \return The duplicated string + * \ingroup talloc_string + * + * The talloc_strndup() function is the talloc equivalent of the C + * library function strndup() + * + * This functions sets the name of the new pointer to the passed + * string. This is equivalent to: + * + * \code + * talloc_set_name_const(ptr, ptr) + * \endcode + */ char *talloc_strndup(const void *t, const char *p, size_t n); char *talloc_strndup_append(char *s, const char *a, size_t n); char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); +/** + * \brief Format a string given a va_list + * \param t The talloc context to hang the result off + * \param fmt The format string + * \param ap The parameters used to fill fmt + * \return The formatted string + * \ingroup talloc_string + * + * The talloc_vasprintf() function is the talloc equivalent of the C + * library function vasprintf() + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * \code + * talloc_set_name_const(ptr, ptr) + * \endcode + */ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +/** + * \brief Format a string + * \param t The talloc context to hang the result off + * \param fmt The format string + * \param ... The parameters used to fill fmt + * \return The formatted string + * \ingroup talloc_string + * + * The talloc_asprintf() function is the talloc equivalent of the C + * library function asprintf() + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * \code + * talloc_set_name_const(ptr, ptr) + * \endcode + */ char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/** + * \brief Append a formatted string to another string + * \param s The string to append to + * \param fmt The format string + * \param ... The parameters used to fill fmt + * \return The formatted string + * \ingroup talloc_string + * + * The talloc_asprintf_append() function appends the given formatted string to + * the given string. Use this varient when the string in the current talloc + * buffer may have been truncated in length. + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * \code + * talloc_set_name_const(ptr, ptr) + * \endcode + */ char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/** + * \brief Append a formatted string to another string + * \param s The string to append to + * \param fmt The format string + * \param ... The parameters used to fill fmt + * \return The formatted string + * \ingroup talloc_string + * + * The talloc_asprintf_append() function appends the given formatted string to + * the end of the currently allocated talloc buffer. This routine should be + * used if you create a large string step by step. talloc_asprintf() or + * talloc_asprintf_append() call strlen() at every + * step. talloc_asprintf_append_buffer() uses the existing buffer size of the + * talloc chunk to calculate where to append the string. + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * \code + * talloc_set_name_const(ptr, ptr) + * \endcode + */ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); -- cgit From 3f9c30022a53a37ad829f8882a9a5161fcadda8b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 16:40:33 +0100 Subject: Delete talloc_guide.txt --- lib/talloc/talloc_guide.txt | 694 -------------------------------------------- 1 file changed, 694 deletions(-) delete mode 100644 lib/talloc/talloc_guide.txt diff --git a/lib/talloc/talloc_guide.txt b/lib/talloc/talloc_guide.txt deleted file mode 100644 index 3201fe6f0f..0000000000 --- a/lib/talloc/talloc_guide.txt +++ /dev/null @@ -1,694 +0,0 @@ -Using talloc in Samba4 -====================== - -.. contents:: - -Andrew Tridgell -September 2004 - -The most current version of this document is available at - http://samba.org/ftp/unpacked/samba4/source/lib/talloc/talloc_guide.txt - -If you are used to the "old" talloc from Samba3 before 3.0.20 then please read -this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the -Samba4 talloc has been ported back to Samba3, so this guide applies to both. - -The new talloc is a hierarchical, reference counted memory pool system -with destructors. Quite a mouthful really, but not too bad once you -get used to it. - -Perhaps the biggest change from Samba3 is that there is no distinction -between a "talloc context" and a "talloc pointer". Any pointer -returned from talloc() is itself a valid talloc context. This means -you can do this:: - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - -and the pointer X->name would be a "child" of the talloc context "X" -which is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) -then it is all destroyed, whereas if you do talloc_free(X) then just X -and X->name are destroyed, and if you do talloc_free(X->name) then -just the name element of X is destroyed. - -If you think about this, then what this effectively gives you is an -n-ary tree, where you can free any part of the tree with -talloc_free(). - -If you find this confusing, then I suggest you run the testsuite to -watch talloc in action. You may also like to add your own tests to -testsuite.c to clarify how some particular situation is handled. - - -Performance ------------ - -All the additional features of talloc() over malloc() do come at a -price. We have a simple performance test in Samba4 that measures -talloc() versus malloc() performance, and it seems that talloc() is -about 4% slower than malloc() on my x86 Debian Linux box. For Samba, -the great reduction in code complexity that we get by using talloc -makes this worthwhile, especially as the total overhead of -talloc/malloc in Samba is already quite small. - - -talloc API ----------- - -The following is a complete guide to the talloc API. Read it all at -least twice. - -Multi-threading ---------------- - -talloc itself does not deal with threads. It is thread-safe (assuming -the underlying "malloc" is), as long as each thread uses different -memory contexts. -If two threads uses the same context then they need to synchronize in -order to be safe. In particular: -- when using talloc_enable_leak_report(), giving directly NULL as a -parent context implicitly refers to a hidden "null context" global -variable, so this should not be used in a multi-threaded environment -without proper synchronization ; -- the context returned by talloc_autofree_context() is also global so -shouldn't be used by several threads simultaneously without -synchronization. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc(const void *context, type); - -The talloc() macro is the core of the talloc library. It takes a -memory context and a type, and returns a pointer to a new area of -memory of the given type. - -The returned pointer is itself a talloc context, so you can use it as -the context argument to more calls to talloc if you wish. - -The returned pointer is a "child" of the supplied context. This means -that if you talloc_free() the context then the new child disappears as -well. Alternatively you can free just the child. - -The context argument to talloc() can be NULL, in which case a new top -level context is created. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_size(const void *context, size_t size); - -The function talloc_size() should be used when you don't have a -convenient type to pass to talloc(). Unlike talloc(), it is not type -safe (as it returns a void *), so you are on your own for type checking. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); - -The talloc_ptrtype() macro should be used when you have a pointer and -want to allocate memory to point at with this pointer. When compiling -with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() -and talloc_get_name() will return the current location in the source file. -and not the type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free(void *ptr); - -The talloc_free() function frees a piece of talloc memory, and all its -children. You can call talloc_free() on any pointer returned by -talloc(). - -The return value of talloc_free() indicates success or failure, with 0 -returned for success and -1 for failure. The only possible failure -condition is if the pointer had a destructor attached to it and the -destructor returned -1. See talloc_set_destructor() for details on -destructors. - -If this pointer has an additional parent when talloc_free() is called -then the memory is not actually released, but instead the most -recently established parent is destroyed. See talloc_reference() for -details on establishing additional parents. - -For more control on which parent is removed, see talloc_unlink() - -talloc_free() operates recursively on its children. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free_children(void *ptr); - -The talloc_free_children() walks along the list of all children of a -talloc context and talloc_free()s only the children, not the context -itself. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_reference(const void *context, const void *ptr); - -The talloc_reference() function makes "context" an additional parent -of "ptr". - -The return value of talloc_reference() is always the original pointer -"ptr", unless talloc ran out of memory in creating the reference in -which case it will return NULL (each additional reference consumes -around 48 bytes of memory on intel x86 platforms). - -If "ptr" is NULL, then the function is a no-op, and simply returns NULL. - -After creating a reference you can free it in one of the following -ways: - - - you can talloc_free() any parent of the original pointer. That - will reduce the number of parents of this pointer by 1, and will - cause this pointer to be freed if it runs out of parents. - - - you can talloc_free() the pointer itself. That will destroy the - most recently established parent to the pointer and leave the - pointer as a child of its current parent. - -For more control on which parent to remove, see talloc_unlink() - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_unlink(const void *context, const void *ptr); - -The talloc_unlink() function removes a specific parent from ptr. The -context passed must either be a context used in talloc_reference() -with this pointer, or must be a direct parent of ptr. - -Note that if the parent has already been removed using talloc_free() -then this function will fail and will return -1. Likewise, if "ptr" -is NULL, then the function will make no modifications and return -1. - -Usually you can just use talloc_free() instead of talloc_unlink(), but -sometimes it is useful to have the additional control on which parent -is removed. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - -The function talloc_set_destructor() sets the "destructor" for the -pointer "ptr". A destructor is a function that is called when the -memory used by a pointer is about to be released. The destructor -receives the pointer as an argument, and should return 0 for success -and -1 for failure. - -The destructor can do anything it wants to, including freeing other -pieces of memory. A common use for destructors is to clean up -operating system resources (such as open file descriptors) contained -in the structure the destructor is placed on. - -You can only place one destructor on a pointer. If you need more than -one destructor then you can create a zero-length child of the pointer -and place an additional destructor on that. - -To remove a destructor call talloc_set_destructor() with NULL for the -destructor. - -If your destructor attempts to talloc_free() the pointer that it is -the destructor for then talloc_free() will return -1 and the free will -be ignored. This would be a pointless operation anyway, as the -destructor is only called when the memory is just about to go away. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_increase_ref_count(const void *ptr); - -The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - -You can use either syntax, depending on which you think is clearer in -your code. - -It returns 0 on success and -1 on failure. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_reference_count(const void *ptr); - -Return the number of references to the pointer. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name(const void *ptr, const char *fmt, ...); - -Each talloc pointer has a "name". The name is used principally for -debugging purposes, although it is also possible to set and get the -name on a pointer in as a way of "marking" pointers in your code. - -The main use for names on pointer is for "talloc reports". See -talloc_report() and talloc_report_full() for details. Also see -talloc_enable_leak_report() and talloc_enable_leak_report_full(). - -The talloc_set_name() function allocates memory as a child of the -pointer. It is logically equivalent to: - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - -Note that multiple calls to talloc_set_name() will allocate more -memory without releasing the name. All of the memory is released when -the ptr is freed using talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name_const(const void *ptr, const char *name); - -The function talloc_set_name_const() is just like talloc_set_name(), -but it takes a string constant, and is much faster. It is extensively -used by the "auto naming" macros, such as talloc_p(). - -This function does not allocate any memory. It just copies the -supplied pointer into the internal representation of the talloc -ptr. This means you must not pass a name pointer to memory that will -disappear before the ptr is freed with talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named(const void *context, size_t size, const char *fmt, ...); - -The talloc_named() function creates a named talloc pointer. It is -equivalent to: - - ptr = talloc_size(context, size); - talloc_set_name(ptr, fmt, ....); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named_const(const void *context, size_t size, const char *name); - -This is equivalent to:: - - ptr = talloc_size(context, size); - talloc_set_name_const(ptr, name); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const char *talloc_get_name(const void *ptr); - -This returns the current name for the given talloc pointer. See -talloc_set_name() for details. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_init(const char *fmt, ...); - -This function creates a zero length named talloc context as a top -level context. It is equivalent to:: - - talloc_named(NULL, 0, fmt, ...); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_new(void *ctx); - -This is a utility macro that creates a new memory context hanging -off an exiting context, automatically naming it "talloc_new: __location__" -where __location__ is the source line it is called from. It is -particularly useful for creating a new temporary working context. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_realloc(const void *context, void *ptr, type, count); - -The talloc_realloc() macro changes the size of a talloc -pointer. The "count" argument is the number of elements of type "type" -that you want the resulting pointer to hold. - -talloc_realloc() has the following equivalences:: - - talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); - talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); - talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); - -The "context" argument is only used if "ptr" is NULL, otherwise it is -ignored. - -talloc_realloc() returns the new pointer, or NULL on failure. The call -will fail either due to a lack of memory, or because the pointer has -more than one parent (see talloc_reference()). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_realloc_size(const void *context, void *ptr, size_t size); - -the talloc_realloc_size() function is useful when the type is not -known so the typesafe talloc_realloc() cannot be used. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_steal(const void *new_ctx, const void *ptr); - -The talloc_steal() function changes the parent context of a talloc -pointer. It is typically used when the context that the pointer is -currently a child of is going to be freed and you wish to keep the -memory for a longer time. - -The talloc_steal() function returns the pointer that you pass it. It -does not have any failure modes. - -NOTE: It is possible to produce loops in the parent/child relationship -if you are not careful with talloc_steal(). No guarantees are provided -as to your sanity or the safety of your data if you do this. - -talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_total_size(const void *ptr); - -The talloc_total_size() function returns the total size in bytes used -by this pointer and all child pointers. Mostly useful for debugging. - -Passing NULL is allowed, but it will only give a meaningful result if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_total_blocks(const void *ptr); - -The talloc_total_blocks() function returns the total memory block -count used by this pointer and all child pointers. Mostly useful for -debugging. - -Passing NULL is allowed, but it will only give a meaningful result if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *priv), - void *priv); - -This provides a more flexible reports than talloc_report(). It -will recursively call the callback for the entire tree of memory -referenced by the pointer. References in the tree are passed with -is_ref = 1 and the pointer that is referenced. - -You can pass NULL for the pointer, in which case a report is -printed for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() -has been called. - -The recursion is stopped when depth >= max_depth. -max_depth = -1 means only stop at leaf nodes. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); - -This provides a more flexible reports than talloc_report(). It -will let you specify the depth and max_depth. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report(const void *ptr, FILE *f); - -The talloc_report() function prints a summary report of all memory -used by ptr. One line of report is printed for each immediate child of -ptr, showing the total memory and number of blocks used by that child. - -You can pass NULL for the pointer, in which case a report is printed -for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_full(const void *ptr, FILE *f); - -This provides a more detailed report than talloc_report(). It will -recursively print the ensire tree of memory referenced by the -pointer. References in the tree are shown by giving the name of the -pointer that is referenced. - -You can pass NULL for the pointer, in which case a report is printed -for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_leak_report(void); - -This enables calling of talloc_report(NULL, stderr) when the program -exits. In Samba4 this is enabled by using the --leak-report command -line option. - -For it to be useful, this function must be called before any other -talloc function as it establishes a "null context" that acts as the -top of the tree. If you don't call this function first then passing -NULL to talloc_report() or talloc_report_full() won't give you the -full tree printout. - -Here is a typical talloc report: - -talloc report on 'null_context' (total 267 bytes in 15 blocks) - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(UTF8,CP850) contains 42 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(CP850,UTF8) contains 42 bytes in 2 blocks - iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks - iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_leak_report_full(void); - -This enables calling of talloc_report_full(NULL, stderr) when the -program exits. In Samba4 this is enabled by using the ---leak-report-full command line option. - -For it to be useful, this function must be called before any other -talloc function as it establishes a "null context" that acts as the -top of the tree. If you don't call this function first then passing -NULL to talloc_report() or talloc_report_full() won't give you the -full tree printout. - -Here is a typical full report: - -full talloc report on 'root' (total 18 bytes in 8 blocks) - p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_null_tracking(void); - -This enables tracking of the NULL memory context without enabling leak -reporting on exit. Useful for when you want to do your own leak -reporting call via talloc_report_null_full(); - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_disable_null_tracking(void); - -This disables tracking of the NULL memory context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_zero(const void *ctx, type); - -The talloc_zero() macro is equivalent to:: - - ptr = talloc(ctx, type); - if (ptr) memset(ptr, 0, sizeof(type)); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_zero_size(const void *ctx, size_t size) - -The talloc_zero_size() function is useful when you don't have a known type - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_memdup(const void *ctx, const void *p, size_t size); - -The talloc_memdup() function is equivalent to:: - - ptr = talloc_size(ctx, size); - if (ptr) memcpy(ptr, p, size); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_strdup(const void *ctx, const char *p); - -The talloc_strdup() function is equivalent to:: - - ptr = talloc_size(ctx, strlen(p)+1); - if (ptr) memcpy(ptr, p, strlen(p)+1); - -This functions sets the name of the new pointer to the passed -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_strndup(const void *t, const char *p, size_t n); - -The talloc_strndup() function is the talloc equivalent of the C -library function strndup() - -This functions sets the name of the new pointer to the passed -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_append_string(const void *t, char *orig, const char *append); - -The talloc_append_string() function appends the given formatted -string to the given string. - -This function sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); - -The talloc_vasprintf() function is the talloc equivalent of the C -library function vasprintf() - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf(const void *t, const char *fmt, ...); - -The talloc_asprintf() function is the talloc equivalent of the C -library function asprintf() - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf_append(char *s, const char *fmt, ...); - -The talloc_asprintf_append() function appends the given formatted -string to the given string. -Use this varient when the string in the current talloc buffer may -have been truncated in length. - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); - -The talloc_asprintf_append() function appends the given formatted -string to the end of the currently allocated talloc buffer. -Use this varient when the string in the current talloc buffer has -not been changed. - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -((type *)talloc_array(const void *ctx, type, uint_t count); - -The talloc_array() macro is equivalent to:: - - (type *)talloc_size(ctx, sizeof(type) * count); - -except that it provides integer overflow protection for the multiply, -returning NULL if the multiply overflows. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_array_size(const void *ctx, size_t size, uint_t count); - -The talloc_array_size() function is useful when the type is not -known. It operates in the same way as talloc_array(), but takes a size -instead of a type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count); - -The talloc_ptrtype() macro should be used when you have a pointer to an array -and want to allocate memory of an array to point at with this pointer. When compiling -with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() -and talloc_get_name() will return the current location in the source file. -and not the type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); - -This is a non-macro version of talloc_realloc(), which is useful -as libraries sometimes want a ralloc function pointer. A realloc() -implementation encapsulates the functionality of malloc(), free() and -realloc() in one call, which is why it is useful to be able to pass -around a single function pointer. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_autofree_context(void); - -This is a handy utility function that returns a talloc context -which will be automatically freed on program exit. This can be used -to reduce the noise in memory leak reports. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_check_name(const void *ptr, const char *name); - -This function checks if a pointer has the specified name. If it does -then the pointer is returned. It it doesn't then NULL is returned. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_get_type(const void *ptr, type); - -This macro allows you to do type checking on talloc pointers. It is -particularly useful for void* private pointers. It is equivalent to -this:: - - (type *)talloc_check_name(ptr, #type) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -talloc_set_type(const void *ptr, type); - -This macro allows you to force the name of a pointer to be a -particular type. This can be used in conjunction with -talloc_get_type() to do type checking on void* pointers. - -It is equivalent to this:: - - talloc_set_name_const(ptr, #type) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -talloc_get_size(const void *ctx); - -This function lets you know the amount of memory alloced so far by -this context. It does NOT account for subcontext memory. -This can be used to calculate the size of an array. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_find_parent_byname(const void *ctx, const char *name); - -Find a parent memory context of the current context that has the given -name. This can be very useful in complex programs where it may be -difficult to pass all information down to the level you need, but you -know the structure you want is a parent of another context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_find_parent_bytype(ctx, type); - -Like talloc_find_parent_byname() but takes a type, making it typesafe. - -- cgit From ba42320c7e9f5ccbd32eccbfb1f2d77e13b3a318 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 16:50:58 +0100 Subject: Add a default "undocumented" module --- lib/talloc/talloc.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 4b50ba99c2..523a4840d3 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -117,6 +117,13 @@ * allocated memory hierarchy. */ +/** \defgroup todo Default group of undocumented stuff + * + * This should be empty... + */ + +/*\{*/ + /** * \typedef TALLOC_CTX * \brief Define a talloc parent type @@ -1210,3 +1217,5 @@ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIB void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); #endif + +/*\}*/ -- cgit From cfce2d3611f225244fadf3d27d76371827fd6422 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 16:52:13 +0100 Subject: Add some initial hook to the front page --- lib/talloc/talloc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 523a4840d3..d0a9762f4d 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -56,6 +56,9 @@ * If you think about this, then what this effectively gives you is an n-ary * tree, where you can free any part of the tree with talloc_free(). * + * To start, you should probably first look at the definitions of + * ::TALLOC_CTX, talloc_init(), talloc() and talloc_free(). + * * \section named_blocks Named blocks * * Every talloc chunk has a name that can be used as a dynamic type-checking -- cgit From db447d0c476699dbf7fa0567c67f5938674ec811 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 16:58:54 +0100 Subject: Reformatting --- lib/talloc/talloc.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index d0a9762f4d..4adc67b7fd 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -99,28 +99,33 @@ * programming. */ -/** \defgroup talloc_ref Talloc References +/** + * \defgroup talloc_ref Talloc References * * This module contains the definitions around talloc references */ -/** \defgroup talloc_array Array routines +/** + * \defgroup talloc_array Array routines * * Talloc contains some handy helpers for handling Arrays conveniently */ -/** \defgroup talloc_string String handling routines +/** + * \defgroup talloc_string String handling routines * * Talloc contains some handy string handling functions */ -/** \defgroup talloc_debug Debugging support routines +/** + * \defgroup talloc_debug Debugging support routines * * To aid memory debugging, talloc contains routines to inspect the currently * allocated memory hierarchy. */ -/** \defgroup todo Default group of undocumented stuff +/** + * \defgroup talloc_undoc Default group of undocumented stuff * * This should be empty... */ -- cgit From 27944ed7452207ef3c686ff6bcd9c4e1cb7f36d8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 19:48:54 +0100 Subject: Document talloc_pool() --- lib/talloc/talloc.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 4adc67b7fd..e44d924e76 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -628,6 +628,41 @@ typedef void TALLOC_CTX; /* The following definitions come from talloc.c */ void *_talloc(const void *context, size_t size); + +/** + * \brief Allocate a talloc pool + * \param context The talloc context to hang the result off + * \param size Size of the talloc pool + * \result The talloc pool + * \ingroup talloc_basic + * + * A talloc pool is a pure optimization for specific situations. In the + * release process for Samba 3.2 we found out that we had become considerably + * slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU + * consumer in benchmarks. For Samba 3.2 we have internally converted many + * static buffers to dynamically allocated ones, so malloc(3) being beaten + * more was no surprise. But it made us slower. + * + * talloc_pool() is an optimization to call malloc(3) a lot less for the use + * pattern Samba has: The SMB protocol is mainly a request/response protocol + * where we have to allocate a certain amount of memory per request and free + * that after the SMB reply is sent to the client. + * + * talloc_pool() creates a talloc chunk that you can use as a talloc parent + * exactly as you would use any other ::TALLOC_CTX. The difference is that + * when you talloc a child of this pool, no malloc(3) is done. Instead, talloc + * just increments a pointer inside the talloc_pool. This also works + * recursively. If you use the child of the talloc pool as a parent for + * grand-children, their memory is also taken from the talloc pool. + * + * If you talloc_free() children of a talloc pool, the memory is not given + * back to the system. Instead, free(3) is only called if the talloc_pool() + * itself is released with talloc_free(). + * + * The downside of a talloc pool is that if you talloc_move() a child of a + * talloc pool to a talloc parent outside the pool, the whole pool memory is + * not free(3)'ed until that moved chunk is also talloc_free()ed. + */ void *talloc_pool(const void *context, size_t size); void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); -- cgit From 02662d56c64f367bffa2febba9a396c15454cfdb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 20:02:19 +0100 Subject: Add a talloc_internal "module" --- lib/talloc/talloc.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index e44d924e76..f3aa6def63 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -124,6 +124,15 @@ * allocated memory hierarchy. */ +/** + * \defgroup talloc_internal Internal routines + * + * To achieve type-safety, talloc.h defines a lot of macros with type + * casts. These macros define the user interface to the internal routines you + * find here. You should not really use these routines directly but go through + * the external API. + */ + /** * \defgroup talloc_undoc Default group of undocumented stuff * -- cgit From 2ce70d4f5a30973b4cc083dbbb38b519007a31bd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 20:02:42 +0100 Subject: Document _talloc --- lib/talloc/talloc.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index f3aa6def63..01e7326ccc 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -635,7 +635,16 @@ typedef void TALLOC_CTX; #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) -/* The following definitions come from talloc.c */ +/** + * \brief Allocate untyped, unnamed memory + * \param context The talloc context to hang the result off + * \param size Number of char's that you want to allocate + * \return The allocated memory chunk + * \ingroup talloc_internal + * + * Essentially the same as talloc_size() without setting the chunk name to the + * current file/line number. + */ void *_talloc(const void *context, size_t size); /** -- cgit From 3f81649b8dcadb3bd424f41d803dbd59f770b9ba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 20:02:50 +0100 Subject: Document TALLOC_FREE() --- lib/talloc/talloc.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 01e7326ccc..d103d6f4f2 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -633,6 +633,16 @@ typedef void TALLOC_CTX; #define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) #endif +/** + * \def TALLOC_FREE(ctx) + * \brief talloc_free a chunk and NULL out the pointer + * \param ctx The chunk to be freed + * \ingroup talloc_basic + * + * TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want + * immediate feedback (i.e. crash) if you use a pointer after having free'ed + * it. + */ #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) /** -- cgit From 986c2e01cca0be993f1e52d3a27819f4044bfe4b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 23:49:30 +0100 Subject: Document talloc_parent, talloc_parent_name and talloc_is_parent --- lib/talloc/talloc.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index d103d6f4f2..9806bdd3ad 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -849,7 +849,25 @@ const char *talloc_get_name(const void *ptr); void *talloc_check_name(const void *ptr, const char *name); void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); + +/** + * \brief Return the parent chunk of a pointer + * \param ptr The talloc pointer to inspect + * \return The talloc parent of "ptr" + * \ingroup talloc_basic + * + * Return the parent chunk of a pointer + */ void *talloc_parent(const void *ptr); + +/** + * \brief Return a talloc chunk's parent name + * \param ptr The talloc pointer to inspect + * \return The name of ptr's parent chunk + * \ingroup talloc_basic + * + * Return a talloc chunk's parent name + */ const char *talloc_parent_name(const void *ptr); /** @@ -1149,6 +1167,17 @@ size_t talloc_get_size(const void *ctx); */ void *talloc_find_parent_byname(const void *ctx, const char *name); void talloc_show_parents(const void *context, FILE *file); + +/** + * \brief Check if a context is parent of a talloc chunk + * \param context The assumed talloc context + * \param ptr The talloc chunk to check + * \return Is context an anchestor of ptr + * \ingroup talloc_basic + * + * talloc_is_parent() checks if context is referenced in the talloc + * hierarchy above ptr. Return 1 if this is the case, 0 if not. + */ int talloc_is_parent(const void *context, const void *ptr); /** -- cgit From 59dff5745528a3efe585cdeb03e2bedd6b2e404a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Mar 2009 23:57:14 +0100 Subject: Document talloc_zero_array() --- lib/talloc/talloc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 9806bdd3ad..ae488baf32 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -426,6 +426,22 @@ typedef void TALLOC_CTX; #define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) +/** + * \def talloc_zero_array(ctx, type, count) + * \brief Allocate a 0-initialized array + * \param ctx The talloc context to hang the result off + * \param type The type that we want to allocate + * \param count The number of "type" elements you want to allocate + * \return The allocated result, properly cast to "type *" + * \ingroup talloc_array + * + * The talloc_zero_array() macro is equivalent to: + * + * \code + * ptr = talloc_array(ctx, type, count); + * if (ptr) memset(ptr, sizeof(type) * count); + * \endcode + */ #define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) /** -- cgit From 257ea7e6f10ab4eda4efae0d6ad0cdc2bd49ffd8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:47:37 +0100 Subject: Revert "Document talloc_zero_array()" This reverts commit 59dff5745528a3efe585cdeb03e2bedd6b2e404a. --- lib/talloc/talloc.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index ae488baf32..9806bdd3ad 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -426,22 +426,6 @@ typedef void TALLOC_CTX; #define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) -/** - * \def talloc_zero_array(ctx, type, count) - * \brief Allocate a 0-initialized array - * \param ctx The talloc context to hang the result off - * \param type The type that we want to allocate - * \param count The number of "type" elements you want to allocate - * \return The allocated result, properly cast to "type *" - * \ingroup talloc_array - * - * The talloc_zero_array() macro is equivalent to: - * - * \code - * ptr = talloc_array(ctx, type, count); - * if (ptr) memset(ptr, sizeof(type) * count); - * \endcode - */ #define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) /** -- cgit From c086c26ffba72f27530d93ca4a7ad315203f7194 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:47:44 +0100 Subject: Revert "Document talloc_parent, talloc_parent_name and talloc_is_parent" This reverts commit 986c2e01cca0be993f1e52d3a27819f4044bfe4b. --- lib/talloc/talloc.h | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 9806bdd3ad..d103d6f4f2 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -849,25 +849,7 @@ const char *talloc_get_name(const void *ptr); void *talloc_check_name(const void *ptr, const char *name); void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); - -/** - * \brief Return the parent chunk of a pointer - * \param ptr The talloc pointer to inspect - * \return The talloc parent of "ptr" - * \ingroup talloc_basic - * - * Return the parent chunk of a pointer - */ void *talloc_parent(const void *ptr); - -/** - * \brief Return a talloc chunk's parent name - * \param ptr The talloc pointer to inspect - * \return The name of ptr's parent chunk - * \ingroup talloc_basic - * - * Return a talloc chunk's parent name - */ const char *talloc_parent_name(const void *ptr); /** @@ -1167,17 +1149,6 @@ size_t talloc_get_size(const void *ctx); */ void *talloc_find_parent_byname(const void *ctx, const char *name); void talloc_show_parents(const void *context, FILE *file); - -/** - * \brief Check if a context is parent of a talloc chunk - * \param context The assumed talloc context - * \param ptr The talloc chunk to check - * \return Is context an anchestor of ptr - * \ingroup talloc_basic - * - * talloc_is_parent() checks if context is referenced in the talloc - * hierarchy above ptr. Return 1 if this is the case, 0 if not. - */ int talloc_is_parent(const void *context, const void *ptr); /** -- cgit From f15a0305f3982a9bc54aac0690e25a52f1021bb2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:47:51 +0100 Subject: Revert "Document TALLOC_FREE()" This reverts commit 3f81649b8dcadb3bd424f41d803dbd59f770b9ba. --- lib/talloc/talloc.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index d103d6f4f2..01e7326ccc 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -633,16 +633,6 @@ typedef void TALLOC_CTX; #define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) #endif -/** - * \def TALLOC_FREE(ctx) - * \brief talloc_free a chunk and NULL out the pointer - * \param ctx The chunk to be freed - * \ingroup talloc_basic - * - * TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want - * immediate feedback (i.e. crash) if you use a pointer after having free'ed - * it. - */ #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) /** -- cgit From cce595d1fcaa84d09ae9e261b5e20da03ca38137 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:47:59 +0100 Subject: Revert "Document _talloc" This reverts commit 2ce70d4f5a30973b4cc083dbbb38b519007a31bd. --- lib/talloc/talloc.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 01e7326ccc..f3aa6def63 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -635,16 +635,7 @@ typedef void TALLOC_CTX; #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) -/** - * \brief Allocate untyped, unnamed memory - * \param context The talloc context to hang the result off - * \param size Number of char's that you want to allocate - * \return The allocated memory chunk - * \ingroup talloc_internal - * - * Essentially the same as talloc_size() without setting the chunk name to the - * current file/line number. - */ +/* The following definitions come from talloc.c */ void *_talloc(const void *context, size_t size); /** -- cgit From 6b1a5bbf02dfdb847a5481d1b4b37deb0e0f09a5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:06 +0100 Subject: Revert "Add a talloc_internal "module"" This reverts commit 02662d56c64f367bffa2febba9a396c15454cfdb. --- lib/talloc/talloc.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index f3aa6def63..e44d924e76 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -124,15 +124,6 @@ * allocated memory hierarchy. */ -/** - * \defgroup talloc_internal Internal routines - * - * To achieve type-safety, talloc.h defines a lot of macros with type - * casts. These macros define the user interface to the internal routines you - * find here. You should not really use these routines directly but go through - * the external API. - */ - /** * \defgroup talloc_undoc Default group of undocumented stuff * -- cgit From c67ea37d62692e5e21f76135ecdfa0d369bed0eb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:14 +0100 Subject: Revert "Document talloc_pool()" This reverts commit 27944ed7452207ef3c686ff6bcd9c4e1cb7f36d8. --- lib/talloc/talloc.h | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index e44d924e76..4adc67b7fd 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -628,41 +628,6 @@ typedef void TALLOC_CTX; /* The following definitions come from talloc.c */ void *_talloc(const void *context, size_t size); - -/** - * \brief Allocate a talloc pool - * \param context The talloc context to hang the result off - * \param size Size of the talloc pool - * \result The talloc pool - * \ingroup talloc_basic - * - * A talloc pool is a pure optimization for specific situations. In the - * release process for Samba 3.2 we found out that we had become considerably - * slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU - * consumer in benchmarks. For Samba 3.2 we have internally converted many - * static buffers to dynamically allocated ones, so malloc(3) being beaten - * more was no surprise. But it made us slower. - * - * talloc_pool() is an optimization to call malloc(3) a lot less for the use - * pattern Samba has: The SMB protocol is mainly a request/response protocol - * where we have to allocate a certain amount of memory per request and free - * that after the SMB reply is sent to the client. - * - * talloc_pool() creates a talloc chunk that you can use as a talloc parent - * exactly as you would use any other ::TALLOC_CTX. The difference is that - * when you talloc a child of this pool, no malloc(3) is done. Instead, talloc - * just increments a pointer inside the talloc_pool. This also works - * recursively. If you use the child of the talloc pool as a parent for - * grand-children, their memory is also taken from the talloc pool. - * - * If you talloc_free() children of a talloc pool, the memory is not given - * back to the system. Instead, free(3) is only called if the talloc_pool() - * itself is released with talloc_free(). - * - * The downside of a talloc pool is that if you talloc_move() a child of a - * talloc pool to a talloc parent outside the pool, the whole pool memory is - * not free(3)'ed until that moved chunk is also talloc_free()ed. - */ void *talloc_pool(const void *context, size_t size); void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); -- cgit From 5098f4625e74eb4b37b6f7fdfa0486df7e1d7cf4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:19 +0100 Subject: Revert "Reformatting" This reverts commit db447d0c476699dbf7fa0567c67f5938674ec811. --- lib/talloc/talloc.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 4adc67b7fd..d0a9762f4d 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -99,33 +99,28 @@ * programming. */ -/** - * \defgroup talloc_ref Talloc References +/** \defgroup talloc_ref Talloc References * * This module contains the definitions around talloc references */ -/** - * \defgroup talloc_array Array routines +/** \defgroup talloc_array Array routines * * Talloc contains some handy helpers for handling Arrays conveniently */ -/** - * \defgroup talloc_string String handling routines +/** \defgroup talloc_string String handling routines * * Talloc contains some handy string handling functions */ -/** - * \defgroup talloc_debug Debugging support routines +/** \defgroup talloc_debug Debugging support routines * * To aid memory debugging, talloc contains routines to inspect the currently * allocated memory hierarchy. */ -/** - * \defgroup talloc_undoc Default group of undocumented stuff +/** \defgroup todo Default group of undocumented stuff * * This should be empty... */ -- cgit From 790326cc38a9453aea3ad7e5a3f7384bfdd58e84 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:27 +0100 Subject: Revert "Add some initial hook to the front page" This reverts commit cfce2d3611f225244fadf3d27d76371827fd6422. --- lib/talloc/talloc.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index d0a9762f4d..523a4840d3 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -56,9 +56,6 @@ * If you think about this, then what this effectively gives you is an n-ary * tree, where you can free any part of the tree with talloc_free(). * - * To start, you should probably first look at the definitions of - * ::TALLOC_CTX, talloc_init(), talloc() and talloc_free(). - * * \section named_blocks Named blocks * * Every talloc chunk has a name that can be used as a dynamic type-checking -- cgit From b7fb083dd775c625882163f140e7e5ca550ebec7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:34 +0100 Subject: Revert "Add a default "undocumented" module" This reverts commit ba42320c7e9f5ccbd32eccbfb1f2d77e13b3a318. --- lib/talloc/talloc.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 523a4840d3..4b50ba99c2 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -117,13 +117,6 @@ * allocated memory hierarchy. */ -/** \defgroup todo Default group of undocumented stuff - * - * This should be empty... - */ - -/*\{*/ - /** * \typedef TALLOC_CTX * \brief Define a talloc parent type @@ -1217,5 +1210,3 @@ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIB void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); #endif - -/*\}*/ -- cgit From c3df04069940ab29f52763dc56f2ded98a4a72a6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:41 +0100 Subject: Revert "Delete talloc_guide.txt" This reverts commit 3f9c30022a53a37ad829f8882a9a5161fcadda8b. --- lib/talloc/talloc_guide.txt | 694 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 694 insertions(+) create mode 100644 lib/talloc/talloc_guide.txt diff --git a/lib/talloc/talloc_guide.txt b/lib/talloc/talloc_guide.txt new file mode 100644 index 0000000000..3201fe6f0f --- /dev/null +++ b/lib/talloc/talloc_guide.txt @@ -0,0 +1,694 @@ +Using talloc in Samba4 +====================== + +.. contents:: + +Andrew Tridgell +September 2004 + +The most current version of this document is available at + http://samba.org/ftp/unpacked/samba4/source/lib/talloc/talloc_guide.txt + +If you are used to the "old" talloc from Samba3 before 3.0.20 then please read +this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the +Samba4 talloc has been ported back to Samba3, so this guide applies to both. + +The new talloc is a hierarchical, reference counted memory pool system +with destructors. Quite a mouthful really, but not too bad once you +get used to it. + +Perhaps the biggest change from Samba3 is that there is no distinction +between a "talloc context" and a "talloc pointer". Any pointer +returned from talloc() is itself a valid talloc context. This means +you can do this:: + + struct foo *X = talloc(mem_ctx, struct foo); + X->name = talloc_strdup(X, "foo"); + +and the pointer X->name would be a "child" of the talloc context "X" +which is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) +then it is all destroyed, whereas if you do talloc_free(X) then just X +and X->name are destroyed, and if you do talloc_free(X->name) then +just the name element of X is destroyed. + +If you think about this, then what this effectively gives you is an +n-ary tree, where you can free any part of the tree with +talloc_free(). + +If you find this confusing, then I suggest you run the testsuite to +watch talloc in action. You may also like to add your own tests to +testsuite.c to clarify how some particular situation is handled. + + +Performance +----------- + +All the additional features of talloc() over malloc() do come at a +price. We have a simple performance test in Samba4 that measures +talloc() versus malloc() performance, and it seems that talloc() is +about 4% slower than malloc() on my x86 Debian Linux box. For Samba, +the great reduction in code complexity that we get by using talloc +makes this worthwhile, especially as the total overhead of +talloc/malloc in Samba is already quite small. + + +talloc API +---------- + +The following is a complete guide to the talloc API. Read it all at +least twice. + +Multi-threading +--------------- + +talloc itself does not deal with threads. It is thread-safe (assuming +the underlying "malloc" is), as long as each thread uses different +memory contexts. +If two threads uses the same context then they need to synchronize in +order to be safe. In particular: +- when using talloc_enable_leak_report(), giving directly NULL as a +parent context implicitly refers to a hidden "null context" global +variable, so this should not be used in a multi-threaded environment +without proper synchronization ; +- the context returned by talloc_autofree_context() is also global so +shouldn't be used by several threads simultaneously without +synchronization. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc(const void *context, type); + +The talloc() macro is the core of the talloc library. It takes a +memory context and a type, and returns a pointer to a new area of +memory of the given type. + +The returned pointer is itself a talloc context, so you can use it as +the context argument to more calls to talloc if you wish. + +The returned pointer is a "child" of the supplied context. This means +that if you talloc_free() the context then the new child disappears as +well. Alternatively you can free just the child. + +The context argument to talloc() can be NULL, in which case a new top +level context is created. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_size(const void *context, size_t size); + +The function talloc_size() should be used when you don't have a +convenient type to pass to talloc(). Unlike talloc(), it is not type +safe (as it returns a void *), so you are on your own for type checking. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); + +The talloc_ptrtype() macro should be used when you have a pointer and +want to allocate memory to point at with this pointer. When compiling +with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() +and talloc_get_name() will return the current location in the source file. +and not the type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_free(void *ptr); + +The talloc_free() function frees a piece of talloc memory, and all its +children. You can call talloc_free() on any pointer returned by +talloc(). + +The return value of talloc_free() indicates success or failure, with 0 +returned for success and -1 for failure. The only possible failure +condition is if the pointer had a destructor attached to it and the +destructor returned -1. See talloc_set_destructor() for details on +destructors. + +If this pointer has an additional parent when talloc_free() is called +then the memory is not actually released, but instead the most +recently established parent is destroyed. See talloc_reference() for +details on establishing additional parents. + +For more control on which parent is removed, see talloc_unlink() + +talloc_free() operates recursively on its children. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_free_children(void *ptr); + +The talloc_free_children() walks along the list of all children of a +talloc context and talloc_free()s only the children, not the context +itself. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_reference(const void *context, const void *ptr); + +The talloc_reference() function makes "context" an additional parent +of "ptr". + +The return value of talloc_reference() is always the original pointer +"ptr", unless talloc ran out of memory in creating the reference in +which case it will return NULL (each additional reference consumes +around 48 bytes of memory on intel x86 platforms). + +If "ptr" is NULL, then the function is a no-op, and simply returns NULL. + +After creating a reference you can free it in one of the following +ways: + + - you can talloc_free() any parent of the original pointer. That + will reduce the number of parents of this pointer by 1, and will + cause this pointer to be freed if it runs out of parents. + + - you can talloc_free() the pointer itself. That will destroy the + most recently established parent to the pointer and leave the + pointer as a child of its current parent. + +For more control on which parent to remove, see talloc_unlink() + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_unlink(const void *context, const void *ptr); + +The talloc_unlink() function removes a specific parent from ptr. The +context passed must either be a context used in talloc_reference() +with this pointer, or must be a direct parent of ptr. + +Note that if the parent has already been removed using talloc_free() +then this function will fail and will return -1. Likewise, if "ptr" +is NULL, then the function will make no modifications and return -1. + +Usually you can just use talloc_free() instead of talloc_unlink(), but +sometimes it is useful to have the additional control on which parent +is removed. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + +The function talloc_set_destructor() sets the "destructor" for the +pointer "ptr". A destructor is a function that is called when the +memory used by a pointer is about to be released. The destructor +receives the pointer as an argument, and should return 0 for success +and -1 for failure. + +The destructor can do anything it wants to, including freeing other +pieces of memory. A common use for destructors is to clean up +operating system resources (such as open file descriptors) contained +in the structure the destructor is placed on. + +You can only place one destructor on a pointer. If you need more than +one destructor then you can create a zero-length child of the pointer +and place an additional destructor on that. + +To remove a destructor call talloc_set_destructor() with NULL for the +destructor. + +If your destructor attempts to talloc_free() the pointer that it is +the destructor for then talloc_free() will return -1 and the free will +be ignored. This would be a pointless operation anyway, as the +destructor is only called when the memory is just about to go away. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_increase_ref_count(const void *ptr); + +The talloc_increase_ref_count(ptr) function is exactly equivalent to: + + talloc_reference(NULL, ptr); + +You can use either syntax, depending on which you think is clearer in +your code. + +It returns 0 on success and -1 on failure. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_reference_count(const void *ptr); + +Return the number of references to the pointer. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_name(const void *ptr, const char *fmt, ...); + +Each talloc pointer has a "name". The name is used principally for +debugging purposes, although it is also possible to set and get the +name on a pointer in as a way of "marking" pointers in your code. + +The main use for names on pointer is for "talloc reports". See +talloc_report() and talloc_report_full() for details. Also see +talloc_enable_leak_report() and talloc_enable_leak_report_full(). + +The talloc_set_name() function allocates memory as a child of the +pointer. It is logically equivalent to: + talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + +Note that multiple calls to talloc_set_name() will allocate more +memory without releasing the name. All of the memory is released when +the ptr is freed using talloc_free(). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_name_const(const void *ptr, const char *name); + +The function talloc_set_name_const() is just like talloc_set_name(), +but it takes a string constant, and is much faster. It is extensively +used by the "auto naming" macros, such as talloc_p(). + +This function does not allocate any memory. It just copies the +supplied pointer into the internal representation of the talloc +ptr. This means you must not pass a name pointer to memory that will +disappear before the ptr is freed with talloc_free(). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_named(const void *context, size_t size, const char *fmt, ...); + +The talloc_named() function creates a named talloc pointer. It is +equivalent to: + + ptr = talloc_size(context, size); + talloc_set_name(ptr, fmt, ....); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_named_const(const void *context, size_t size, const char *name); + +This is equivalent to:: + + ptr = talloc_size(context, size); + talloc_set_name_const(ptr, name); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +const char *talloc_get_name(const void *ptr); + +This returns the current name for the given talloc pointer. See +talloc_set_name() for details. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_init(const char *fmt, ...); + +This function creates a zero length named talloc context as a top +level context. It is equivalent to:: + + talloc_named(NULL, 0, fmt, ...); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_new(void *ctx); + +This is a utility macro that creates a new memory context hanging +off an exiting context, automatically naming it "talloc_new: __location__" +where __location__ is the source line it is called from. It is +particularly useful for creating a new temporary working context. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_realloc(const void *context, void *ptr, type, count); + +The talloc_realloc() macro changes the size of a talloc +pointer. The "count" argument is the number of elements of type "type" +that you want the resulting pointer to hold. + +talloc_realloc() has the following equivalences:: + + talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); + talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); + talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); + +The "context" argument is only used if "ptr" is NULL, otherwise it is +ignored. + +talloc_realloc() returns the new pointer, or NULL on failure. The call +will fail either due to a lack of memory, or because the pointer has +more than one parent (see talloc_reference()). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_realloc_size(const void *context, void *ptr, size_t size); + +the talloc_realloc_size() function is useful when the type is not +known so the typesafe talloc_realloc() cannot be used. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_steal(const void *new_ctx, const void *ptr); + +The talloc_steal() function changes the parent context of a talloc +pointer. It is typically used when the context that the pointer is +currently a child of is going to be freed and you wish to keep the +memory for a longer time. + +The talloc_steal() function returns the pointer that you pass it. It +does not have any failure modes. + +NOTE: It is possible to produce loops in the parent/child relationship +if you are not careful with talloc_steal(). No guarantees are provided +as to your sanity or the safety of your data if you do this. + +talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_total_size(const void *ptr); + +The talloc_total_size() function returns the total size in bytes used +by this pointer and all child pointers. Mostly useful for debugging. + +Passing NULL is allowed, but it will only give a meaningful result if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_total_blocks(const void *ptr); + +The talloc_total_blocks() function returns the total memory block +count used by this pointer and all child pointers. Mostly useful for +debugging. + +Passing NULL is allowed, but it will only give a meaningful result if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *priv), + void *priv); + +This provides a more flexible reports than talloc_report(). It +will recursively call the callback for the entire tree of memory +referenced by the pointer. References in the tree are passed with +is_ref = 1 and the pointer that is referenced. + +You can pass NULL for the pointer, in which case a report is +printed for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() +has been called. + +The recursion is stopped when depth >= max_depth. +max_depth = -1 means only stop at leaf nodes. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); + +This provides a more flexible reports than talloc_report(). It +will let you specify the depth and max_depth. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report(const void *ptr, FILE *f); + +The talloc_report() function prints a summary report of all memory +used by ptr. One line of report is printed for each immediate child of +ptr, showing the total memory and number of blocks used by that child. + +You can pass NULL for the pointer, in which case a report is printed +for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_full(const void *ptr, FILE *f); + +This provides a more detailed report than talloc_report(). It will +recursively print the ensire tree of memory referenced by the +pointer. References in the tree are shown by giving the name of the +pointer that is referenced. + +You can pass NULL for the pointer, in which case a report is printed +for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_leak_report(void); + +This enables calling of talloc_report(NULL, stderr) when the program +exits. In Samba4 this is enabled by using the --leak-report command +line option. + +For it to be useful, this function must be called before any other +talloc function as it establishes a "null context" that acts as the +top of the tree. If you don't call this function first then passing +NULL to talloc_report() or talloc_report_full() won't give you the +full tree printout. + +Here is a typical talloc report: + +talloc report on 'null_context' (total 267 bytes in 15 blocks) + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(UTF8,CP850) contains 42 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(CP850,UTF8) contains 42 bytes in 2 blocks + iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks + iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_leak_report_full(void); + +This enables calling of talloc_report_full(NULL, stderr) when the +program exits. In Samba4 this is enabled by using the +--leak-report-full command line option. + +For it to be useful, this function must be called before any other +talloc function as it establishes a "null context" that acts as the +top of the tree. If you don't call this function first then passing +NULL to talloc_report() or talloc_report_full() won't give you the +full tree printout. + +Here is a typical full report: + +full talloc report on 'root' (total 18 bytes in 8 blocks) + p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_null_tracking(void); + +This enables tracking of the NULL memory context without enabling leak +reporting on exit. Useful for when you want to do your own leak +reporting call via talloc_report_null_full(); + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_disable_null_tracking(void); + +This disables tracking of the NULL memory context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_zero(const void *ctx, type); + +The talloc_zero() macro is equivalent to:: + + ptr = talloc(ctx, type); + if (ptr) memset(ptr, 0, sizeof(type)); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_zero_size(const void *ctx, size_t size) + +The talloc_zero_size() function is useful when you don't have a known type + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_memdup(const void *ctx, const void *p, size_t size); + +The talloc_memdup() function is equivalent to:: + + ptr = talloc_size(ctx, size); + if (ptr) memcpy(ptr, p, size); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_strdup(const void *ctx, const char *p); + +The talloc_strdup() function is equivalent to:: + + ptr = talloc_size(ctx, strlen(p)+1); + if (ptr) memcpy(ptr, p, strlen(p)+1); + +This functions sets the name of the new pointer to the passed +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_strndup(const void *t, const char *p, size_t n); + +The talloc_strndup() function is the talloc equivalent of the C +library function strndup() + +This functions sets the name of the new pointer to the passed +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_append_string(const void *t, char *orig, const char *append); + +The talloc_append_string() function appends the given formatted +string to the given string. + +This function sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); + +The talloc_vasprintf() function is the talloc equivalent of the C +library function vasprintf() + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf(const void *t, const char *fmt, ...); + +The talloc_asprintf() function is the talloc equivalent of the C +library function asprintf() + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append(char *s, const char *fmt, ...); + +The talloc_asprintf_append() function appends the given formatted +string to the given string. +Use this varient when the string in the current talloc buffer may +have been truncated in length. + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); + +The talloc_asprintf_append() function appends the given formatted +string to the end of the currently allocated talloc buffer. +Use this varient when the string in the current talloc buffer has +not been changed. + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +((type *)talloc_array(const void *ctx, type, uint_t count); + +The talloc_array() macro is equivalent to:: + + (type *)talloc_size(ctx, sizeof(type) * count); + +except that it provides integer overflow protection for the multiply, +returning NULL if the multiply overflows. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_array_size(const void *ctx, size_t size, uint_t count); + +The talloc_array_size() function is useful when the type is not +known. It operates in the same way as talloc_array(), but takes a size +instead of a type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count); + +The talloc_ptrtype() macro should be used when you have a pointer to an array +and want to allocate memory of an array to point at with this pointer. When compiling +with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() +and talloc_get_name() will return the current location in the source file. +and not the type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); + +This is a non-macro version of talloc_realloc(), which is useful +as libraries sometimes want a ralloc function pointer. A realloc() +implementation encapsulates the functionality of malloc(), free() and +realloc() in one call, which is why it is useful to be able to pass +around a single function pointer. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_autofree_context(void); + +This is a handy utility function that returns a talloc context +which will be automatically freed on program exit. This can be used +to reduce the noise in memory leak reports. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_check_name(const void *ptr, const char *name); + +This function checks if a pointer has the specified name. If it does +then the pointer is returned. It it doesn't then NULL is returned. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_get_type(const void *ptr, type); + +This macro allows you to do type checking on talloc pointers. It is +particularly useful for void* private pointers. It is equivalent to +this:: + + (type *)talloc_check_name(ptr, #type) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +talloc_set_type(const void *ptr, type); + +This macro allows you to force the name of a pointer to be a +particular type. This can be used in conjunction with +talloc_get_type() to do type checking on void* pointers. + +It is equivalent to this:: + + talloc_set_name_const(ptr, #type) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +talloc_get_size(const void *ctx); + +This function lets you know the amount of memory alloced so far by +this context. It does NOT account for subcontext memory. +This can be used to calculate the size of an array. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_find_parent_byname(const void *ctx, const char *name); + +Find a parent memory context of the current context that has the given +name. This can be very useful in complex programs where it may be +difficult to pass all information down to the level you need, but you +know the structure you want is a parent of another context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_find_parent_bytype(ctx, type); + +Like talloc_find_parent_byname() but takes a type, making it typesafe. + -- cgit From a83c18062ae04942ceff757534ba251b045ad04c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:48 +0100 Subject: Revert "Convert the contents of talloc_guide.txt to doxygen-style talloc.h comments" This reverts commit d21212c9192b41a3fdc7e96cb9bf0125a1dc6c2d. --- lib/talloc/talloc.h | 1024 +-------------------------------------------------- 1 file changed, 1 insertion(+), 1023 deletions(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 4b50ba99c2..5c8d5c5fe2 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -29,119 +29,7 @@ #include #include -/** \mainpage - * - * \section intro_sec Introduction - * - * Talloc is a hierarchical, reference counted memory pool system with - * destructors. Quite a mouthful really, but not too bad once you get used to - * it. - * - * Perhaps the biggest difference from other memory pool systems is that there - * is no distinction between a "talloc context" and a "talloc pointer". Any - * pointer returned from talloc() is itself a valid talloc context. This means - * you can do this: - * - * \code - * struct foo *X = talloc(mem_ctx, struct foo); - * X->name = talloc_strdup(X, "foo"); - * \endcode - * - * and the pointer X->name would be a "child" of the talloc context "X" which - * is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) then it is - * all destroyed, whereas if you do talloc_free(X) then just X and X->name are - * destroyed, and if you do talloc_free(X->name) then just the name element of - * X is destroyed. - * - * If you think about this, then what this effectively gives you is an n-ary - * tree, where you can free any part of the tree with talloc_free(). - * - * \section named_blocks Named blocks - * - * Every talloc chunk has a name that can be used as a dynamic type-checking - * system. If for some reason like a callback function you had to cast a - * "struct foo *" to a "void *" variable, later you can safely reassign the - * "void *" pointer to a "struct foo *" by using the talloc_get_type() or - * talloc_get_type_abort() macros. - * - * \code - * struct foo *X = talloc_get_type_abort(ptr, struct foo); - * \endcode - * - * This will abort if "ptr" does not contain a pointer that has been created - * with talloc(mem_ctx, struct foo). - * - * \section multi_threading Multi-Threading - * - * talloc itself does not deal with threads. It is thread-safe (assuming the - * underlying "malloc" is), as long as each thread uses different memory - * contexts. - * - * If two threads uses the same context then they need to synchronize in order - * to be safe. In particular: - * - * - * - when using talloc_enable_leak_report(), giving directly NULL as a - * parent context implicitly refers to a hidden "null context" global - * variable, so this should not be used in a multi-threaded environment - * without proper synchronization - * - the context returned by talloc_autofree_context() is also global so - * shouldn't be used by several threads simultaneously without - * synchronization. - */ - -/** \defgroup talloc_basic Basic Talloc Routines - * - * This module contains the basic talloc routines that are used in everyday - * programming. - */ - -/** \defgroup talloc_ref Talloc References - * - * This module contains the definitions around talloc references - */ - -/** \defgroup talloc_array Array routines - * - * Talloc contains some handy helpers for handling Arrays conveniently - */ - -/** \defgroup talloc_string String handling routines - * - * Talloc contains some handy string handling functions - */ - -/** \defgroup talloc_debug Debugging support routines - * - * To aid memory debugging, talloc contains routines to inspect the currently - * allocated memory hierarchy. - */ - -/** - * \typedef TALLOC_CTX - * \brief Define a talloc parent type - * \ingroup talloc_basic - * - * As talloc is a hierarchial memory allocator, every talloc chunk is a - * potential parent to other talloc chunks. So defining a separate type for a - * talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless, - * as it provides an indicator for function arguments. You will frequently - * write code like - * - * \code - * struct foo *foo_create(TALLOC_CTX *mem_ctx) - * { - * struct foo *result; - * result = talloc(mem_ctx, struct foo); - * if (result == NULL) return NULL; - * ... initialize foo ... - * return result; - * } - * \endcode - * - * In this type of allocating functions it is handy to have a general - * TALLOC_CTX type to indicate which parent to put allocated structures on. - */ +/* this is only needed for compatibility with the old talloc */ typedef void TALLOC_CTX; /* @@ -170,62 +58,6 @@ typedef void TALLOC_CTX; #endif #endif -/** - * \def talloc_set_destructor - * \brief Assign a function to be called when a chunk is freed - * \param ptr The talloc chunk to add a destructor to - * \param function The destructor function to be called - * \ingroup talloc_basic - * - * The function talloc_set_destructor() sets the "destructor" for the pointer - * "ptr". A destructor is a function that is called when the memory used by a - * pointer is about to be released. The destructor receives the pointer as an - * argument, and should return 0 for success and -1 for failure. - * - * The destructor can do anything it wants to, including freeing other pieces - * of memory. A common use for destructors is to clean up operating system - * resources (such as open file descriptors) contained in the structure the - * destructor is placed on. - * - * You can only place one destructor on a pointer. If you need more than one - * destructor then you can create a zero-length child of the pointer and place - * an additional destructor on that. - * - * To remove a destructor call talloc_set_destructor() with NULL for the - * destructor. - * - * If your destructor attempts to talloc_free() the pointer that it is the - * destructor for then talloc_free() will return -1 and the free will be - * ignored. This would be a pointless operation anyway, as the destructor is - * only called when the memory is just about to go away. - */ - -/** - * \def talloc_steal(ctx, ptr) - * \brief Change a talloc chunk's parent - * \param ctx The new parent context - * \param ptr The talloc chunk to move - * \return ptr - * \ingroup talloc_basic - * - * The talloc_steal() function changes the parent context of a talloc - * pointer. It is typically used when the context that the pointer is - * currently a child of is going to be freed and you wish to keep the - * memory for a longer time. - * - * The talloc_steal() function returns the pointer that you pass it. It - * does not have any failure modes. - * - * NOTE: It is possible to produce loops in the parent/child relationship - * if you are not careful with talloc_steal(). No guarantees are provided - * as to your sanity or the safety of your data if you do this. - * - * To make the changed hierarchy less error-prone, you might consider to use - * talloc_move(). - * - * talloc_steal (ctx, NULL) will return NULL with no sideeffects. - */ - /* try to make talloc_set_destructor() and talloc_steal() type safe, if we have a recent gcc */ #if (__GNUC__ >= 3) @@ -245,359 +77,34 @@ typedef void TALLOC_CTX; #define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)) #endif -/** - * \def talloc_reference(ctx, ptr) - * \brief Create an additional talloc parent to a pointer - * \param ctx The additional parent - * \param ptr The pointer you want to create an additional parent for - * \return ptr - * \ingroup talloc_ref - * - * The talloc_reference() function makes "context" an additional parent of - * "ptr". - * - * The return value of talloc_reference() is always the original pointer - * "ptr", unless talloc ran out of memory in creating the reference in which - * case it will return NULL (each additional reference consumes around 48 - * bytes of memory on intel x86 platforms). - * - * If "ptr" is NULL, then the function is a no-op, and simply returns NULL. - * - * After creating a reference you can free it in one of the following ways: - * - * - you can talloc_free() any parent of the original pointer. That - * will reduce the number of parents of this pointer by 1, and will - * cause this pointer to be freed if it runs out of parents. - * - * - you can talloc_free() the pointer itself. That will destroy the - * most recently established parent to the pointer and leave the - * pointer as a child of its current parent. - * - * For more control on which parent to remove, see talloc_unlink() - */ #define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr)) - - -/** - * \def talloc_move(ctx, ptr) - * \brief Change a talloc chunk's parent - * \param ctx The new parent context - * \param ptr Pointer to the talloc chunk to move - * \return ptr - * \ingroup talloc_basic - * - * talloc_move() has the same effect as talloc_steal(), and additionally sets - * the source pointer to NULL. You would use it like this: - * - * \code - * struct foo *X = talloc(tmp_ctx, struct foo); - * struct foo *Y; - * Y = talloc_move(new_ctx, &X); - * \endcode - */ #define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr)) /* useful macros for creating type checked pointers */ - -/** - * \def talloc(ctx, type) - * \brief Main entry point to allocate structures - * \param ctx The talloc context to hang the result off - * \param type The type that we want to allocate - * \return Pointer to a piece of memory, properly cast to "type *" - * \ingroup talloc_basic - * - * The talloc() macro is the core of the talloc library. It takes a memory - * context and a type, and returns a pointer to a new area of memory of the - * given type. - * - * The returned pointer is itself a talloc context, so you can use it as the - * context argument to more calls to talloc if you wish. - * - * The returned pointer is a "child" of the supplied context. This means that - * if you talloc_free() the context then the new child disappears as - * well. Alternatively you can free just the child. - * - * The context argument to talloc() can be NULL, in which case a new top - * level context is created. - */ #define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) - -/** - * \def talloc_size(ctx, size) - * \brief Untyped allocation - * \param ctx The talloc context to hang the result off - * \param size Number of char's that you want to allocate - * \return The allocated memory chunk - * \ingroup talloc_basic - * - * The function talloc_size() should be used when you don't have a convenient - * type to pass to talloc(). Unlike talloc(), it is not type safe (as it - * returns a void *), so you are on your own for type checking. - */ #define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) - -/** - * \def talloc_ptrtype(ctx, ptr) - * \brief Allocate into a typed pointer - * \param ctx The talloc context to hang the result off - * \param ptr The pointer you want to assign the result to - * \result The allocated memory chunk, properly cast - * \ingroup talloc_basic - * - * The talloc_ptrtype() macro should be used when you have a pointer and - * want to allocate memory to point at with this pointer. When compiling - * with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() - * and talloc_get_name() will return the current location in the source file. - * and not the type. - */ #define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) -/** - * \def talloc_new(ctx) - * \brief Allocate a new 0-sized talloc chunk - * \param ctx The talloc parent context - * \return A new talloc chunk - * \ingroup talloc_basic - * - * This is a utility macro that creates a new memory context hanging off an - * exiting context, automatically naming it "talloc_new: __location__" where - * __location__ is the source line it is called from. It is particularly - * useful for creating a new temporary working context. - */ #define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) -/** - * \def talloc_zero(ctx, type) - * \brief Allocate a 0-initizialized structure - * \param ctx The talloc context to hang the result off - * \param type The type that we want to allocate - * \return Pointer to a piece of memory, properly cast to "type *" - * \ingroup talloc_basic - * - * The talloc_zero() macro is equivalent to: - * - * \code - * ptr = talloc(ctx, type); - * if (ptr) memset(ptr, 0, sizeof(type)); - * \endcode - */ #define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) - -/** - * \def talloc_zero_size(ctx, size) - * \brief Untyped, 0-initialized allocation - * \param ctx The talloc context to hang the result off - * \param size Number of char's that you want to allocate - * \return The allocated memory chunk - * \ingroup talloc_basic - * - * The talloc_zero_size() macro is equivalent to: - * - * \code - * ptr = talloc_size(ctx, size); - * if (ptr) memset(ptr, 0, size); - * \endcode - */ - #define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) #define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) - -/** - * \def talloc_array(ctx, type, count) - * \brief Allocate an array - * \param ctx The talloc context to hang the result off - * \param type The type that we want to allocate - * \param count The number of "type" elements you want to allocate - * \return The allocated result, properly cast to "type *" - * \ingroup talloc_array - * - * The talloc_array() macro is equivalent to:: - * - * \code - * (type *)talloc_size(ctx, sizeof(type) * count); - * \endcode - * - * except that it provides integer overflow protection for the multiply, - * returning NULL if the multiply overflows. - */ #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) - -/** - * \def talloc_array_size(ctx, size, count) - * \brief Allocate an array - * \param ctx The talloc context to hang the result off - * \param size The size of an array element - * \param count The number of "type" elements you want to allocate - * \return The allocated result, properly cast to "type *" - * \ingroup talloc_array - * - * The talloc_array_size() function is useful when the type is not - * known. It operates in the same way as talloc_array(), but takes a size - * instead of a type. - */ #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) - -/** - * \def talloc_array_ptrtype(ctx, ptr, count) - * \brief Allocate an array into a typed pointer - * \param ctx The talloc context to hang the result off - * \param ptr The pointer you want to assign the result to - * \param count The number of elements you want to allocate - * \result The allocated memory chunk, properly cast - * \ingroup talloc_array - * - * The talloc_array_ptrtype() macro should be used when you have a pointer to - * an array and want to allocate memory of an array to point at with this - * pointer. When compiling with gcc >= 3 it is typesafe. Note this is a - * wrapper of talloc_array_size() and talloc_get_name() will return the - * current location in the source file. and not the type. - */ #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) - -/** - * \def talloc_array_length(ctx) - * \brief Return the number of elements in a talloc'ed array - * \param ctx The talloc'ed array - * \return The number of elements in ctx - * \ingroup talloc_array - * - * A talloc chunk carries its own size, so for talloc'ed arrays it is not - * necessary to store the number of elements explicitly. - */ #define talloc_array_length(ctx) ((ctx) ? talloc_get_size(ctx)/sizeof(*ctx) : 0) -/** - * \def talloc_realloc(ctx, p, type, count) - * \brief Change the size of a talloc array - * \param ctx The parent context used if "p" is NULL - * \param p The chunk to be resized - * \param type The type of the array element inside p - * \param count The intended number of array elements - * \return The new array - * \ingroup talloc_array - * - * The talloc_realloc() macro changes the size of a talloc - * pointer. The "count" argument is the number of elements of type "type" - * that you want the resulting pointer to hold. - * - * talloc_realloc() has the following equivalences:: - * - * \code - * talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); - * talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); - * talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); - * \endcode - * - * The "context" argument is only used if "ptr" is NULL, otherwise it is - * ignored. - * - * talloc_realloc() returns the new pointer, or NULL on failure. The call - * will fail either due to a lack of memory, or because the pointer has - * more than one parent (see talloc_reference()). - */ #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) - -/** - * \def talloc_realloc_size(ctx, ptr, size) - * \brief Untyped realloc - * \param ctx The parent context used if "ptr" is NULL - * \param ptr The chunk to be resized - * \param size The new chunk size - * \return The new chunk - * \ingroup talloc_array - * - * The talloc_realloc_size() function is useful when the type is not known so - * the typesafe talloc_realloc() cannot be used. - */ #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) -/** - * \def talloc_memdup(t, p, size) - * \brief Duplicate a memory area into a talloc chunk - * \param t The talloc context to hang the result off - * \param p The memory chunk you want to duplicate - * \param size Number of char's that you want copy - * \return The allocated memory chunk - * \ingroup talloc_basic - * - * The talloc_memdup() function is equivalent to:: - * - * \code - * ptr = talloc_size(ctx, size); - * if (ptr) memcpy(ptr, p, size); - * \endcode - */ #define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) -/** - * \def talloc_set_type(ptr, type) - * \brief Assign a type to a talloc chunk - * \param ptr The talloc chunk to assign the type to - * \param type The type to assign - * \ingroup talloc_basic - * - * This macro allows you to force the name of a pointer to be a - * particular type. This can be used in conjunction with - * talloc_get_type() to do type checking on void* pointers. - * - * It is equivalent to this:: - * - * \code - * talloc_set_name_const(ptr, #type) - * \endcode - */ #define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) - -/** - * \def talloc_get_type(ptr, type) - * \brief Get a typed pointer out of a talloc pointer - * \param ptr The talloc pointer to check - * \param type The type to check against - * \return ptr, properly cast, or NULL - * \ingroup talloc_basic - * - * This macro allows you to do type checking on talloc pointers. It is - * particularly useful for void* private pointers. It is equivalent to - * this: - * - * \code - * (type *)talloc_check_name(ptr, #type) - * \endcode - */ - #define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) - -/** - * \def talloc_get_type_abort(ptr, type) - * \brief Helper macro to safely turn a void * into a typed pointer - * \param ptr The void * to convert - * \param type The type that this chunk contains - * \return Same value as ptr, type-checked and properly cast - * \ingroup talloc_basic - * - * This macro is used together with talloc(mem_ctx, struct foo). If you had to - * assing the talloc chunk pointer to some void * variable, - * talloc_get_type_abort() is the recommended way to get the convert the void - * pointer back to a typed pointer. - */ #define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) -/** - * \def talloc_find_parent_bytype(ptr, type) - * \brief Find a parent context by type - * \param ptr The talloc chunk to start from - * \param type The type of the parent to look for - * \ingroup talloc_basic - * - * Find a parent memory context of the current context that has the given - * name. This can be very useful in complex programs where it may be - * difficult to pass all information down to the level you need, but you - * know the structure you want is a parent of another context. - * - * Like talloc_find_parent_byname() but takes a type, making it typesafe. - */ #define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) #if TALLOC_DEPRECATED @@ -615,596 +122,67 @@ typedef void TALLOC_CTX; void *_talloc(const void *context, size_t size); void *talloc_pool(const void *context, size_t size); void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - -/** - * \brief Increase the reference count of a talloc chunk - * \param ptr - * \return success? - * \ingroup talloc_ref - * - * The talloc_increase_ref_count(ptr) function is exactly equivalent to: - * - * \code - * talloc_reference(NULL, ptr); - * \endcode - * - * You can use either syntax, depending on which you think is clearer in - * your code. - * - * It returns 0 on success and -1 on failure. - */ int talloc_increase_ref_count(const void *ptr); - -/** - * \brief Return the number of references to a talloc chunk - * \param ptr The chunk you are interested in - * \return Number of refs - * \ingroup talloc_ref - */ size_t talloc_reference_count(const void *ptr); void *_talloc_reference(const void *context, const void *ptr); - -/** - * \brief Remove a specific parent from a talloc chunk - * \param context The talloc parent to remove - * \param ptr The talloc ptr you want to remove the parent from - * \ingroup talloc_ref - * - * The talloc_unlink() function removes a specific parent from ptr. The - * context passed must either be a context used in talloc_reference() with - * this pointer, or must be a direct parent of ptr. - * - * Note that if the parent has already been removed using talloc_free() then - * this function will fail and will return -1. Likewise, if "ptr" is NULL, - * then the function will make no modifications and return -1. - * - * Usually you can just use talloc_free() instead of talloc_unlink(), but - * sometimes it is useful to have the additional control on which parent is - * removed. - */ int talloc_unlink(const void *context, void *ptr); - -/** - * \brief Assign a name to a talloc chunk - * \param ptr The talloc chunk to assign a name to - * \param fmt Format string for the name - * \param ... printf-style additional arguments - * \return The assigned name - * \ingroup talloc_basic - * - * Each talloc pointer has a "name". The name is used principally for - * debugging purposes, although it is also possible to set and get the name on - * a pointer in as a way of "marking" pointers in your code. - * - * The main use for names on pointer is for "talloc reports". See - * talloc_report() and talloc_report_full() for details. Also see - * talloc_enable_leak_report() and talloc_enable_leak_report_full(). - * - * The talloc_set_name() function allocates memory as a child of the - * pointer. It is logically equivalent to: - * - * \code - * talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - * \endcode - * - * Note that multiple calls to talloc_set_name() will allocate more memory - * without releasing the name. All of the memory is released when the ptr is - * freed using talloc_free(). - */ const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -/** - * \brief Assign a name to a talloc chunk - * \param ptr The talloc chunk to assign a name to - * \param name Format string for the name - * \ingroup talloc_basic - * - * The function talloc_set_name_const() is just like talloc_set_name(), but it - * takes a string constant, and is much faster. It is extensively used by the - * "auto naming" macros, such as talloc_p(). - * - * This function does not allocate any memory. It just copies the supplied - * pointer into the internal representation of the talloc ptr. This means you - * must not pass a name pointer to memory that will disappear before the ptr - * is freed with talloc_free(). - */ void talloc_set_name_const(const void *ptr, const char *name); - -/** - * \brief Create a named talloc chunk - * \param context The talloc context to hang the result off - * \param size Number of char's that you want to allocate - * \param fmt Format string for the name - * \param ... printf-style additional arguments - * \return The allocated memory chunk - * \ingroup talloc_basic - * - * The talloc_named() function creates a named talloc pointer. It is - * equivalent to: - * - * \code - * ptr = talloc_size(context, size); - * talloc_set_name(ptr, fmt, ....); - * \endcode - * - */ void *talloc_named(const void *context, size_t size, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -/** - * \brief Basic routine to allocate a chunk of memory - * \param context The parent context - * \param size The number of char's that we want to allocate - * \param name The name the talloc block has - * \return The allocated chunk - * \ingroup talloc_basic - * - * This is equivalent to: - * - * \code - * ptr = talloc_size(context, size); - * talloc_set_name_const(ptr, name); - * \endcode - */ void *talloc_named_const(const void *context, size_t size, const char *name); - -/** - * \brief Return the name of a talloc chunk - * \param ptr The talloc chunk - * \return The name - * \ingroup talloc_basic - * - * This returns the current name for the given talloc pointer. See - * talloc_set_name() for details. - */ const char *talloc_get_name(const void *ptr); - -/** - * \brief Verify that a talloc chunk carries a specified name - * \param ptr The talloc chunk to check - * \param name The name to check agains - * \ingroup talloc_basic - * - * This function checks if a pointer has the specified name. If it does - * then the pointer is returned. It it doesn't then NULL is returned. - */ void *talloc_check_name(const void *ptr, const char *name); - void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); void *talloc_parent(const void *ptr); const char *talloc_parent_name(const void *ptr); - -/** - * \brief Create a new top level talloc context - * \param fmt Format string for the name - * \param ... printf-style additional arguments - * \return The allocated memory chunk - * \ingroup talloc_basic - * - * This function creates a zero length named talloc context as a top level - * context. It is equivalent to: - * - * \code - * talloc_named(NULL, 0, fmt, ...); - * \endcode - */ void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); - -/** - * \brief Free a chunk of talloc memory - * \param ptr The chunk to be freed - * \return success? - * \ingroup talloc_basic - * - * The talloc_free() function frees a piece of talloc memory, and all its - * children. You can call talloc_free() on any pointer returned by talloc(). - * - * The return value of talloc_free() indicates success or failure, with 0 - * returned for success and -1 for failure. The only possible failure - * condition is if the pointer had a destructor attached to it and the - * destructor returned -1. See talloc_set_destructor() for details on - * destructors. - * - * If this pointer has an additional parent when talloc_free() is called - * then the memory is not actually released, but instead the most - * recently established parent is destroyed. See talloc_reference() for - * details on establishing additional parents. - * - * For more control on which parent is removed, see talloc_unlink() - * - * talloc_free() operates recursively on its children. - */ int talloc_free(void *ptr); - -/** - * \brief Free a talloc chunk's children - * \param ptr The chunk that you want to free the children of - * \return success? - * \ingroup talloc_basic - * - * The talloc_free_children() walks along the list of all children of a talloc - * context and talloc_free()s only the children, not the context itself. - */ void talloc_free_children(void *ptr); void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); void *_talloc_steal(const void *new_ctx, const void *ptr); void *_talloc_move(const void *new_ctx, const void *pptr); - -/** - * \brief Return the total size of a talloc chunk including its children - * \param ptr The talloc chunk - * \return The total size - * \ingroup talloc_basic - * - * The talloc_total_size() function returns the total size in bytes used - * by this pointer and all child pointers. Mostly useful for debugging. - * - * Passing NULL is allowed, but it will only give a meaningful result if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - */ size_t talloc_total_size(const void *ptr); - -/** - * \brief Return the number of talloc chunks hanging off a chunk - * \param ptr The talloc chunk - * \return The total size - * \ingroup talloc_basic - * - * The talloc_total_blocks() function returns the total memory block - * count used by this pointer and all child pointers. Mostly useful for - * debugging. - * - * Passing NULL is allowed, but it will only give a meaningful result if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - */ size_t talloc_total_blocks(const void *ptr); - -/** - * \brief Walk a complete talloc hierarchy - * \param ptr The talloc chunk - * \param depth Internal parameter to control recursion. Call with 0. - * \param max_depth Maximum recursion level. - * \param callback Function to be called on every chunk - * \param private_data Private pointer passed to callback - * \ingroup talloc_debug - * - * This provides a more flexible reports than talloc_report(). It - * will recursively call the callback for the entire tree of memory - * referenced by the pointer. References in the tree are passed with - * is_ref = 1 and the pointer that is referenced. - * - * You can pass NULL for the pointer, in which case a report is - * printed for the top level memory context, but only if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() - * has been called. - * - * The recursion is stopped when depth >= max_depth. - * max_depth = -1 means only stop at leaf nodes. - */ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *private_data), void *private_data); - -/** - * \brief Print a talloc hierarchy - * \param ptr The talloc chunk - * \param depth Internal parameter to control recursion. Call with 0. - * \param max_depth Maximum recursion level. - * \param f The file handle to print to - * \ingroup talloc_debug - * - * This provides a more flexible reports than talloc_report(). It - * will let you specify the depth and max_depth. - */ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); - -/** - * \brief Print a summary report of all memory used by ptr - * \param ptr The talloc chunk - * \param f The file handle to print to - * \ingroup talloc_debug - * - * This provides a more detailed report than talloc_report(). It will - * recursively print the ensire tree of memory referenced by the - * pointer. References in the tree are shown by giving the name of the - * pointer that is referenced. - * - * You can pass NULL for the pointer, in which case a report is printed - * for the top level memory context, but only if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - */ void talloc_report_full(const void *ptr, FILE *f); - -/** - * \brief Print a summary report of all memory used by ptr - * \param ptr The talloc chunk - * \param f The file handle to print to - * \ingroup talloc_debug - * - * The talloc_report() function prints a summary report of all memory - * used by ptr. One line of report is printed for each immediate child of - * ptr, showing the total memory and number of blocks used by that child. - * - * You can pass NULL for the pointer, in which case a report is printed - * for the top level memory context, but only if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - */ void talloc_report(const void *ptr, FILE *f); - -/** - * \brief Enable tracking the use of NULL memory contexts - * \ingroup talloc_debug - * - * This enables tracking of the NULL memory context without enabling leak - * reporting on exit. Useful for when you want to do your own leak - * reporting call via talloc_report_null_full(); - */ void talloc_enable_null_tracking(void); - -/** - * \brief Disable tracking of the NULL memory context - * \ingroup talloc_debug - * - * This disables tracking of the NULL memory context. - */ - void talloc_disable_null_tracking(void); - -/** - * \brief Enable calling of talloc_report(NULL, stderr) when a program exits - * \ingroup talloc_debug - * - * This enables calling of talloc_report(NULL, stderr) when the program - * exits. In Samba4 this is enabled by using the --leak-report command - * line option. - * - * For it to be useful, this function must be called before any other - * talloc function as it establishes a "null context" that acts as the - * top of the tree. If you don't call this function first then passing - * NULL to talloc_report() or talloc_report_full() won't give you the - * full tree printout. - * - * Here is a typical talloc report: - * -\verbatim -talloc report on 'null_context' (total 267 bytes in 15 blocks) - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(UTF8,CP850) contains 42 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(CP850,UTF8) contains 42 bytes in 2 blocks - iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks - iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks -\endverbatim - */ void talloc_enable_leak_report(void); - -/** - * \brief Enable calling of talloc_report(NULL, stderr) when a program exits - * \ingroup talloc_debug - * - * This enables calling of talloc_report_full(NULL, stderr) when the - * program exits. In Samba4 this is enabled by using the - * --leak-report-full command line option. - * - * For it to be useful, this function must be called before any other - * talloc function as it establishes a "null context" that acts as the - * top of the tree. If you don't call this function first then passing - * NULL to talloc_report() or talloc_report_full() won't give you the - * full tree printout. - * - * Here is a typical full report: -\verbatim -full talloc report on 'root' (total 18 bytes in 8 blocks) - p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) -\endverbatim -*/ void talloc_enable_leak_report_full(void); void *_talloc_zero(const void *ctx, size_t size, const char *name); void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); - -/** - * \brief Provide a function version of talloc_realloc_size - * \param context The parent context used if "ptr" is NULL - * \param ptr The chunk to be resized - * \param size The new chunk size - * \return The new chunk - * \ingroup talloc_array - * - * This is a non-macro version of talloc_realloc(), which is useful as - * libraries sometimes want a ralloc function pointer. A realloc() - * implementation encapsulates the functionality of malloc(), free() and - * realloc() in one call, which is why it is useful to be able to pass around - * a single function pointer. -*/ void *talloc_realloc_fn(const void *context, void *ptr, size_t size); - -/** - * \brief Provide a talloc context that is freed at program exit - * \return A talloc context - * \ingroup talloc_basic - * - * This is a handy utility function that returns a talloc context - * which will be automatically freed on program exit. This can be used - * to reduce the noise in memory leak reports. - */ void *talloc_autofree_context(void); - -/** - * \brief Get the size of a talloc chunk - * \param ctx The talloc chunk - * \return The size - * \ingroup talloc_basic - * - * This function lets you know the amount of memory alloced so far by - * this context. It does NOT account for subcontext memory. - * This can be used to calculate the size of an array. - */ size_t talloc_get_size(const void *ctx); - -/** - * \brief Find a parent context by name - * \param ctx The talloc chunk to start from - * \param name The name of the parent we look for - * \ingroup talloc_basic - * - * Find a parent memory context of the current context that has the given - * name. This can be very useful in complex programs where it may be - * difficult to pass all information down to the level you need, but you - * know the structure you want is a parent of another context. - */ void *talloc_find_parent_byname(const void *ctx, const char *name); void talloc_show_parents(const void *context, FILE *file); int talloc_is_parent(const void *context, const void *ptr); -/** - * \brief Duplicate a string into a talloc chunk - * \param t The talloc context to hang the result off - * \param p The string you want to duplicate - * \return The duplicated string - * \ingroup talloc_string - * - * The talloc_strdup() function is equivalent to: - * - * \code - * ptr = talloc_size(ctx, strlen(p)+1); - * if (ptr) memcpy(ptr, p, strlen(p)+1); - * \endcode - * - * This functions sets the name of the new pointer to the passed - * string. This is equivalent to: - * - * \code - * talloc_set_name_const(ptr, ptr) - * \endcode - */ char *talloc_strdup(const void *t, const char *p); char *talloc_strdup_append(char *s, const char *a); char *talloc_strdup_append_buffer(char *s, const char *a); -/** - * \brief Duplicate a length-limited string into a talloc chunk - * \param t The talloc context to hang the result off - * \param p The string you want to duplicate - * \param n The maximum string length to duplicate - * \return The duplicated string - * \ingroup talloc_string - * - * The talloc_strndup() function is the talloc equivalent of the C - * library function strndup() - * - * This functions sets the name of the new pointer to the passed - * string. This is equivalent to: - * - * \code - * talloc_set_name_const(ptr, ptr) - * \endcode - */ char *talloc_strndup(const void *t, const char *p, size_t n); char *talloc_strndup_append(char *s, const char *a, size_t n); char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); -/** - * \brief Format a string given a va_list - * \param t The talloc context to hang the result off - * \param fmt The format string - * \param ap The parameters used to fill fmt - * \return The formatted string - * \ingroup talloc_string - * - * The talloc_vasprintf() function is the talloc equivalent of the C - * library function vasprintf() - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * \code - * talloc_set_name_const(ptr, ptr) - * \endcode - */ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -/** - * \brief Format a string - * \param t The talloc context to hang the result off - * \param fmt The format string - * \param ... The parameters used to fill fmt - * \return The formatted string - * \ingroup talloc_string - * - * The talloc_asprintf() function is the talloc equivalent of the C - * library function asprintf() - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * \code - * talloc_set_name_const(ptr, ptr) - * \endcode - */ char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -/** - * \brief Append a formatted string to another string - * \param s The string to append to - * \param fmt The format string - * \param ... The parameters used to fill fmt - * \return The formatted string - * \ingroup talloc_string - * - * The talloc_asprintf_append() function appends the given formatted string to - * the given string. Use this varient when the string in the current talloc - * buffer may have been truncated in length. - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * \code - * talloc_set_name_const(ptr, ptr) - * \endcode - */ char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -/** - * \brief Append a formatted string to another string - * \param s The string to append to - * \param fmt The format string - * \param ... The parameters used to fill fmt - * \return The formatted string - * \ingroup talloc_string - * - * The talloc_asprintf_append() function appends the given formatted string to - * the end of the currently allocated talloc buffer. This routine should be - * used if you create a large string step by step. talloc_asprintf() or - * talloc_asprintf_append() call strlen() at every - * step. talloc_asprintf_append_buffer() uses the existing buffer size of the - * talloc chunk to calculate where to append the string. - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * \code - * talloc_set_name_const(ptr, ptr) - * \endcode - */ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); -- cgit From f590915fe5b0deb9e99ab5b2c13c587eadf194f6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 09:48:54 +0100 Subject: Revert "Add a basic Doxyfile for talloc" This reverts commit f55e84e904173bed8dc9099ad523ca1e7be12355. --- lib/talloc/Doxyfile | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 lib/talloc/Doxyfile diff --git a/lib/talloc/Doxyfile b/lib/talloc/Doxyfile deleted file mode 100644 index 0ccf563d75..0000000000 --- a/lib/talloc/Doxyfile +++ /dev/null @@ -1,8 +0,0 @@ -OUTPUT_DIRECTORY = doc -PROJECT_NAME = Talloc -OPTIMIZE_OUTPUT_FOR_C = YES -GENERATE_LATEX = NO -GENERATE_MAN = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = YES -PREDEFINED = PRINTF_ATTRIBUTE(x,y)= -- cgit From 2835d0d46331ae5275b8f9eaeea7dd78e998cfeb Mon Sep 17 00:00:00 2001 From: Andy Kelk Date: Sun, 22 Mar 2009 11:06:52 +0100 Subject: Add dirsort module --- source3/Makefile.in | 5 ++ source3/configure.in | 3 +- source3/modules/vfs_dirsort.c | 194 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 source3/modules/vfs_dirsort.c diff --git a/source3/Makefile.in b/source3/Makefile.in index cf74182f27..49cf8408d3 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -687,6 +687,7 @@ VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \ VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o PERFCOUNT_TEST_OBJ = modules/perfcount_test.o +VFS_DIRSORT_OBJ = modules/vfs_dirsort.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -2625,6 +2626,10 @@ bin/security.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/security.o @echo "Building plugin $@" @$(SHLD_MODULE) libgpo/gpext/security.o +bin/dirsort.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_DIRSORT_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_DIRSORT_OBJ) + ######################################################### ## IdMap NSS plugins diff --git a/source3/configure.in b/source3/configure.in index dc5850aba1..c43c033866 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -436,7 +436,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen vfs_dirsort" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -6213,6 +6213,7 @@ SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS) SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS) SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS) SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS) +SMB_MODULE(vfs_dirsort, \$(VFS_DIRSORT_OBJ), "bin/dirsort.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c new file mode 100644 index 0000000000..f9a31c8976 --- /dev/null +++ b/source3/modules/vfs_dirsort.c @@ -0,0 +1,194 @@ +/* + * VFS module to provide a sorted directory list. + * + * Copyright (C) Andy Kelk (andy@mopoke.co.uk), 2009 + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" + +static int compare_dirent (const void *a, const void *b) { + const SMB_STRUCT_DIRENT *da = (const SMB_STRUCT_DIRENT *) a; + const SMB_STRUCT_DIRENT *db = (const SMB_STRUCT_DIRENT *) b; + return strcmp(da->d_name, db->d_name); +} + +struct dirsort_privates { + long pos; + SMB_STRUCT_DIRENT *directory_list; + long number_of_entries; + time_t mtime; + SMB_STRUCT_DIR *source_directory; + int fd; +}; + +static void free_dirsort_privates(void **datap) { + struct dirsort_privates *data = (struct dirsort_privates *) *datap; + SAFE_FREE(data->directory_list); + SAFE_FREE(data); + *datap = NULL; + + return; +} + +static void open_and_sort_dir (vfs_handle_struct *handle) +{ + SMB_STRUCT_DIRENT *dp; + struct stat dir_stat; + long current_pos; + struct dirsort_privates *data = NULL; + + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return); + + data->number_of_entries = 0; + + if (fstat(data->fd, &dir_stat) == 0) { + data->mtime = dir_stat.st_mtime; + } + + while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL) + != NULL) { + data->number_of_entries++; + } + + /* Open the underlying directory and count the number of entries + Skip back to the beginning as we'll read it again */ + SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory); + + /* Set up an array and read the directory entries into it */ + SAFE_FREE(data->directory_list); /* destroy previous cache if needed */ + data->directory_list = (SMB_STRUCT_DIRENT *)SMB_MALLOC( + data->number_of_entries * sizeof(SMB_STRUCT_DIRENT)); + current_pos = data->pos; + data->pos = 0; + while ((dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, + NULL)) != NULL) { + data->directory_list[data->pos++] = *dp; + } + + /* Sort the directory entries by name */ + data->pos = current_pos; + qsort(data->directory_list, data->number_of_entries, + sizeof(SMB_STRUCT_DIRENT), compare_dirent); +} + +static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle, + const char *fname, const char *mask, + uint32 attr) +{ + struct dirsort_privates *data = NULL; + + /* set up our private data about this directory */ + data = (struct dirsort_privates *)SMB_MALLOC( + sizeof(struct dirsort_privates)); + + data->directory_list = NULL; + data->pos = 0; + + /* Open the underlying directory and count the number of entries */ + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, + attr); + + data->fd = dirfd(data->source_directory); + + SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates, + struct dirsort_privates, return NULL); + + open_and_sort_dir(handle); + + return data->source_directory; +} + +static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp) +{ + struct dirsort_privates *data = NULL; + time_t current_mtime; + struct stat dir_stat; + + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, + return NULL); + + if (fstat(data->fd, &dir_stat) == -1) { + return NULL; + } + + current_mtime = dir_stat.st_mtime; + + /* throw away cache and re-read the directory if we've changed */ + if (current_mtime > data->mtime) { + open_and_sort_dir(handle); + } + + if (data->pos >= data->number_of_entries) { + return NULL; + } + + return &data->directory_list[data->pos++]; +} + +static void dirsort_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, + long offset) +{ + struct dirsort_privates *data = NULL; + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return); + + data->pos = offset; +} + +static long dirsort_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + struct dirsort_privates *data = NULL; + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, + return -1); + + return data->pos; +} + +static void dirsort_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + struct dirsort_privates *data = NULL; + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return); + + data->pos = 0; +} + +/* VFS operations structure */ + +static vfs_op_tuple dirsort_op_tuples[] = { + + /* Directory operations */ + + {SMB_VFS_OP(dirsort_opendir), SMB_VFS_OP_OPENDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_readdir), SMB_VFS_OP_READDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_seekdir), SMB_VFS_OP_SEEKDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_telldir), SMB_VFS_OP_TELLDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_rewinddir), SMB_VFS_OP_REWINDDIR, + SMB_VFS_LAYER_TRANSPARENT}, + + {NULL, SMB_VFS_OP_NOOP, + SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_dirsort_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "dirsort", + dirsort_op_tuples); +} -- cgit From 14df86e9e368fdab327bd07a2954f650b2946ff2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 11:39:10 +0100 Subject: Use StrCaseCmp in the dirsort module --- source3/modules/vfs_dirsort.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c index f9a31c8976..53d1820c11 100644 --- a/source3/modules/vfs_dirsort.c +++ b/source3/modules/vfs_dirsort.c @@ -23,7 +23,7 @@ static int compare_dirent (const void *a, const void *b) { const SMB_STRUCT_DIRENT *da = (const SMB_STRUCT_DIRENT *) a; const SMB_STRUCT_DIRENT *db = (const SMB_STRUCT_DIRENT *) b; - return strcmp(da->d_name, db->d_name); + return StrCaseCmp(da->d_name, db->d_name); } struct dirsort_privates { -- cgit From 191152daa1384435746baf0062864a5d6f10cce3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 11:39:32 +0100 Subject: Document the dirsort module --- docs-xml/manpages-3/vfs_dirsort.8.xml | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs-xml/manpages-3/vfs_dirsort.8.xml diff --git a/docs-xml/manpages-3/vfs_dirsort.8.xml b/docs-xml/manpages-3/vfs_dirsort.8.xml new file mode 100644 index 0000000000..cec5f270c8 --- /dev/null +++ b/docs-xml/manpages-3/vfs_dirsort.8.xml @@ -0,0 +1,69 @@ + + + + + + vfs_dirsort + 8 + Samba + System Administration tools + 3.3 + + + + + vfs_dirsort + Sort directory contents + + + + + vfs objects = dirsort + + + + + DESCRIPTION + + This VFS module is part of the + samba + 7 suite. + + The vfs_dirsort module sorts directory + entries alphabetically before sending them to the client. + + Please be aware that adding this module might have negative + performance implications for large directories. + + + + + EXAMPLES + + Sort directories for all shares: + + + + dirsort + + + + + + VERSION + + This man page is correct for version 3.3 of the Samba suite. + + + + + AUTHOR + + The original Samba software and related utilities + were created by Andrew Tridgell. Samba is now developed + by the Samba Team as an Open Source project similar + to the way the Linux kernel is developed. + + + + -- 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(-) 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 From 1f72e4abfdc85fbe624ec7910b68868d97f88ff2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 22 Mar 2009 12:36:38 +0100 Subject: Revert "socket_wrapper: fix connect() for dgram sockets, if the destination isn't there yet" This reverts commit 66dc53ee017d74a6f610bbe04337f064901fe2a1. Somehow this leads to timeouts in some tests, samba4.ldb.ldapi and samba4.rpc.schannel. I need to look at it more closely later... metze --- lib/socket_wrapper/socket_wrapper.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 1d35c8d20c..44082e78a1 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -1686,14 +1686,10 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; - if (si->type == SOCK_DGRAM) { - ret = 0; - } else { - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); - ret = real_connect(s, (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); - } + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); /* to give better errors */ if (ret == -1 && errno == ENOENT) { -- cgit From 1bff89c4ad1cb76c8fec1ba9bcebfbd0da5ee15e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 13:14:15 +0100 Subject: Only build the dirsort module if we have the dirfd function Fix the build on HP/UX --- source3/configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index c43c033866..cfc2473a82 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -436,7 +436,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen vfs_dirsort" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -879,7 +879,7 @@ fi AC_CHECK_FUNCS(dirfd) if test x"$ac_cv_func_dirfd" = x"yes"; then - default_shared_modules="$default_shared_modules vfs_syncops" + default_shared_modules="$default_shared_modules vfs_syncops vfs_dirsort" fi AC_CACHE_CHECK([for struct sigevent type],samba_cv_struct_sigevent, [ -- cgit From 979a1b06d01817a01967d9137e4f70f222fa8eab Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 22:07:58 +0100 Subject: talloc_array_length: talloc_get_size deals fine with NULL --- lib/talloc/talloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 5c8d5c5fe2..f87564a13b 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -94,7 +94,7 @@ typedef void TALLOC_CTX; #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) -#define talloc_array_length(ctx) ((ctx) ? talloc_get_size(ctx)/sizeof(*ctx) : 0) +#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx)) #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) -- cgit