From e548ec9c24d7f05fea81910b8c7cf3fc0bd137db Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 15 Mar 2009 17:14:25 +0100 Subject: display_sec: Remove use of samba3-specific data types. --- source3/lib/display_sec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c index fe1ae77edd..6edbb27f3a 100644 --- a/source3/lib/display_sec.c +++ b/source3/lib/display_sec.c @@ -24,7 +24,7 @@ convert a security permissions into a string ****************************************************************************/ -char *get_sec_mask_str(TALLOC_CTX *ctx, uint32 type) +char *get_sec_mask_str(TALLOC_CTX *ctx, uint32_t type) { char *typestr = talloc_strdup(ctx, ""); @@ -122,7 +122,7 @@ void display_sec_access(uint32_t *info) { char *mask_str = get_sec_mask_str(NULL, *info); printf("\t\tPermissions: 0x%x: %s\n", *info, mask_str ? mask_str : ""); - TALLOC_FREE(mask_str); + talloc_free(mask_str); } /**************************************************************************** @@ -238,7 +238,7 @@ void display_sec_acl(SEC_ACL *sec_acl) } } -void display_acl_type(uint16 type) +void display_acl_type(uint16_t type) { fstring typestr=""; -- cgit From 44787565715f0622cc1d049854427d735ca1c14b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 15 Mar 2009 18:10:20 +0100 Subject: Strip /usr/include from include flags, so we don't end up including the system tevent if it's too old. --- lib/util/fault.m4 | 2 ++ source4/auth/config.m4 | 2 ++ source4/build/m4/public.m4 | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/util/fault.m4 b/lib/util/fault.m4 index bac553a158..c22976998e 100644 --- a/lib/util/fault.m4 +++ b/lib/util/fault.m4 @@ -9,6 +9,8 @@ if test x"$ac_cv_header_execinfo_h" = x"yes" -a x"$ac_cv_func_ext_backtrace" = x EXECINFO_CPPFLAGS="$CPPFLAGS" EXECINFO_LDFLAGS="$LDFLAGS" LIB_REMOVE_USR_LIB(EXECINFO_LDFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(EXECINFO_CFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(EXECINFO_CPPFLAGS) else SMB_ENABLE(EXECINFO,NO) fi diff --git a/source4/auth/config.m4 b/source4/auth/config.m4 index fb9ee58c60..9735b17cac 100644 --- a/source4/auth/config.m4 +++ b/source4/auth/config.m4 @@ -28,6 +28,8 @@ if test x"$ac_cv_header_sasl_sasl_h" = x"yes" -a x"$ac_cv_lib_ext_sasl2_sasl_cli SASL_CPPFLAGS="$CPPFLAGS" SASL_LDFLAGS="$LDFLAGS" LIB_REMOVE_USR_LIB(SASL_LDFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(SASL_CPPFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(SASL_CFLAGS) else SMB_ENABLE(cyrus_sasl,NO) fi diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index 6860e56e7f..732de1e20e 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -101,10 +101,12 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG], ac_cv_$1_libs_only_other="`$PKG_CONFIG --libs-only-other '$2'` `$PKG_CONFIG --libs-only-L '$2'`" LIB_REMOVE_USR_LIB(ac_cv_$1_libs_only_other) + ac_cv_$1_includedir_only="`$PKG_CONFIG --cflags-only-I '$2'`" + CFLAGS_REMOVE_USR_INCLUDE(ac_cv_$1_includedir_only) SMB_EXT_LIB($1, [`$PKG_CONFIG --libs-only-l '$2'`], [`$PKG_CONFIG --cflags-only-other '$2'`], - [`$PKG_CONFIG --cflags-only-I '$2'`], + [$ac_cv_$1_includedir_only], [$ac_cv_$1_libs_only_other]) ac_cv_$1_found=yes -- cgit From 844a1b3cd27f323087b707e494c5e3860340eb27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 19 Mar 2009 16:07:07 +1100 Subject: flush after showing the prompt in smbclient --- source4/lib/smbreadline/smbreadline.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/lib/smbreadline/smbreadline.c b/source4/lib/smbreadline/smbreadline.c index 5fb3bf4fae..b07417357f 100644 --- a/source4/lib/smbreadline/smbreadline.c +++ b/source4/lib/smbreadline/smbreadline.c @@ -83,6 +83,7 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void) char *ret; printf("%s", prompt); + fflush(stdout); line = (char *)malloc(BUFSIZ); if (!line) { -- 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 From 298bff5019be5a40dc0023b5af1e980fba91abd9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 12:05:02 +0100 Subject: Fix connect to port 139 only -- thanks gd for bugging me :-) --- source3/libsmb/cliconnect.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ebb01c44a6..525c361beb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1841,10 +1841,9 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss, tevent_req_set_callback(r445, smb_sock_connected, fd445); tevent_req_set_callback(r139, smb_sock_connected, fd139); - while ((fd139->fd == -1) - && tevent_req_is_in_progress(r139) - && (fd445->fd == -1) - && tevent_req_is_in_progress(r445)) { + while ((fd445->fd == -1) && (fd139->fd == -1) + && (tevent_req_is_in_progress(r139) + || tevent_req_is_in_progress(r445))) { event_loop_once(ev); } -- cgit From 435a0a5a3bc8114991650a78e1f90049d2f3f343 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 23 Mar 2009 09:16:18 +0100 Subject: socket_wrapper: fix connect() for dgram sockets, if the destination isn't there yet Now we defer the real_connect() for dgram sockets to the first send()/sendto() call, as the destination might not be there at connect time. Commit 66dc53ee017d74a6f610bbe04337f064901fe2a1 was an incomplete fix for this problem. metze --- lib/socket_wrapper/socket_wrapper.c | 56 ++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 44082e78a1..553827b192 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -218,6 +218,7 @@ struct socket_info int bcast; int is_server; int connected; + int defer_connect; char *path; char *tmp_path; @@ -1686,10 +1687,15 @@ _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) { + si->defer_connect = 1; + 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) { @@ -1917,7 +1923,22 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return len; } - + + if (si->defer_connect) { + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(un_addr)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + return ret; + } + si->defer_connect = 0; + } + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); break; default: @@ -2002,6 +2023,33 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) len = MIN(len, 1500); + if (si->defer_connect) { + struct sockaddr_un un_addr; + int bcast = 0; + + if (si->bound == 0) { + ret = swrap_auto_bind(si, si->family); + if (ret == -1) return -1; + } + + ret = sockaddr_convert_to_un(si, si->peername, si->peername_len, + &un_addr, 0, &bcast); + if (ret == -1) return -1; + + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(un_addr)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + return ret; + } + si->defer_connect = 0; + } + ret = real_send(s, buf, len, flags); if (ret == -1) { -- cgit From 7716ad68a8d859ac3651c4eb559b6e45d98566db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 23 Mar 2009 11:44:00 +0100 Subject: s3:smbd: if we allow trans2 on the IPC$ share, then we have to allow transs2 too. Otherwise we'll confuse the client signing engine, when we reply an error to each transs2. metze --- source3/smbd/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 18fbdd7939..6d53bbe929 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -913,7 +913,7 @@ static const struct smb_message_struct { /* 0x30 */ { NULL, NULL, 0 }, /* 0x31 */ { NULL, NULL, 0 }, /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC }, -/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER}, +/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC }, /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER}, /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER}, /* 0x36 */ { NULL, NULL, 0 }, -- cgit From 1a48d0793b9d3a76aff76580661626e5cd95f427 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 8 Mar 2009 17:47:08 +0100 Subject: s3:libsmb: rename smb_signing.c => clisigning.c This prepares a large simplification of the smb_signing code metze --- source3/Makefile.in | 2 +- source3/include/proto.h | 2 +- source3/libsmb/clisigning.c | 1006 ++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smb_signing.c | 1006 ------------------------------------------ 4 files changed, 1008 insertions(+), 1008 deletions(-) create mode 100644 source3/libsmb/clisigning.c delete mode 100644 source3/libsmb/smb_signing.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 49cf8408d3..0db6f62c5c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -364,7 +364,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \ lib/substitute.o lib/dbwrap_util.o \ lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \ - lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \ + lib/tallocmsg.o lib/dmallocmsg.o libsmb/clisigning.o \ lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \ lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \ lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \ diff --git a/source3/include/proto.h b/source3/include/proto.h index c84b1cb9ac..1ed623c4cb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3181,7 +3181,7 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf); NTSTATUS cli_decrypt_message(struct cli_state *cli); NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out); -/* The following definitions come from libsmb/smb_signing.c */ +/* The following definitions come from libsmb/clisigning.c */ bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c new file mode 100644 index 0000000000..a3ed0e7572 --- /dev/null +++ b/source3/libsmb/clisigning.c @@ -0,0 +1,1006 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett 2002-2003 + + 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" + +/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ +struct outstanding_packet_lookup { + struct outstanding_packet_lookup *prev, *next; + uint16 mid; + uint32 reply_seq_num; + bool can_delete; /* Set to False in trans state. */ +}; + +struct smb_basic_signing_context { + DATA_BLOB mac_key; + uint32 send_seq_num; + struct outstanding_packet_lookup *outstanding_packet_list; +}; + +static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, + uint16 mid, uint32 reply_seq_num) +{ + struct outstanding_packet_lookup *t; + + /* Ensure we only add a mid once. */ + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + return False; + } + } + + t = SMB_XMALLOC_P(struct outstanding_packet_lookup); + ZERO_STRUCTP(t); + + t->mid = mid; + t->reply_seq_num = reply_seq_num; + t->can_delete = True; + + /* + * Add to the *start* of the list not the end of the list. + * This ensures that the *last* send sequence with this mid + * is returned by preference. + * This can happen if the mid wraps and one of the early + * mid numbers didn't get a reply and is still lurking on + * the list. JRA. Found by Fran Fabrizio . + */ + + DLIST_ADD(*list, t); + DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", + (unsigned int)reply_seq_num, (unsigned int)mid )); + return True; +} + +static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, + uint16 mid, uint32 *reply_seq_num) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + *reply_seq_num = t->reply_seq_num; + DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", + (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); + if (t->can_delete) { + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + } + return True; + } + } + return False; +} + +static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + t->can_delete = can_delete_entry; + return True; + } + } + return False; +} + +/*********************************************************** + SMB signing - Common code before we set a new signing implementation +************************************************************/ + +static bool cli_set_smb_signing_common(struct cli_state *cli) +{ + if (!cli->sign_info.allow_smb_signing) { + return False; + } + + if (!cli->sign_info.negotiated_smb_signing + && !cli->sign_info.mandatory_signing) { + return False; + } + + if (cli->sign_info.doing_signing) { + return False; + } + + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(&cli->sign_info); + + /* These calls are INCOMPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + return True; +} + +/*********************************************************** + SMB signing - Common code for 'real' implementations +************************************************************/ + +static bool set_smb_signing_real_common(struct smb_sign_info *si) +{ + if (si->mandatory_signing) { + DEBUG(5, ("Mandatory SMB signing enabled!\n")); + } + + si->doing_signing = True; + DEBUG(5, ("SMB signing enabled!\n")); + + return True; +} + +static void mark_packet_signed(char *outbuf) +{ + uint16 flags2; + flags2 = SVAL(outbuf,smb_flg2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(outbuf,smb_flg2, flags2); +} + +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the field */ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static bool null_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + bool must_be_ok) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void null_free_signing_context(struct smb_sign_info *si) +{ + return; +} + +/** + SMB signing - NULL implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ + +static bool null_set_signing(struct smb_sign_info *si) +{ + si->signing_context = NULL; + + si->sign_outgoing_message = null_sign_outgoing_message; + si->check_incoming_message = null_check_incoming_message; + si->free_signing_context = null_free_signing_context; + + return True; +} + +/** + * Free the signing context + */ + +static void free_signing_context(struct smb_sign_info *si) +{ + if (si->free_signing_context) { + si->free_signing_context(si); + si->signing_context = NULL; + } + + null_set_signing(si); +} + + +static bool signing_good(const char *inbuf, struct smb_sign_info *si, + bool good, uint32 seq, bool must_be_ok) +{ + if (good) { + + if (!si->doing_signing) { + si->doing_signing = True; + } + + if (!si->seen_valid) { + si->seen_valid = True; + } + + } else { + if (!si->mandatory_signing && !si->seen_valid) { + + if (!must_be_ok) { + return True; + } + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" + "isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; + free_signing_context(si); + return True; + } else if (!must_be_ok) { + /* This packet is known to be unsigned */ + return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (seq) + DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); + return False; + } + } + return True; +} + +/*********************************************************** + SMB signing - Simple implementation - calculate a MAC on the packet +************************************************************/ + +static void simple_packet_signature(struct smb_basic_signing_context *data, + const uchar *buf, uint32 seq_number, + unsigned char calc_md5_mac[16]) +{ + const size_t offset_end_of_sig = (smb_ss_field + 8); + unsigned char sequence_buf[8]; + struct MD5Context md5_ctx; +#if 0 + /* JRA - apparently this is incorrect. */ + unsigned char key_buf[16]; +#endif + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + * + * We do this here, to avoid modifying the packet. + */ + + DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); + + SIVAL(sequence_buf, 0, seq_number); + SIVAL(sequence_buf, 4, 0); + + /* Calculate the 16 byte MAC - but don't alter the data in the + incoming packet. + + This makes for a bit of fussing about, but it's not too bad. + */ + MD5Init(&md5_ctx); + + /* intialise with the key */ + MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); +#if 0 + /* JRA - apparently this is incorrect. */ + /* NB. When making and verifying SMB signatures, Windows apparently + zero-pads the key to 128 bits if it isn't long enough. + From Nalin Dahyabhai */ + if (data->mac_key.length < sizeof(key_buf)) { + memset(key_buf, 0, sizeof(key_buf)); + MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); + } +#endif + + /* copy in the first bit of the SMB header */ + MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + /* copy in the rest of the packet in, skipping the signature */ + MD5Update(&md5_ctx, buf + offset_end_of_sig, + smb_len(buf) - (offset_end_of_sig - 4)); + + /* calculate the MD5 sig */ + MD5Final(calc_md5_mac, &md5_ctx); +} + + +/*********************************************************** + SMB signing - Client implementation - send the MAC. +************************************************************/ + +static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(outbuf); + + simple_packet_signature(data, (const unsigned char *)outbuf, + data->send_seq_num, calc_md5_mac); + + DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signatures...*/ + + /* Instead of re-introducing the trans_info_conect we + used to have here, we use the fact that during a + SMBtrans/SMBtrans2/SMBnttrans send that the mid stays + constant. This means that calling store_sequence_for_reply() + will return False for all trans secondaries, as the mid is already + on the stored sequence list. As the send_seqence_number must + remain constant for all primary+secondary trans sends, we + only increment the send sequence number when we successfully + add a new entry to the outstanding sequence list. This means + I can isolate the fix here rather than re-adding the trans + signing on/off calls in libsmb/clitrans2.c JRA. + */ + + if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { + data->send_seq_num += 2; + } +} + +/*********************************************************** + SMB signing - Client implementation - check a MAC sent by server. +************************************************************/ + +static bool client_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + bool must_be_ok) +{ + bool good; + uint32 reply_seq_number; + unsigned char calc_md5_mac[16]; + unsigned char *server_sent_mac; + + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + + if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { + DEBUG(1, ("client_check_incoming_message: received message " + "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) )); + return False; + } + + simple_packet_signature(data, (const unsigned char *)inbuf, + reply_seq_number, calc_md5_mac); + + server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (!good) { + DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); +#if 1 /* JRATEST */ + { + int i; + for (i = -5; i < 5; i++) { + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ +We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); + break; + } + } + } +#endif /* JRATEST */ + + } else { + DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); + } + return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); +} + +/*********************************************************** + SMB signing - Simple implementation - free signing context +************************************************************/ + +static void simple_free_signing_context(struct smb_sign_info *si) +{ + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; + struct outstanding_packet_lookup *list; + struct outstanding_packet_lookup *next; + + for (list = data->outstanding_packet_list; list; list = next) { + next = list->next; + DLIST_REMOVE(data->outstanding_packet_list, list); + SAFE_FREE(list); + } + + data_blob_free(&data->mac_key); + + SAFE_FREE(si->signing_context); + + return; +} + +/*********************************************************** + SMB signing - Simple implementation - setup the MAC key. +************************************************************/ + +bool cli_simple_set_signing(struct cli_state *cli, + const DATA_BLOB user_session_key, + const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!user_session_key.length) + return False; + + if (!cli_set_smb_signing_common(cli)) { + return False; + } + + if (!set_smb_signing_real_common(&cli->sign_info)) { + return False; + } + + data = SMB_XMALLOC_P(struct smb_basic_signing_context); + memset(data, '\0', sizeof(*data)); + + cli->sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, response.length + user_session_key.length); + + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); + + DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); + dump_data(10, user_session_key.data, user_session_key.length); + + if (response.length) { + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + DEBUG(10, ("cli_simple_set_signing: response_data\n")); + dump_data(10, response.data, response.length); + } else { + DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); + } + + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + + cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; + cli->sign_info.check_incoming_message = client_check_incoming_message; + cli->sign_info.free_signing_context = simple_free_signing_context; + + return True; +} + +/*********************************************************** + SMB signing - TEMP implementation - calculate a MAC to send. +************************************************************/ + +static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(outbuf); + + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); + return; +} + +/*********************************************************** + SMB signing - TEMP implementation - check a MAC sent by server. +************************************************************/ + +static bool temp_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, bool foo) +{ + return True; +} + +/*********************************************************** + SMB signing - TEMP implementation - free signing context +************************************************************/ + +static void temp_free_signing_context(struct smb_sign_info *si) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +bool cli_null_set_signing(struct cli_state *cli) +{ + return null_set_signing(&cli->sign_info); +} + +/*********************************************************** + SMB signing - temp implementation - setup the MAC key. +************************************************************/ + +bool cli_temp_set_signing(struct cli_state *cli) +{ + if (!cli_set_smb_signing_common(cli)) { + return False; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = temp_check_incoming_message; + cli->sign_info.free_signing_context = temp_free_signing_context; + + return True; +} + +void cli_free_signing_context(struct cli_state *cli) +{ + free_signing_context(&cli->sign_info); +} + +/** + * Sign a packet with the current mechanism + */ + +void cli_calculate_sign_mac(struct cli_state *cli, char *buf) +{ + cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); +} + +/** + * Check a packet with the current mechanism + * @return False if we had an established signing connection + * which had a bad checksum, True otherwise. + */ + +bool cli_check_sign_mac(struct cli_state *cli, char *buf) +{ + if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { + free_signing_context(&cli->sign_info); + return False; + } + return True; +} + +/*********************************************************** + Enter trans/trans2/nttrans state. +************************************************************/ + +bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +{ + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!data) { + return False; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { + return False; + } + + return True; +} + +/*********************************************************** + Leave trans/trans2/nttrans state. +************************************************************/ + +bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +{ + uint32 reply_seq_num; + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!data) { + return False; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { + return False; + } + + /* Now delete the stored mid entry. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { + return False; + } + + return True; +} + +/*********************************************************** + Is client signing on ? +************************************************************/ + +bool client_is_signing_on(struct cli_state *cli) +{ + struct smb_sign_info *si = &cli->sign_info; + return si->doing_signing; +} + +/*********************************************************** + SMB signing - Server implementation - send the MAC. +************************************************************/ + +static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; + uint32 send_seq_number = data->send_seq_num-1; + uint16 mid; + + if (!si->doing_signing) { + return; + } + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(outbuf); + + mid = SVAL(outbuf, smb_mid); + + /* See if this is a reply for a deferred packet. */ + get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + + simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); + + DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); + dump_data(10, calc_md5_mac, 8); + + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote client actually verifies signatures...*/ +} + +/*********************************************************** + SMB signing - Server implementation - check a MAC sent by server. +************************************************************/ + +static bool srv_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + bool must_be_ok) +{ + bool good; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; + uint32 reply_seq_number = data->send_seq_num; + uint32 saved_seq; + unsigned char calc_md5_mac[16]; + unsigned char *server_sent_mac; + + if (!si->doing_signing) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + + /* We always increment the sequence number. */ + data->send_seq_num += 2; + + saved_seq = reply_seq_number; + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + + server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (!good) { + + if (saved_seq) { + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", + (unsigned int)saved_seq)); + dump_data(5, calc_md5_mac, 8); + + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + (unsigned int)reply_seq_number)); + dump_data(5, server_sent_mac, 8); + } + +#if 1 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ +We were expecting seq %u\n", reply_seq_number, saved_seq )); + break; + } + } + } +#endif /* JRATEST */ + + } else { + DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); + dump_data(10, server_sent_mac, 8); + } + + return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); +} + +/*********************************************************** + SMB signing - server API's. +************************************************************/ + +static struct smb_sign_info srv_sign_info = { + null_sign_outgoing_message, + null_check_incoming_message, + null_free_signing_context, + NULL, + False, + False, + False, + False +}; + +/*********************************************************** + Turn signing off or on for oplock break code. +************************************************************/ + +bool srv_oplock_set_signing(bool onoff) +{ + bool ret = srv_sign_info.doing_signing; + srv_sign_info.doing_signing = onoff; + return ret; +} + +/*********************************************************** + Called to validate an incoming packet from the client. +************************************************************/ + +bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) +{ + /* Check if it's a non-session message. */ + if(CVAL(inbuf,0)) { + return True; + } + + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); +} + +/*********************************************************** + Called to sign an outgoing packet to the client. +************************************************************/ + +void srv_calculate_sign_mac(char *outbuf) +{ + /* Check if it's a non-session message. */ + if(CVAL(outbuf,0)) { + return; + } + + srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); +} + +/*********************************************************** + Called by server to defer an outgoing packet. +************************************************************/ + +void srv_defer_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + if (!data) + return; + + /* + * Ensure we only store this mid reply once... + */ + + store_sequence_for_reply(&data->outstanding_packet_list, mid, + data->send_seq_num-1); +} + +/*********************************************************** + Called to remove sequence records when a deferred packet is + cancelled by mid. This should never find one.... +************************************************************/ + +void srv_cancel_sign_response(uint16 mid, bool cancel) +{ + struct smb_basic_signing_context *data; + uint32 dummy_seq; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + if (!data) + return; + + DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); + + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) + ; + + /* cancel doesn't send a reply so doesn't burn a sequence number. */ + if (cancel) { + data->send_seq_num -= 1; + } +} + +/*********************************************************** + Called by server negprot when signing has been negotiated. +************************************************************/ + +void srv_set_signing_negotiated(void) +{ + srv_sign_info.allow_smb_signing = True; + srv_sign_info.negotiated_smb_signing = True; + if (lp_server_signing() == Required) + srv_sign_info.mandatory_signing = True; + + srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; + srv_sign_info.check_incoming_message = temp_check_incoming_message; + srv_sign_info.free_signing_context = temp_free_signing_context; +} + +/*********************************************************** + Returns whether signing is active. We can't use sendfile or raw + reads/writes if it is. +************************************************************/ + +bool srv_is_signing_active(void) +{ + return srv_sign_info.doing_signing; +} + + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +bool srv_is_signing_negotiated(void) +{ + return srv_sign_info.negotiated_smb_signing; +} + +/*********************************************************** + Returns whether signing is actually happening +************************************************************/ + +bool srv_signing_started(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) { + return False; + } + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return False; + + if (data->send_seq_num == 0) { + return False; + } + + return True; +} + +/*********************************************************** + Turn on signing from this packet onwards. +************************************************************/ + +void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!user_session_key.length) + return; + + if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { + DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", + (unsigned int)srv_sign_info.negotiated_smb_signing, + (unsigned int)srv_sign_info.mandatory_signing )); + return; + } + + /* Once we've turned on, ignore any more sessionsetups. */ + if (srv_sign_info.doing_signing) { + return; + } + + if (srv_sign_info.free_signing_context) + srv_sign_info.free_signing_context(&srv_sign_info); + + srv_sign_info.doing_signing = True; + + data = SMB_XMALLOC_P(struct smb_basic_signing_context); + memset(data, '\0', sizeof(*data)); + + srv_sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, response.length + user_session_key.length); + + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); + if (response.length) + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + + DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", + BOOLSTR(srv_sign_info.negotiated_smb_signing), + BOOLSTR(srv_sign_info.mandatory_signing) )); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + + srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; + srv_sign_info.check_incoming_message = srv_check_incoming_message; + srv_sign_info.free_signing_context = simple_free_signing_context; +} diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c deleted file mode 100644 index a3ed0e7572..0000000000 --- a/source3/libsmb/smb_signing.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB Signing Code - Copyright (C) Jeremy Allison 2003. - Copyright (C) Andrew Bartlett 2002-2003 - - 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" - -/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ -struct outstanding_packet_lookup { - struct outstanding_packet_lookup *prev, *next; - uint16 mid; - uint32 reply_seq_num; - bool can_delete; /* Set to False in trans state. */ -}; - -struct smb_basic_signing_context { - DATA_BLOB mac_key; - uint32 send_seq_num; - struct outstanding_packet_lookup *outstanding_packet_list; -}; - -static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num) -{ - struct outstanding_packet_lookup *t; - - /* Ensure we only add a mid once. */ - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - return False; - } - } - - t = SMB_XMALLOC_P(struct outstanding_packet_lookup); - ZERO_STRUCTP(t); - - t->mid = mid; - t->reply_seq_num = reply_seq_num; - t->can_delete = True; - - /* - * Add to the *start* of the list not the end of the list. - * This ensures that the *last* send sequence with this mid - * is returned by preference. - * This can happen if the mid wraps and one of the early - * mid numbers didn't get a reply and is still lurking on - * the list. JRA. Found by Fran Fabrizio . - */ - - DLIST_ADD(*list, t); - DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", - (unsigned int)reply_seq_num, (unsigned int)mid )); - return True; -} - -static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - *reply_seq_num = t->reply_seq_num; - DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", - (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - if (t->can_delete) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - } - return True; - } - } - return False; -} - -static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - t->can_delete = can_delete_entry; - return True; - } - } - return False; -} - -/*********************************************************** - SMB signing - Common code before we set a new signing implementation -************************************************************/ - -static bool cli_set_smb_signing_common(struct cli_state *cli) -{ - if (!cli->sign_info.allow_smb_signing) { - return False; - } - - if (!cli->sign_info.negotiated_smb_signing - && !cli->sign_info.mandatory_signing) { - return False; - } - - if (cli->sign_info.doing_signing) { - return False; - } - - if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(&cli->sign_info); - - /* These calls are INCOMPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - return True; -} - -/*********************************************************** - SMB signing - Common code for 'real' implementations -************************************************************/ - -static bool set_smb_signing_real_common(struct smb_sign_info *si) -{ - if (si->mandatory_signing) { - DEBUG(5, ("Mandatory SMB signing enabled!\n")); - } - - si->doing_signing = True; - DEBUG(5, ("SMB signing enabled!\n")); - - return True; -} - -static void mark_packet_signed(char *outbuf) -{ - uint16 flags2; - flags2 = SVAL(outbuf,smb_flg2); - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(outbuf,smb_flg2, flags2); -} - -/*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. -************************************************************/ - -static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - /* we can't zero out the sig, as we might be trying to send a - session request - which is NBT-level, not SMB level and doesn't - have the field */ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ - -static bool null_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - return True; -} - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ - -static void null_free_signing_context(struct smb_sign_info *si) -{ - return; -} - -/** - SMB signing - NULL implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ - -static bool null_set_signing(struct smb_sign_info *si) -{ - si->signing_context = NULL; - - si->sign_outgoing_message = null_sign_outgoing_message; - si->check_incoming_message = null_check_incoming_message; - si->free_signing_context = null_free_signing_context; - - return True; -} - -/** - * Free the signing context - */ - -static void free_signing_context(struct smb_sign_info *si) -{ - if (si->free_signing_context) { - si->free_signing_context(si); - si->signing_context = NULL; - } - - null_set_signing(si); -} - - -static bool signing_good(const char *inbuf, struct smb_sign_info *si, - bool good, uint32 seq, bool must_be_ok) -{ - if (good) { - - if (!si->doing_signing) { - si->doing_signing = True; - } - - if (!si->seen_valid) { - si->seen_valid = True; - } - - } else { - if (!si->mandatory_signing && !si->seen_valid) { - - if (!must_be_ok) { - return True; - } - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" - "isn't sending correct signatures. Turning off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else if (!must_be_ok) { - /* This packet is known to be unsigned */ - return True; - } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (seq) - DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); - return False; - } - } - return True; -} - -/*********************************************************** - SMB signing - Simple implementation - calculate a MAC on the packet -************************************************************/ - -static void simple_packet_signature(struct smb_basic_signing_context *data, - const uchar *buf, uint32 seq_number, - unsigned char calc_md5_mac[16]) -{ - const size_t offset_end_of_sig = (smb_ss_field + 8); - unsigned char sequence_buf[8]; - struct MD5Context md5_ctx; -#if 0 - /* JRA - apparently this is incorrect. */ - unsigned char key_buf[16]; -#endif - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - * - * We do this here, to avoid modifying the packet. - */ - - DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); - - SIVAL(sequence_buf, 0, seq_number); - SIVAL(sequence_buf, 4, 0); - - /* Calculate the 16 byte MAC - but don't alter the data in the - incoming packet. - - This makes for a bit of fussing about, but it's not too bad. - */ - MD5Init(&md5_ctx); - - /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); -#if 0 - /* JRA - apparently this is incorrect. */ - /* NB. When making and verifying SMB signatures, Windows apparently - zero-pads the key to 128 bits if it isn't long enough. - From Nalin Dahyabhai */ - if (data->mac_key.length < sizeof(key_buf)) { - memset(key_buf, 0, sizeof(key_buf)); - MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); - } -#endif - - /* copy in the first bit of the SMB header */ - MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); - - /* copy in the sequence number, instead of the signature */ - MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); - - /* copy in the rest of the packet in, skipping the signature */ - MD5Update(&md5_ctx, buf + offset_end_of_sig, - smb_len(buf) - (offset_end_of_sig - 4)); - - /* calculate the MD5 sig */ - MD5Final(calc_md5_mac, &md5_ctx); -} - - -/*********************************************************** - SMB signing - Client implementation - send the MAC. -************************************************************/ - -static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) - return; - - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - simple_packet_signature(data, (const unsigned char *)outbuf, - data->send_seq_num, calc_md5_mac); - - DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, calc_md5_mac, 8); - - memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signatures...*/ - - /* Instead of re-introducing the trans_info_conect we - used to have here, we use the fact that during a - SMBtrans/SMBtrans2/SMBnttrans send that the mid stays - constant. This means that calling store_sequence_for_reply() - will return False for all trans secondaries, as the mid is already - on the stored sequence list. As the send_seqence_number must - remain constant for all primary+secondary trans sends, we - only increment the send sequence number when we successfully - add a new entry to the outstanding sequence list. This means - I can isolate the fix here rather than re-adding the trans - signing on/off calls in libsmb/clitrans2.c JRA. - */ - - if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { - data->send_seq_num += 2; - } -} - -/*********************************************************** - SMB signing - Client implementation - check a MAC sent by server. -************************************************************/ - -static bool client_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - bool good; - uint32 reply_seq_number; - unsigned char calc_md5_mac[16]; - unsigned char *server_sent_mac; - - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) - return True; - - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); - return False; - } - - if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { - DEBUG(1, ("client_check_incoming_message: received message " - "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) )); - return False; - } - - simple_packet_signature(data, (const unsigned char *)inbuf, - reply_seq_number, calc_md5_mac); - - server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; - good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - - if (!good) { - DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, calc_md5_mac, 8); - - DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, server_sent_mac, 8); -#if 1 /* JRATEST */ - { - int i; - for (i = -5; i < 5; i++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac); - if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); - break; - } - } - } -#endif /* JRATEST */ - - } else { - DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, server_sent_mac, 8); - } - return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); -} - -/*********************************************************** - SMB signing - Simple implementation - free signing context -************************************************************/ - -static void simple_free_signing_context(struct smb_sign_info *si) -{ - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - struct outstanding_packet_lookup *list; - struct outstanding_packet_lookup *next; - - for (list = data->outstanding_packet_list; list; list = next) { - next = list->next; - DLIST_REMOVE(data->outstanding_packet_list, list); - SAFE_FREE(list); - } - - data_blob_free(&data->mac_key); - - SAFE_FREE(si->signing_context); - - return; -} - -/*********************************************************** - SMB signing - Simple implementation - setup the MAC key. -************************************************************/ - -bool cli_simple_set_signing(struct cli_state *cli, - const DATA_BLOB user_session_key, - const DATA_BLOB response) -{ - struct smb_basic_signing_context *data; - - if (!user_session_key.length) - return False; - - if (!cli_set_smb_signing_common(cli)) { - return False; - } - - if (!set_smb_signing_real_common(&cli->sign_info)) { - return False; - } - - data = SMB_XMALLOC_P(struct smb_basic_signing_context); - memset(data, '\0', sizeof(*data)); - - cli->sign_info.signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); - - DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, user_session_key.data, user_session_key.length); - - if (response.length) { - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); - DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, response.data, response.length); - } else { - DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); - } - - dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); - - /* Initialise the sequence number */ - data->send_seq_num = 0; - - /* Initialise the list of outstanding packets */ - data->outstanding_packet_list = NULL; - - cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; - cli->sign_info.check_incoming_message = client_check_incoming_message; - cli->sign_info.free_signing_context = simple_free_signing_context; - - return True; -} - -/*********************************************************** - SMB signing - TEMP implementation - calculate a MAC to send. -************************************************************/ - -static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - /* I wonder what BSRSPYL stands for - but this is what MS - actually sends! */ - memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); - return; -} - -/*********************************************************** - SMB signing - TEMP implementation - check a MAC sent by server. -************************************************************/ - -static bool temp_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, bool foo) -{ - return True; -} - -/*********************************************************** - SMB signing - TEMP implementation - free signing context -************************************************************/ - -static void temp_free_signing_context(struct smb_sign_info *si) -{ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - setup the MAC key. -************************************************************/ - -bool cli_null_set_signing(struct cli_state *cli) -{ - return null_set_signing(&cli->sign_info); -} - -/*********************************************************** - SMB signing - temp implementation - setup the MAC key. -************************************************************/ - -bool cli_temp_set_signing(struct cli_state *cli) -{ - if (!cli_set_smb_signing_common(cli)) { - return False; - } - - cli->sign_info.signing_context = NULL; - - cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; - cli->sign_info.check_incoming_message = temp_check_incoming_message; - cli->sign_info.free_signing_context = temp_free_signing_context; - - return True; -} - -void cli_free_signing_context(struct cli_state *cli) -{ - free_signing_context(&cli->sign_info); -} - -/** - * Sign a packet with the current mechanism - */ - -void cli_calculate_sign_mac(struct cli_state *cli, char *buf) -{ - cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); -} - -/** - * Check a packet with the current mechanism - * @return False if we had an established signing connection - * which had a bad checksum, True otherwise. - */ - -bool cli_check_sign_mac(struct cli_state *cli, char *buf) -{ - if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { - free_signing_context(&cli->sign_info); - return False; - } - return True; -} - -/*********************************************************** - Enter trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) -{ - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { - return False; - } - - return True; -} - -/*********************************************************** - Leave trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) -{ - uint32 reply_seq_num; - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { - return False; - } - - /* Now delete the stored mid entry. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { - return False; - } - - return True; -} - -/*********************************************************** - Is client signing on ? -************************************************************/ - -bool client_is_signing_on(struct cli_state *cli) -{ - struct smb_sign_info *si = &cli->sign_info; - return si->doing_signing; -} - -/*********************************************************** - SMB signing - Server implementation - send the MAC. -************************************************************/ - -static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - uint32 send_seq_number = data->send_seq_num-1; - uint16 mid; - - if (!si->doing_signing) { - return; - } - - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - mid = SVAL(outbuf, smb_mid); - - /* See if this is a reply for a deferred packet. */ - get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); - - simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); - - DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); - dump_data(10, calc_md5_mac, 8); - - memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote client actually verifies signatures...*/ -} - -/*********************************************************** - SMB signing - Server implementation - check a MAC sent by server. -************************************************************/ - -static bool srv_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - bool good; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - uint32 reply_seq_number = data->send_seq_num; - uint32 saved_seq; - unsigned char calc_md5_mac[16]; - unsigned char *server_sent_mac; - - if (!si->doing_signing) - return True; - - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); - return False; - } - - /* We always increment the sequence number. */ - data->send_seq_num += 2; - - saved_seq = reply_seq_number; - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - - server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; - good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - - if (!good) { - - if (saved_seq) { - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", - (unsigned int)saved_seq)); - dump_data(5, calc_md5_mac, 8); - - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", - (unsigned int)reply_seq_number)); - dump_data(5, server_sent_mac, 8); - } - -#if 1 /* JRATEST */ - { - int i; - reply_seq_number -= 5; - for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number, saved_seq )); - break; - } - } - } -#endif /* JRATEST */ - - } else { - DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, server_sent_mac, 8); - } - - return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); -} - -/*********************************************************** - SMB signing - server API's. -************************************************************/ - -static struct smb_sign_info srv_sign_info = { - null_sign_outgoing_message, - null_check_incoming_message, - null_free_signing_context, - NULL, - False, - False, - False, - False -}; - -/*********************************************************** - Turn signing off or on for oplock break code. -************************************************************/ - -bool srv_oplock_set_signing(bool onoff) -{ - bool ret = srv_sign_info.doing_signing; - srv_sign_info.doing_signing = onoff; - return ret; -} - -/*********************************************************** - Called to validate an incoming packet from the client. -************************************************************/ - -bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) -{ - /* Check if it's a non-session message. */ - if(CVAL(inbuf,0)) { - return True; - } - - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); -} - -/*********************************************************** - Called to sign an outgoing packet to the client. -************************************************************/ - -void srv_calculate_sign_mac(char *outbuf) -{ - /* Check if it's a non-session message. */ - if(CVAL(outbuf,0)) { - return; - } - - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); -} - -/*********************************************************** - Called by server to defer an outgoing packet. -************************************************************/ - -void srv_defer_sign_response(uint16 mid) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - - if (!data) - return; - - /* - * Ensure we only store this mid reply once... - */ - - store_sequence_for_reply(&data->outstanding_packet_list, mid, - data->send_seq_num-1); -} - -/*********************************************************** - Called to remove sequence records when a deferred packet is - cancelled by mid. This should never find one.... -************************************************************/ - -void srv_cancel_sign_response(uint16 mid, bool cancel) -{ - struct smb_basic_signing_context *data; - uint32 dummy_seq; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - - if (!data) - return; - - DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); - - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) - ; - - /* cancel doesn't send a reply so doesn't burn a sequence number. */ - if (cancel) { - data->send_seq_num -= 1; - } -} - -/*********************************************************** - Called by server negprot when signing has been negotiated. -************************************************************/ - -void srv_set_signing_negotiated(void) -{ - srv_sign_info.allow_smb_signing = True; - srv_sign_info.negotiated_smb_signing = True; - if (lp_server_signing() == Required) - srv_sign_info.mandatory_signing = True; - - srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; - srv_sign_info.check_incoming_message = temp_check_incoming_message; - srv_sign_info.free_signing_context = temp_free_signing_context; -} - -/*********************************************************** - Returns whether signing is active. We can't use sendfile or raw - reads/writes if it is. -************************************************************/ - -bool srv_is_signing_active(void) -{ - return srv_sign_info.doing_signing; -} - - -/*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. -************************************************************/ - -bool srv_is_signing_negotiated(void) -{ - return srv_sign_info.negotiated_smb_signing; -} - -/*********************************************************** - Returns whether signing is actually happening -************************************************************/ - -bool srv_signing_started(void) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) { - return False; - } - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data) - return False; - - if (data->send_seq_num == 0) { - return False; - } - - return True; -} - -/*********************************************************** - Turn on signing from this packet onwards. -************************************************************/ - -void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) -{ - struct smb_basic_signing_context *data; - - if (!user_session_key.length) - return; - - if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { - DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", - (unsigned int)srv_sign_info.negotiated_smb_signing, - (unsigned int)srv_sign_info.mandatory_signing )); - return; - } - - /* Once we've turned on, ignore any more sessionsetups. */ - if (srv_sign_info.doing_signing) { - return; - } - - if (srv_sign_info.free_signing_context) - srv_sign_info.free_signing_context(&srv_sign_info); - - srv_sign_info.doing_signing = True; - - data = SMB_XMALLOC_P(struct smb_basic_signing_context); - memset(data, '\0', sizeof(*data)); - - srv_sign_info.signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); - if (response.length) - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); - - dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); - - DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", - BOOLSTR(srv_sign_info.negotiated_smb_signing), - BOOLSTR(srv_sign_info.mandatory_signing) )); - - /* Initialise the sequence number */ - data->send_seq_num = 0; - - /* Initialise the list of outstanding packets */ - data->outstanding_packet_list = NULL; - - srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; - srv_sign_info.check_incoming_message = srv_check_incoming_message; - srv_sign_info.free_signing_context = simple_free_signing_context; -} -- cgit From 2654653f55ed5744cc9fca6a79127386f55425e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Mar 2009 08:42:05 +0100 Subject: s3:libsmb: add a much simplified smb_siging infrastructure It's the job of the caller to maintain the seqnum/mid mapping. Hopefully we can use this code in s4 later too. metze --- source3/Makefile.in | 3 +- source3/include/includes.h | 1 + source3/include/smb_signing.h | 46 ++++++ source3/libsmb/smb_signing.c | 370 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 source3/include/smb_signing.h create mode 100644 source3/libsmb/smb_signing.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 0db6f62c5c..8dbb7b5d67 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -364,7 +364,8 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \ lib/substitute.o lib/dbwrap_util.o \ lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \ - lib/tallocmsg.o lib/dmallocmsg.o libsmb/clisigning.o \ + lib/tallocmsg.o lib/dmallocmsg.o \ + libsmb/clisigning.o libsmb/smb_signing.o \ lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \ lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \ lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \ diff --git a/source3/include/includes.h b/source3/include/includes.h index 4bf4b5c735..c883e17713 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -598,6 +598,7 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "messages.h" #include "locking.h" #include "smb_perfcount.h" +#include "smb_signing.h" #include "smb.h" #include "nameserv.h" #include "secrets.h" diff --git a/source3/include/smb_signing.h b/source3/include/smb_signing.h new file mode 100644 index 0000000000..770c40cb35 --- /dev/null +++ b/source3/include/smb_signing.h @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett 2002-2003 + Copyright (C) Stefan Metzmacher 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 . +*/ + +#ifndef _SMB_SIGNING_H_ +#define _SMB_SIGNING_H_ + +struct smb_signing_state; + +struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx, + bool allowed, + bool mandatory); +uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway); +void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway); +void smb_signing_sign_pdu(struct smb_signing_state *si, + uint8_t *outbuf, uint32_t seqnum); +bool smb_signing_check_pdu(struct smb_signing_state *si, + const uint8_t *inbuf, uint32_t seqnum); +bool smb_signing_set_bsrspyl(struct smb_signing_state *si); +bool smb_signing_activate(struct smb_signing_state *si, + const DATA_BLOB user_session_key, + const DATA_BLOB response); +bool smb_signing_is_active(struct smb_signing_state *si); +bool smb_signing_is_allowed(struct smb_signing_state *si); +bool smb_signing_is_mandatory(struct smb_signing_state *si); +bool smb_signing_set_negotiated(struct smb_signing_state *si); +bool smb_signing_is_negotiated(struct smb_signing_state *si); + +#endif /* _SMB_SIGNING_H_ */ diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c new file mode 100644 index 0000000000..32d2883965 --- /dev/null +++ b/source3/libsmb/smb_signing.c @@ -0,0 +1,370 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett 2002-2003 + Copyright (C) Stefan Metzmacher 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" + +/* Used by the SMB signing functions. */ + +struct smb_signing_state { + /* is signing localy allowed */ + bool allowed; + + /* is signing localy mandatory */ + bool mandatory; + + /* is signing negotiated by the peer */ + bool negotiated; + + /* send BSRSPYL signatures */ + bool bsrspyl; + + bool active; /* Have I ever seen a validly signed packet? */ + + /* mac_key.length > 0 means signing is started */ + DATA_BLOB mac_key; + + /* the next expected seqnum */ + uint32_t seqnum; +}; + +static void smb_signing_reset_info(struct smb_signing_state *si) +{ + si->active = false; + si->bsrspyl = false; + data_blob_free(&si->mac_key); + si->seqnum = 0; +} + +struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx, + bool allowed, + bool mandatory) +{ + struct smb_signing_state *si; + + si = talloc_zero(mem_ctx, struct smb_signing_state); + if (si == NULL) { + return NULL; + } + + if (mandatory) { + allowed = true; + } + + si->allowed = allowed; + si->mandatory = mandatory; + + return si; +} + +static bool smb_signing_good(struct smb_signing_state *si, + bool good, uint32_t seq) +{ + if (good) { + if (!si->active) { + si->active = true; + } + return true; + } + + if (!si->mandatory && !si->active) { + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("smb_signing_good: signing negotiated but not required and peer\n" + "isn't sending correct signatures. Turning off.\n")); + smb_signing_reset_info(si); + return true; + } + + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + DEBUG(0, ("smb_signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); + return false; +} + +static void smb_signing_md5(const DATA_BLOB *mac_key, + const uint8_t *buf, uint32_t seq_number, + uint8_t calc_md5_mac[16]) +{ + const size_t offset_end_of_sig = (smb_ss_field + 8); + uint8_t sequence_buf[8]; + struct MD5Context md5_ctx; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + * + * We do this here, to avoid modifying the packet. + */ + + DEBUG(10,("smb_signing_md5: sequence number %u\n", seq_number )); + + SIVAL(sequence_buf, 0, seq_number); + SIVAL(sequence_buf, 4, 0); + + /* Calculate the 16 byte MAC - but don't alter the data in the + incoming packet. + + This makes for a bit of fussing about, but it's not too bad. + */ + MD5Init(&md5_ctx); + + /* intialise with the key */ + MD5Update(&md5_ctx, mac_key->data, mac_key->length); + + /* copy in the first bit of the SMB header */ + MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + /* copy in the rest of the packet in, skipping the signature */ + MD5Update(&md5_ctx, buf + offset_end_of_sig, + smb_len(buf) - (offset_end_of_sig - 4)); + + /* calculate the MD5 sig */ + MD5Final(calc_md5_mac, &md5_ctx); +} + +uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway) +{ + uint32_t seqnum; + + if (si->mac_key.length == 0) { + return 0; + } + + seqnum = si->seqnum; + if (oneway) { + si->seqnum += 1; + } else { + si->seqnum += 2; + } + + return seqnum; +} + +void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway) +{ + if (si->mac_key.length == 0) { + return; + } + + if (oneway) { + si->seqnum -= 1; + } else { + si->seqnum -= 2; + } +} + +void smb_signing_sign_pdu(struct smb_signing_state *si, + uint8_t *outbuf, uint32_t seqnum) +{ + uint8_t calc_md5_mac[16]; + uint16_t flags2; + + if (si->mac_key.length == 0) { + if (!si->bsrspyl) { + return; + } + } + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1,("smb_signing_sign_pdu: Logic error. " + "Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf))); + abort(); + } + + /* mark the packet as signed - BEFORE we sign it...*/ + flags2 = SVAL(outbuf,smb_flg2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(outbuf, smb_flg2, flags2); + + if (si->bsrspyl) { + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy(calc_md5_mac, "BSRSPYL ", 8); + } else { + smb_signing_md5(&si->mac_key, outbuf, + seqnum, calc_md5_mac); + } + + DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); + +/* outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signatures...*/ +} + +bool smb_signing_check_pdu(struct smb_signing_state *si, + const uint8_t *inbuf, uint32_t seqnum) +{ + bool good; + uint8_t calc_md5_mac[16]; + const uint8_t *reply_sent_mac; + + if (si->mac_key.length == 0) { + return true; + } + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1,("smb_signing_check_pdu: Can't check signature " + "on short packet! smb_len = %u\n", + smb_len(inbuf))); + return False; + } + + smb_signing_md5(&si->mac_key, inbuf, + seqnum, calc_md5_mac); + + reply_sent_mac = &inbuf[smb_ss_field]; + good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0); + + if (!good) { + int i; + const int sign_range = 5; + + DEBUG(5, ("smb_signing_check_pdu: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("smb_signing_check_pdu: BAD SIG: got SMB signature of\n")); + dump_data(5, reply_sent_mac, 8); + + for (i = -sign_range; i < sign_range; i++) { + smb_signing_md5(&si->mac_key, inbuf, + seqnum+i, calc_md5_mac); + if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("smb_signing_check_pdu: " + "out of seq. seq num %u matches. " + "We were expecting seq %u\n", + (unsigned int)seqnum+i, + (unsigned int)seqnum)); + break; + } + } + } else { + DEBUG(10, ("smb_signing_check_pdu: seq %u: " + "got good SMB signature of\n", + (unsigned int)seqnum)); + dump_data(10, reply_sent_mac, 8); + } + + return smb_signing_good(si, good, seqnum); +} + +bool smb_signing_set_bsrspyl(struct smb_signing_state *si) +{ + if (!si->negotiated) { + return false; + } + + if (si->active) { + return false; + } + + si->bsrspyl = true; + + return true; +} + +bool smb_signing_activate(struct smb_signing_state *si, + const DATA_BLOB user_session_key, + const DATA_BLOB response) +{ + size_t len; + off_t ofs; + + if (!user_session_key.length) { + return false; + } + + if (!si->negotiated) { + return false; + } + + if (si->active) { + return false; + } + + if (si->mac_key.length > 0) { + return false; + } + + smb_signing_reset_info(si); + + len = response.length + user_session_key.length; + si->mac_key = data_blob_talloc(si, NULL, len); + + ofs = 0; + memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length); + + DEBUG(10, ("smb_signing_activate: user_session_key\n")); + dump_data(10, user_session_key.data, user_session_key.length); + + if (response.length) { + ofs = user_session_key.length; + memcpy(&si->mac_key.data[ofs], response.data, response.length); + DEBUG(10, ("smb_signing_activate: response_data\n")); + dump_data(10, response.data, response.length); + } else { + DEBUG(10, ("smb_signing_activate: NULL response_data\n")); + } + + dump_data_pw("smb_signing_activate: mac key is:\n", + si->mac_key.data, si->mac_key.length); + + /* Initialise the sequence number */ + si->seqnum = 2; + + return true; +} + +bool smb_signing_is_active(struct smb_signing_state *si) +{ + return si->active; +} + +bool smb_signing_is_allowed(struct smb_signing_state *si) +{ + return si->allowed; +} + +bool smb_signing_is_mandatory(struct smb_signing_state *si) +{ + return si->mandatory; +} + +bool smb_signing_set_negotiated(struct smb_signing_state *si) +{ + if (!si->allowed) { + return false; + } + + si->negotiated = true; + + return true; +} + +bool smb_signing_is_negotiated(struct smb_signing_state *si) +{ + return si->negotiated; +} -- cgit From c16c90a1cb3b0e2ceadd3dea835a4e69acfc2fae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Mar 2009 09:47:59 +0100 Subject: s3:smbd: use new simplified snb_signing code in the server We keep the seqnum/mid mapping in the smb_request structure. This also moves one global variable into the smbd_server_connection struct. metze --- source3/Makefile.in | 2 +- source3/include/proto.h | 32 +++-- source3/include/smb.h | 2 + source3/libsmb/clisigning.c | 333 -------------------------------------------- source3/param/loadparm.c | 11 +- source3/smbd/aio.c | 13 +- source3/smbd/blocking.c | 5 +- source3/smbd/globals.h | 1 + source3/smbd/ipc.c | 4 + source3/smbd/negprot.c | 2 +- source3/smbd/notify.c | 7 +- source3/smbd/nttrans.c | 3 +- source3/smbd/open.c | 9 -- source3/smbd/oplock.c | 27 +--- source3/smbd/password.c | 8 +- source3/smbd/pipes.c | 1 + source3/smbd/process.c | 50 +++++-- source3/smbd/reply.c | 24 ++-- source3/smbd/service.c | 2 +- source3/smbd/sesssetup.c | 25 ---- source3/smbd/signing.c | 158 +++++++++++++++++++++ source3/smbd/trans2.c | 5 +- 22 files changed, 270 insertions(+), 454 deletions(-) create mode 100644 source3/smbd/signing.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 8dbb7b5d67..46216c7f08 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -733,7 +733,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/change_trust_pw.o smbd/fake_file.o \ smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \ $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \ - smbd/dmapi.o \ + smbd/dmapi.o smbd/signing.o \ smbd/file_access.o \ smbd/dnsregister.o smbd/globals.o \ $(MANGLE_OBJ) @VFS_STATIC@ diff --git a/source3/include/proto.h b/source3/include/proto.h index 1ed623c4cb..356eb4935f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3194,16 +3194,22 @@ bool cli_check_sign_mac(struct cli_state *cli, char *buf); bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid); bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid); bool client_is_signing_on(struct cli_state *cli); -bool srv_oplock_set_signing(bool onoff); -bool srv_check_sign_mac(const char *inbuf, bool must_be_ok); -void srv_calculate_sign_mac(char *outbuf); -void srv_defer_sign_response(uint16 mid); -void srv_cancel_sign_response(uint16 mid, bool cancel); -void srv_set_signing_negotiated(void); -bool srv_is_signing_active(void); -bool srv_is_signing_negotiated(void); -bool srv_signing_started(void); -void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response); + +/* The following definitions come from smbd/signing.c */ + +struct smbd_server_connection; +bool srv_check_sign_mac(struct smbd_server_connection *conn, + const char *inbuf, uint32_t *seqnum); +void srv_calculate_sign_mac(struct smbd_server_connection *conn, + char *outbuf, uint32_t seqnum); +void srv_cancel_sign_response(struct smbd_server_connection *conn); +bool srv_init_signing(struct smbd_server_connection *conn); +void srv_set_signing_negotiated(struct smbd_server_connection *conn); +bool srv_is_signing_active(struct smbd_server_connection *conn); +bool srv_is_signing_negotiated(struct smbd_server_connection *conn); +void srv_set_signing(struct smbd_server_connection *conn, + const DATA_BLOB user_session_key, + const DATA_BLOB response); /* The following definitions come from libsmb/smbdes.c */ @@ -4347,7 +4353,7 @@ const char *lp_printcapname(void); bool lp_disable_spoolss( void ); void lp_set_spoolss_state( uint32 state ); uint32 lp_get_spoolss_state( void ); -bool lp_use_sendfile(int snum); +bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state); void set_use_sendfile(int snum, bool val); void set_store_dos_attributes(int snum, bool val); void lp_set_mangling_method(const char *new_method); @@ -6722,7 +6728,9 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname); void smbd_setup_sig_term_handler(void); void smbd_setup_sig_hup_handler(void); -bool srv_send_smb(int fd, char *buffer, bool do_encrypt, +bool srv_send_smb(int fd, char *buffer, + bool no_signing, uint32_t seqnum, + bool do_encrypt, struct smb_perfcount_data *pcd); int srv_set_message(char *buf, int num_words, diff --git a/source3/include/smb.h b/source3/include/smb.h index 281a218256..215adba1b4 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -621,6 +621,7 @@ struct smb_request { uint16 flags2; uint16 smbpid; uint16 mid; + uint32_t seqnum; uint16 vuid; uint16 tid; uint8 wct; @@ -722,6 +723,7 @@ struct pending_message_list { struct timeval request_time; /* When was this first issued? */ struct timed_event *te; struct smb_perfcount_data pcd; + uint32_t seqnum; bool encrypted; DATA_BLOB buf; DATA_BLOB private_data; diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c index a3ed0e7572..6644bc0d60 100644 --- a/source3/libsmb/clisigning.c +++ b/source3/libsmb/clisigning.c @@ -671,336 +671,3 @@ bool client_is_signing_on(struct cli_state *cli) struct smb_sign_info *si = &cli->sign_info; return si->doing_signing; } - -/*********************************************************** - SMB signing - Server implementation - send the MAC. -************************************************************/ - -static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - uint32 send_seq_number = data->send_seq_num-1; - uint16 mid; - - if (!si->doing_signing) { - return; - } - - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - mid = SVAL(outbuf, smb_mid); - - /* See if this is a reply for a deferred packet. */ - get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); - - simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); - - DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); - dump_data(10, calc_md5_mac, 8); - - memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote client actually verifies signatures...*/ -} - -/*********************************************************** - SMB signing - Server implementation - check a MAC sent by server. -************************************************************/ - -static bool srv_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - bool good; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - uint32 reply_seq_number = data->send_seq_num; - uint32 saved_seq; - unsigned char calc_md5_mac[16]; - unsigned char *server_sent_mac; - - if (!si->doing_signing) - return True; - - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); - return False; - } - - /* We always increment the sequence number. */ - data->send_seq_num += 2; - - saved_seq = reply_seq_number; - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - - server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; - good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - - if (!good) { - - if (saved_seq) { - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", - (unsigned int)saved_seq)); - dump_data(5, calc_md5_mac, 8); - - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", - (unsigned int)reply_seq_number)); - dump_data(5, server_sent_mac, 8); - } - -#if 1 /* JRATEST */ - { - int i; - reply_seq_number -= 5; - for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number, saved_seq )); - break; - } - } - } -#endif /* JRATEST */ - - } else { - DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, server_sent_mac, 8); - } - - return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); -} - -/*********************************************************** - SMB signing - server API's. -************************************************************/ - -static struct smb_sign_info srv_sign_info = { - null_sign_outgoing_message, - null_check_incoming_message, - null_free_signing_context, - NULL, - False, - False, - False, - False -}; - -/*********************************************************** - Turn signing off or on for oplock break code. -************************************************************/ - -bool srv_oplock_set_signing(bool onoff) -{ - bool ret = srv_sign_info.doing_signing; - srv_sign_info.doing_signing = onoff; - return ret; -} - -/*********************************************************** - Called to validate an incoming packet from the client. -************************************************************/ - -bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) -{ - /* Check if it's a non-session message. */ - if(CVAL(inbuf,0)) { - return True; - } - - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); -} - -/*********************************************************** - Called to sign an outgoing packet to the client. -************************************************************/ - -void srv_calculate_sign_mac(char *outbuf) -{ - /* Check if it's a non-session message. */ - if(CVAL(outbuf,0)) { - return; - } - - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); -} - -/*********************************************************** - Called by server to defer an outgoing packet. -************************************************************/ - -void srv_defer_sign_response(uint16 mid) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - - if (!data) - return; - - /* - * Ensure we only store this mid reply once... - */ - - store_sequence_for_reply(&data->outstanding_packet_list, mid, - data->send_seq_num-1); -} - -/*********************************************************** - Called to remove sequence records when a deferred packet is - cancelled by mid. This should never find one.... -************************************************************/ - -void srv_cancel_sign_response(uint16 mid, bool cancel) -{ - struct smb_basic_signing_context *data; - uint32 dummy_seq; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - - if (!data) - return; - - DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); - - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) - ; - - /* cancel doesn't send a reply so doesn't burn a sequence number. */ - if (cancel) { - data->send_seq_num -= 1; - } -} - -/*********************************************************** - Called by server negprot when signing has been negotiated. -************************************************************/ - -void srv_set_signing_negotiated(void) -{ - srv_sign_info.allow_smb_signing = True; - srv_sign_info.negotiated_smb_signing = True; - if (lp_server_signing() == Required) - srv_sign_info.mandatory_signing = True; - - srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; - srv_sign_info.check_incoming_message = temp_check_incoming_message; - srv_sign_info.free_signing_context = temp_free_signing_context; -} - -/*********************************************************** - Returns whether signing is active. We can't use sendfile or raw - reads/writes if it is. -************************************************************/ - -bool srv_is_signing_active(void) -{ - return srv_sign_info.doing_signing; -} - - -/*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. -************************************************************/ - -bool srv_is_signing_negotiated(void) -{ - return srv_sign_info.negotiated_smb_signing; -} - -/*********************************************************** - Returns whether signing is actually happening -************************************************************/ - -bool srv_signing_started(void) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) { - return False; - } - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data) - return False; - - if (data->send_seq_num == 0) { - return False; - } - - return True; -} - -/*********************************************************** - Turn on signing from this packet onwards. -************************************************************/ - -void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) -{ - struct smb_basic_signing_context *data; - - if (!user_session_key.length) - return; - - if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { - DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", - (unsigned int)srv_sign_info.negotiated_smb_signing, - (unsigned int)srv_sign_info.mandatory_signing )); - return; - } - - /* Once we've turned on, ignore any more sessionsetups. */ - if (srv_sign_info.doing_signing) { - return; - } - - if (srv_sign_info.free_signing_context) - srv_sign_info.free_signing_context(&srv_sign_info); - - srv_sign_info.doing_signing = True; - - data = SMB_XMALLOC_P(struct smb_basic_signing_context); - memset(data, '\0', sizeof(*data)); - - srv_sign_info.signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); - if (response.length) - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); - - dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); - - DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", - BOOLSTR(srv_sign_info.negotiated_smb_signing), - BOOLSTR(srv_sign_info.mandatory_signing) )); - - /* Initialise the sequence number */ - data->send_seq_num = 0; - - /* Initialise the list of outstanding packets */ - data->outstanding_packet_list = NULL; - - srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; - srv_sign_info.check_incoming_message = srv_check_incoming_message; - srv_sign_info.free_signing_context = simple_free_signing_context; -} diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index f49a1bc4c9..8460fea567 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -9572,15 +9572,20 @@ uint32 lp_get_spoolss_state( void ) Ensure we don't use sendfile if server smb signing is active. ********************************************************************/ -bool lp_use_sendfile(int snum) +bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state) { + bool sign_active = false; + /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */ if (Protocol < PROTOCOL_NT1) { - return False; + return false; + } + if (signing_state) { + sign_active = smb_signing_is_active(signing_state); } return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && - !srv_is_signing_active()); + !sign_active); } /******************************************************************* diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index cfa4b430eb..77616be48c 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -197,7 +197,6 @@ bool schedule_aio_read_and_X(connection_struct *conn, fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt, (unsigned int)aio_ex->req->mid )); - srv_defer_sign_response(aio_ex->req->mid); outstanding_aio_calls++; return True; } @@ -303,6 +302,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1); show_msg(aio_ex->outbuf); if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf, + true, aio_ex->req->seqnum+1, IS_CONN_ENCRYPTED(fsp->conn), &req->pcd)) { exit_server_cleanly("handle_aio_write: srv_send_smb " @@ -310,8 +310,6 @@ bool schedule_aio_write_and_X(connection_struct *conn, } DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write " "behind for file %s\n", fsp->fsp_name )); - } else { - srv_defer_sign_response(aio_ex->req->mid); } outstanding_aio_calls++; @@ -347,7 +345,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) /* If errno is ECANCELED then don't return anything to the * client. */ if (errno == ECANCELED) { - srv_cancel_sign_response(aio_ex->req->mid, false); return 0; } @@ -378,6 +375,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) smb_setlen(outbuf,outsize - 4); show_msg(outbuf); if (!srv_send_smb(smbd_server_fd(),outbuf, + true, aio_ex->req->seqnum+1, IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) { exit_server_cleanly("handle_aio_read_complete: srv_send_smb " "failed."); @@ -441,7 +439,6 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) /* If errno is ECANCELED then don't return anything to the * client. */ if (errno == ECANCELED) { - srv_cancel_sign_response(aio_ex->req->mid, false); return 0; } @@ -475,7 +472,9 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) } show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn), + if (!srv_send_smb(smbd_server_fd(),outbuf, + true, aio_ex->req->seqnum+1, + IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("handle_aio_write: srv_send_smb failed."); } @@ -534,7 +533,6 @@ void smbd_aio_complete_mid(unsigned int mid) if (!aio_ex) { DEBUG(3,("smbd_aio_complete_mid: Can't find record to " "match mid %u.\n", mid)); - srv_cancel_sign_response(mid, false); return; } @@ -544,7 +542,6 @@ void smbd_aio_complete_mid(unsigned int mid) * ignore. */ DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst " "aio outstanding (mid[%u]).\n", mid)); - srv_cancel_sign_response(mid, false); return; } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 42849931f3..4c61428692 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -204,9 +204,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, (unsigned int)blr->expire_time.tv_usec, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); - /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(blr->req->mid); - return True; } @@ -260,6 +257,7 @@ static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTAT reply_nterror(blr->req, status); if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf, + true, blr->req->seqnum+1, blr->req->encrypted, NULL)) { exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed."); } @@ -343,6 +341,7 @@ static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf, + true, blr->req->seqnum+1, IS_CONN_ENCRYPTED(blr->fsp->conn), NULL)) { exit_server_cleanly("blocking_lock_reply_error: " diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 6ac92ed3dd..b646bc30fd 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -202,6 +202,7 @@ extern int num_children; struct smbd_server_connection { struct fd_event *fde; uint64_t num_requests; + struct smb_signing_state *signing_state; }; extern struct smbd_server_connection *smbd_server_conn; diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f20c851297..d39aab4f47 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -134,6 +134,7 @@ void send_trans_reply(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) { exit_server_cleanly("send_trans_reply: srv_send_smb failed."); } @@ -190,6 +191,7 @@ void send_trans_reply(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) exit_server_cleanly("send_trans_reply: srv_send_smb " "failed."); @@ -296,6 +298,7 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq) send: if (!srv_send_smb( smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn) || req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); @@ -322,6 +325,7 @@ static void api_dcerpc_cmd_read_done(struct tevent_req *subreq) reply_nterror(req, status); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn) ||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb " diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index a921954c49..e548c587c1 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -316,7 +316,7 @@ static void reply_nt1(struct smb_request *req, uint16 choice) capabilities &= ~CAP_RAW_MODE; if (lp_server_signing() == Required) secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; - srv_set_signing_negotiated(); + srv_set_signing_negotiated(smbd_server_conn); } else { DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n")); if (lp_server_signing() == Required) { diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 8ceeaf5f55..fdab2ca848 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -143,7 +143,9 @@ static void change_notify_reply_packet(connection_struct *conn, } show_msg((char *)req->outbuf); - if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + if (!srv_send_smb(smbd_server_fd(), + (char *)req->outbuf, + true, req->seqnum+1, req->encrypted, &req->pcd)) { exit_server_cleanly("change_notify_reply_packet: srv_send_smb " "failed."); @@ -260,9 +262,6 @@ NTSTATUS change_notify_add_request(struct smb_request *req, map->mid = request->req->mid; DLIST_ADD(notify_changes_by_mid, map); - /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(request->req->mid); - return NT_STATUS_OK; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9c7fb1914e..628fc1bd32 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -230,6 +230,7 @@ void send_nt_replies(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) { exit_server_cleanly("send_nt_replies: srv_send_smb failed."); @@ -1129,9 +1130,9 @@ void reply_ntcancel(struct smb_request *req) */ START_PROFILE(SMBntcancel); + srv_cancel_sign_response(smbd_server_conn); remove_pending_change_notify_requests_by_mid(req->mid); remove_pending_lock_requests_by_mid(req->mid); - srv_cancel_sign_response(req->mid, true); DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid)); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index d529b009d5..52df4fa143 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1033,15 +1033,6 @@ static void defer_open(struct share_mode_lock *lck, exit_server("push_deferred_smb_message failed"); } add_deferred_open(lck, req->mid, request_time, state->id); - - /* - * Push the MID of this packet on the signing queue. - * We only do this once, the first time we push the packet - * onto the deferred open queue, as this has a side effect - * of incrementing the response sequence number. - */ - - srv_defer_sign_response(req->mid); } diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 22870283fa..ce00397bbd 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -361,7 +361,6 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx struct share_mode_entry msg; files_struct *fsp; char *break_msg; - bool sign_state; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -423,20 +422,14 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx wait_before_sending_break(); } - /* Save the server smb signing state. */ - sign_state = srv_oplock_set_signing(False); - show_msg(break_msg); if (!srv_send_smb(smbd_server_fd(), - break_msg, + break_msg, false, 0, IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("oplock_break: srv_send_smb failed."); } - /* Restore the sign state to what it was. */ - srv_oplock_set_signing(sign_state); - TALLOC_FREE(break_msg); /* Async level2 request, don't send a reply, just remove the oplock. */ @@ -457,7 +450,6 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, files_struct *fsp; char *break_msg; bool break_to_level2 = False; - bool sign_state; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -530,20 +522,14 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, wait_before_sending_break(); } - /* Save the server smb signing state. */ - sign_state = srv_oplock_set_signing(False); - show_msg(break_msg); if (!srv_send_smb(smbd_server_fd(), - break_msg, + break_msg, false, 0, IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("oplock_break: srv_send_smb failed."); } - /* Restore the sign state to what it was. */ - srv_oplock_set_signing(sign_state); - TALLOC_FREE(break_msg); fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; @@ -570,7 +556,6 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx, unsigned long file_id; files_struct *fsp; char *break_msg; - bool sign_state; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -610,20 +595,14 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx, exit_server("Could not talloc break_msg\n"); } - /* Save the server smb signing state. */ - sign_state = srv_oplock_set_signing(False); - show_msg(break_msg); if (!srv_send_smb(smbd_server_fd(), - break_msg, + break_msg, false, 0, IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("oplock_break: srv_send_smb failed."); } - /* Restore the sign state to what it was. */ - srv_oplock_set_signing(sign_state); - TALLOC_FREE(break_msg); fsp->sent_oplock_break = BREAK_TO_NONE_SENT; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 15d120a79c..076965e783 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -298,11 +298,13 @@ int register_existing_vuid(uint16 vuid, vuser->server_info->unix_name); } - if (srv_is_signing_negotiated() && !vuser->server_info->guest && - !srv_signing_started()) { + if (srv_is_signing_negotiated(smbd_server_conn) && + !vuser->server_info->guest) { /* Try and turn on server signing on the first non-guest * sessionsetup. */ - srv_set_signing(vuser->server_info->user_session_key, response_blob); + srv_set_signing(smbd_server_conn, + vuser->server_info->user_session_key, + response_blob); } /* fill in the current_user_info struct */ diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2686cf41d9..7ae7435646 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -216,6 +216,7 @@ static void pipe_write_done(struct tevent_req *subreq) send: if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn)||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 6d53bbe929..65778ab0fc 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -32,16 +32,20 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf, Send an smb to a fd. ****************************************************************************/ -bool srv_send_smb(int fd, char *buffer, bool do_encrypt, - struct smb_perfcount_data *pcd) +bool srv_send_smb(int fd, char *buffer, + bool do_signing, uint32_t seqnum, + bool do_encrypt, + struct smb_perfcount_data *pcd) { size_t len = 0; size_t nwritten=0; ssize_t ret; char *buf_out = buffer; - /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buf_out); + if (do_signing) { + /* Sign the outgoing packet if required. */ + srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum); + } if (do_encrypt) { NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); @@ -275,7 +279,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, if (CVAL(lenbuf,0) == 0 && min_recv_size && (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */ (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) && - !srv_is_signing_active()) { + !srv_is_signing_active(smbd_server_conn)) { return receive_smb_raw_talloc_partial_read( mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen); @@ -311,7 +315,8 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, unsigned int timeout, size_t *p_unread, bool *p_encrypted, - size_t *p_len) + size_t *p_len, + uint32_t *seqnum) { size_t len = 0; NTSTATUS status; @@ -336,7 +341,7 @@ static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, } /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(*buffer, true)) { + if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on " "incoming packet!\n")); return NT_STATUS_INVALID_NETWORK_RESPONSE; @@ -366,6 +371,7 @@ void init_smb_request(struct smb_request *req, req->flags2 = SVAL(inbuf, smb_flg2); req->smbpid = SVAL(inbuf, smb_pid); req->mid = SVAL(inbuf, smb_mid); + req->seqnum = 0; req->vuid = SVAL(inbuf, smb_uid); req->tid = SVAL(inbuf, smb_tid); req->wct = CVAL(inbuf, smb_wct); @@ -401,7 +407,8 @@ void init_smb_request(struct smb_request *req, static void process_smb(struct smbd_server_connection *conn, uint8_t *inbuf, size_t nread, size_t unread_bytes, - bool encrypted, struct smb_perfcount_data *deferred_pcd); + uint32_t seqnum, bool encrypted, + struct smb_perfcount_data *deferred_pcd); static void smbd_deferred_open_timer(struct event_context *ev, struct timed_event *te, @@ -427,7 +434,7 @@ static void smbd_deferred_open_timer(struct event_context *ev, process_smb(smbd_server_conn, inbuf, msg->buf.length, 0, - msg->encrypted, &msg->pcd); + msg->seqnum, msg->encrypted, &msg->pcd); } /**************************************************************************** @@ -458,6 +465,7 @@ static bool push_queued_message(struct smb_request *req, } msg->request_time = request_time; + msg->seqnum = req->seqnum; msg->encrypted = req->encrypted; SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd); @@ -1362,7 +1370,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in ****************************************************************************/ static void construct_reply(char *inbuf, int size, size_t unread_bytes, - bool encrypted, + uint32_t seqnum, bool encrypted, struct smb_perfcount_data *deferred_pcd) { connection_struct *conn; @@ -1374,6 +1382,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted); req->inbuf = (uint8_t *)talloc_move(req, &inbuf); + req->seqnum = seqnum; /* we popped this message off the queue - keep original perf data */ if (deferred_pcd) @@ -1405,6 +1414,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn)||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); @@ -1420,7 +1430,8 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, ****************************************************************************/ static void process_smb(struct smbd_server_connection *conn, uint8_t *inbuf, size_t nread, size_t unread_bytes, - bool encrypted, struct smb_perfcount_data *deferred_pcd) + uint32_t seqnum, bool encrypted, + struct smb_perfcount_data *deferred_pcd) { int msg_type = CVAL(inbuf,0); @@ -1442,7 +1453,7 @@ static void process_smb(struct smbd_server_connection *conn, show_msg((char *)inbuf); - construct_reply((char *)inbuf,nread,unread_bytes,encrypted,deferred_pcd); + construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd); trans_num++; done: @@ -1637,6 +1648,7 @@ void chain_reply(struct smb_request *req) talloc_get_size(req->chain_outbuf) - 4); if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn) ||req->encrypted, &req->pcd)) { @@ -1761,6 +1773,7 @@ void chain_reply(struct smb_request *req) show_msg((char *)(req->chain_outbuf)); if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn)||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); @@ -1830,6 +1843,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c bool encrypted = false; TALLOC_CTX *mem_ctx = talloc_tos(); NTSTATUS status; + uint32_t seqnum; /* TODO: make this completely nonblocking */ @@ -1838,7 +1852,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c 0, /* timeout */ &unread_bytes, &encrypted, - &inbuf_len); + &inbuf_len, &seqnum); if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { goto process; } @@ -1850,7 +1864,8 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c } process: - process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted, NULL); + process_smb(conn, inbuf, inbuf_len, unread_bytes, + seqnum, encrypted, NULL); } static void smbd_server_connection_handler(struct event_context *ev, @@ -2015,7 +2030,8 @@ void smbd_process(void) unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; DEBUG( 1, ("Connection denied from %s\n", client_addr(get_client_fd(),addr,sizeof(addr)) ) ); - (void)srv_send_smb(smbd_server_fd(),(char *)buf,false, NULL); + (void)srv_send_smb(smbd_server_fd(),(char *)buf, false, + 0, false, NULL); exit_server_cleanly("connection denied"); } @@ -2041,6 +2057,10 @@ void smbd_process(void) DEBUG(0,("Changed root to %s\n", lp_rootdir())); } + if (!srv_init_signing(smbd_server_conn)) { + exit_server("Failed to init smb_signing"); + } + /* Setup oplocks */ if (!init_oplocks(smbd_messaging_context())) exit_server("Failed to init oplocks"); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 8b560bd8ca..6f19a58178 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -497,7 +497,7 @@ void reply_special(char *inbuf) DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n", msg_type, msg_flags)); - srv_send_smb(smbd_server_fd(), outbuf, false, NULL); + srv_send_smb(smbd_server_fd(), outbuf, false, 0, false, NULL); return; } @@ -2766,7 +2766,8 @@ static void send_file_readbraw(connection_struct *conn, */ if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) && - (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) { + (fsp->wcp == NULL) && + lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) { ssize_t sendfile_read = -1; char header[4]; DATA_BLOB header_blob; @@ -2870,7 +2871,8 @@ void reply_readbraw(struct smb_request *req) START_PROFILE(SMBreadbraw); - if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) { + if (srv_is_signing_active(smbd_server_conn) || + is_encrypted_packet(req->inbuf)) { exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - " "raw reads/writes are disallowed."); } @@ -3274,7 +3276,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, if (!req_is_in_chain(req) && !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) && - lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) { + (fsp->wcp == NULL) && + lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) { uint8 headerbuf[smb_size + 12 * 2]; DATA_BLOB header; @@ -3450,7 +3453,8 @@ void reply_read_and_X(struct smb_request *req) return; } /* We currently don't do this on signed or sealed data. */ - if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) { + if (srv_is_signing_active(smbd_server_conn) || + is_encrypted_packet(req->inbuf)) { reply_nterror(req, NT_STATUS_NOT_SUPPORTED); END_PROFILE(SMBreadX); return; @@ -3558,7 +3562,7 @@ void reply_writebraw(struct smb_request *req) */ SCVAL(req->inbuf,smb_com,SMBwritec); - if (srv_is_signing_active()) { + if (srv_is_signing_active(smbd_server_conn)) { END_PROFILE(SMBwritebraw); exit_server_cleanly("reply_writebraw: SMB signing is active - " "raw reads/writes are disallowed."); @@ -3653,9 +3657,10 @@ void reply_writebraw(struct smb_request *req) SSVALS(buf,smb_vwv0,0xFFFF); show_msg(buf); if (!srv_send_smb(smbd_server_fd(), - buf, - IS_CONN_ENCRYPTED(conn), - &req->pcd)) { + buf, + false, 0, /* no signing */ + IS_CONN_ENCRYPTED(conn), + &req->pcd)) { exit_server_cleanly("reply_writebraw: srv_send_smb " "failed."); } @@ -4757,6 +4762,7 @@ void reply_echo(struct smb_request *req) show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn)||req->encrypted, cur_pcd)) exit_server_cleanly("reply_echo: srv_send_smb failed."); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index eb16a2601e..e33f04d971 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -1110,7 +1110,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address ); - dbgtext( "%s", srv_is_signing_active() ? "signed " : ""); + dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : ""); dbgtext( "connect to service %s ", lp_servicename(snum) ); dbgtext( "initially as user %s ", conn->server_info->unix_name ); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2c29192220..e8878a29ab 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -90,25 +90,6 @@ static int push_signature(uint8 **outbuf) return result; } -/**************************************************************************** - Start the signing engine if needed. Don't fail signing here. -****************************************************************************/ - -static void sessionsetup_start_signing_engine( - const auth_serversupplied_info *server_info, - const uint8 *inbuf) -{ - if (!server_info->guest && !srv_signing_started()) { - /* We need to start the signing engine - * here but a W2K client sends the old - * "BSRSPYL " signature instead of the - * correct one. Subsequent packets will - * be correct. - */ - srv_check_sign_mac((char *)inbuf, False); - } -} - /**************************************************************************** Send a security blob via a session setup reply. ****************************************************************************/ @@ -579,7 +560,6 @@ static void reply_spnego_kerberos(struct smb_request *req, SSVAL(req->outbuf, smb_uid, sess_vuid); - sessionsetup_start_signing_engine(server_info, req->inbuf); /* Successful logon. Keep this vuid. */ *p_invalidate_vuid = False; } @@ -668,9 +648,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req, if (server_info->guest) { SSVAL(req->outbuf,smb_vwv2,1); } - - sessionsetup_start_signing_engine(server_info, - (uint8 *)req->inbuf); } out: @@ -1804,8 +1781,6 @@ void reply_sesssetup_and_X(struct smb_request *req) /* current_user_info is changed on new vuid */ reload_services( True ); - - sessionsetup_start_signing_engine(server_info, req->inbuf); } data_blob_free(&nt_resp); diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c new file mode 100644 index 0000000000..b56eb71f45 --- /dev/null +++ b/source3/smbd/signing.c @@ -0,0 +1,158 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett 2002-2003 + Copyright (C) Stefan Metzmacher 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" +#include "smbd/globals.h" + + +/*********************************************************** + Called to validate an incoming packet from the client. +************************************************************/ + +bool srv_check_sign_mac(struct smbd_server_connection *conn, + const char *inbuf, uint32_t *seqnum) +{ + /* Check if it's a non-session message. */ + if(CVAL(inbuf,0)) { + return true; + } + + *seqnum = smb_signing_next_seqnum(conn->signing_state, false); + return smb_signing_check_pdu(conn->signing_state, + (const uint8_t *)inbuf, + *seqnum); +} + +/*********************************************************** + Called to sign an outgoing packet to the client. +************************************************************/ + +void srv_calculate_sign_mac(struct smbd_server_connection *conn, + char *outbuf, uint32_t seqnum) +{ + /* Check if it's a non-session message. */ + if(CVAL(outbuf,0)) { + return; + } + + smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum); +} + + +/*********************************************************** + Called to indicate a oneway request +************************************************************/ +void srv_cancel_sign_response(struct smbd_server_connection *conn) +{ + smb_signing_cancel_reply(conn->signing_state, true); +} + +/*********************************************************** + Called by server negprot when signing has been negotiated. +************************************************************/ + +bool srv_init_signing(struct smbd_server_connection *conn) +{ + bool allowed = true; + bool mandatory = false; + + switch (lp_server_signing()) { + case Required: + mandatory = true; + break; + case Auto: + break; + case True: + break; + case False: + allowed = false; + break; + } + + conn->signing_state = smb_signing_init(smbd_event_context(), + allowed, mandatory); + if (!conn->signing_state) { + return false; + } + + return true; +} + +void srv_set_signing_negotiated(struct smbd_server_connection *conn) +{ + smb_signing_set_negotiated(conn->signing_state); +} + +/*********************************************************** + Returns whether signing is active. We can't use sendfile or raw + reads/writes if it is. +************************************************************/ + +bool srv_is_signing_active(struct smbd_server_connection *conn) +{ + return smb_signing_is_active(conn->signing_state); +} + + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +bool srv_is_signing_negotiated(struct smbd_server_connection *conn) +{ + return smb_signing_is_negotiated(conn->signing_state); +} + +/*********************************************************** + Turn on signing from this packet onwards. +************************************************************/ + +void srv_set_signing(struct smbd_server_connection *conn, + const DATA_BLOB user_session_key, + const DATA_BLOB response) +{ + bool negotiated; + bool mandatory; + + if (!user_session_key.length) + return; + + negotiated = smb_signing_is_negotiated(conn->signing_state); + mandatory = smb_signing_is_mandatory(conn->signing_state); + + if (!negotiated && !mandatory) { + DEBUG(5,("srv_set_signing: signing negotiated = %u, " + "mandatory_signing = %u. Not allowing smb signing.\n", + negotiated, mandatory)); + return; + } + + if (!smb_signing_activate(conn->signing_state, + user_session_key, response)) { + return; + } + + DEBUG(3,("srv_set_signing: turning on SMB signing: " + "signing negotiated = %u, mandatory_signing = %u.\n", + negotiated, mandatory)); +} + diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ee1dda98b2..df01a39893 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -832,6 +832,7 @@ void send_trans2_replies(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) exit_server_cleanly("send_trans2_replies: srv_send_smb failed."); @@ -2892,8 +2893,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned case SMB_QUERY_CIFS_UNIX_INFO: { bool large_write = lp_min_receive_file_size() && - !srv_is_signing_active(); - bool large_read = !srv_is_signing_active(); + !srv_is_signing_active(smbd_server_conn); + bool large_read = !srv_is_signing_active(smbd_server_conn); int encrypt_caps = 0; if (!lp_unix_extensions()) { -- cgit From 6af15943c6f868d08945d0ca993506c17107fbd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Mar 2009 09:50:36 +0100 Subject: s3:libsmb: use new simplified smb_signing code for the client side We store the seqnum/mid mapping in the cli_request structure for async requests and in the cli_state structure for sync calls. We skip the signing check for oplock requests while waiting for async requests coming in. metze --- source3/include/async_smb.h | 2 + source3/include/client.h | 10 +- source3/include/proto.h | 15 +- source3/include/smb.h | 15 - source3/libsmb/async_smb.c | 43 ++- source3/libsmb/cliconnect.c | 39 ++- source3/libsmb/clientgen.c | 104 ++++++- source3/libsmb/clisigning.c | 650 +++----------------------------------------- source3/libsmb/clitrans.c | 54 ++-- 9 files changed, 224 insertions(+), 708 deletions(-) diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h index 7fc4ff7d27..2ac1101a1e 100644 --- a/source3/include/async_smb.h +++ b/source3/include/async_smb.h @@ -63,6 +63,8 @@ struct cli_request { */ uint16_t mid; + uint32_t seqnum; + /** * The bytes we have to ship to the server */ diff --git a/source3/include/client.h b/source3/include/client.h index 320a90e66b..db19f34a9d 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -166,6 +166,13 @@ struct smb_trans_enc_state { } s; }; +struct cli_state_seqnum { + struct cli_state_seqnum *prev, *next; + uint16_t mid; + uint32_t seqnum; + bool persistent; +}; + struct cli_state { /** * A list of subsidiary connections for DFS. @@ -217,6 +224,7 @@ struct cli_state { size_t max_xmit; size_t max_mux; char *outbuf; + struct cli_state_seqnum *seqnum; char *inbuf; unsigned int bufsize; int initialised; @@ -231,7 +239,7 @@ struct cli_state { TALLOC_CTX *call_mem_ctx; #endif - smb_sign_info sign_info; + struct smb_signing_state *signing_state; struct smb_trans_enc_state *trans_enc_state; /* Setup if we're encrypting SMB's. */ diff --git a/source3/include/proto.h b/source3/include/proto.h index 356eb4935f..d93c4a5125 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2410,6 +2410,10 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, int cli_set_message(char *buf,int num_words,int num_bytes,bool zero); unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout); void cli_set_port(struct cli_state *cli, int port); +bool cli_state_seqnum_persistent(struct cli_state *cli, + uint16_t mid); +bool cli_state_seqnum_remove(struct cli_state *cli, + uint16_t mid); bool cli_receive_smb(struct cli_state *cli); ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len); bool cli_receive_smb_readX_header(struct cli_state *cli); @@ -3186,14 +3190,13 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out); bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response); -bool cli_null_set_signing(struct cli_state *cli); bool cli_temp_set_signing(struct cli_state *cli); -void cli_free_signing_context(struct cli_state *cli); -void cli_calculate_sign_mac(struct cli_state *cli, char *buf); -bool cli_check_sign_mac(struct cli_state *cli, char *buf); -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid); -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid); +void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum); +bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum); bool client_is_signing_on(struct cli_state *cli); +bool client_is_signing_allowed(struct cli_state *cli); +bool client_is_signing_mandatory(struct cli_state *cli); +void cli_set_signing_negotiated(struct cli_state *cli); /* The following definitions come from smbd/signing.c */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 215adba1b4..84aa36a364 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1849,21 +1849,6 @@ struct ip_service { /* Special name type used to cause a _kerberos DNS lookup. */ #define KDC_NAME_TYPE 0xDCDC -/* Used by the SMB signing functions. */ - -typedef struct smb_sign_info { - void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si); - bool (*check_incoming_message)(const char *inbuf, struct smb_sign_info *si, bool must_be_ok); - void (*free_signing_context)(struct smb_sign_info *si); - void *signing_context; - - bool negotiated_smb_signing; - bool allow_smb_signing; - bool doing_signing; - bool mandatory_signing; - bool seen_valid; /* Have I ever seen a validly signed packet? */ -} smb_sign_info; - struct ea_struct { uint8 flags; char *name; diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 066ac7bdb8..86fd5c8bef 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -550,7 +550,7 @@ void cli_chain_uncork(struct cli_state *cli) _smb_setlen_large(((char *)req->outbuf), smblen); } - cli_calculate_sign_mac(cli, (char *)req->outbuf); + cli_calculate_sign_mac(cli, (char *)req->outbuf, &req->seqnum); if (cli_encryption_on(cli)) { NTSTATUS status; @@ -811,9 +811,16 @@ NTSTATUS cli_pull_reply(struct async_req *req, */ -static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) +static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu, + struct cli_request **_req, + uint16_t *_mid) { NTSTATUS status; + struct cli_request *req = NULL; + uint16_t mid; + + *_req = NULL; + *_mid = 0; if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ && (SVAL(pdu, 4) != 0x45ff)) /* 0xFF"E" */ { @@ -846,11 +853,27 @@ static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) } } - if (!cli_check_sign_mac(cli, pdu)) { + mid = SVAL(pdu, smb_mid); + + for (req = cli->outstanding_requests; req; req = req->next) { + if (req->mid == mid) { + break; + } + } + + if (!req) { + /* oplock breaks are not signed */ + goto done; + } + + if (!cli_check_sign_mac(cli, pdu, req->seqnum+1)) { DEBUG(10, ("cli_check_sign_mac failed\n")); return NT_STATUS_ACCESS_DENIED; } +done: + *_req = req; + *_mid = mid; return NT_STATUS_OK; } @@ -863,7 +886,7 @@ static void handle_incoming_pdu(struct cli_state *cli) { struct cli_request *req, *next; uint16_t mid; - size_t raw_pdu_len, buf_len, pdu_len, rest_len; + size_t raw_pdu_len, buf_len, rest_len; char *pdu; int i; NTSTATUS status; @@ -923,23 +946,13 @@ static void handle_incoming_pdu(struct cli_state *cli) } } - status = validate_smb_crypto(cli, pdu); + status = validate_smb_crypto(cli, pdu, &req, &mid); if (!NT_STATUS_IS_OK(status)) { goto invalidate_requests; } - mid = SVAL(pdu, smb_mid); - DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid)); - for (req = cli->outstanding_requests; req; req = req->next) { - if (req->mid == mid) { - break; - } - } - - pdu_len = smb_len(pdu) + 4; - if (req == NULL) { DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid)); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 525c361beb..aa1ca595a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -505,11 +505,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, ok = cli_simple_set_signing(cli, session_key, nt_response); #endif if (ok) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli, cli->outbuf); - - if (!cli_check_sign_mac(cli, cli->inbuf)) { + if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { result = NT_STATUS_ACCESS_DENIED; goto end; } @@ -747,11 +743,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * if (cli_simple_set_signing( cli, session_key_krb5, data_blob_null)) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli, cli->outbuf); - - if (!cli_check_sign_mac(cli, cli->inbuf)) { + if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { nt_status = NT_STATUS_ACCESS_DENIED; goto nt_error; } @@ -873,11 +865,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (cli_simple_set_signing( cli, ntlmssp_state->session_key, data_blob_null)) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli, cli->outbuf); - - if (!cli_check_sign_mac(cli, cli->inbuf)) { + if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { nt_status = NT_STATUS_ACCESS_DENIED; } } @@ -1540,13 +1528,16 @@ NTSTATUS cli_negprot_recv(struct async_req *req) cli->protocol = prots[protnum].prot; - if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { + if ((cli->protocol < PROTOCOL_NT1) && + client_is_signing_mandatory(cli)) { DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); return NT_STATUS_ACCESS_DENIED; } if (cli->protocol >= PROTOCOL_NT1) { struct timespec ts; + bool negotiated_smb_signing = false; + /* NT protocol */ cli->sec_mode = CVAL(vwv + 1, 0); cli->max_mux = SVAL(vwv + 1, 1); @@ -1579,22 +1570,24 @@ NTSTATUS cli_negprot_recv(struct async_req *req) if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { /* Fail if server says signing is mandatory and we don't want to support it. */ - if (!cli->sign_info.allow_smb_signing) { + if (!client_is_signing_allowed(cli)) { DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return NT_STATUS_ACCESS_DENIED; } - cli->sign_info.negotiated_smb_signing = True; - cli->sign_info.mandatory_signing = True; - } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) { + negotiated_smb_signing = true; + } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) { /* Fail if client says signing is mandatory and the server doesn't support it. */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); return NT_STATUS_ACCESS_DENIED; } - cli->sign_info.negotiated_smb_signing = True; - cli->sign_info.mandatory_signing = True; + negotiated_smb_signing = true; } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { - cli->sign_info.negotiated_smb_signing = True; + negotiated_smb_signing = true; + } + + if (negotiated_smb_signing) { + cli_set_signing_negotiated(cli); } if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c1ba4e5c4f..6186387076 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -135,6 +135,79 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) return len; } +static bool cli_state_set_seqnum(struct cli_state *cli, uint16_t mid, uint32_t seqnum) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + c->seqnum = seqnum; + return true; + } + } + + c = talloc_zero(cli, struct cli_state_seqnum); + if (!c) { + return false; + } + + c->mid = mid; + c->seqnum = seqnum; + c->persistent = false; + DLIST_ADD_END(cli->seqnum, c, struct cli_state_seqnum *); + + return true; +} + +bool cli_state_seqnum_persistent(struct cli_state *cli, + uint16_t mid) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + c->persistent = true; + return true; + } + } + + return false; +} + +bool cli_state_seqnum_remove(struct cli_state *cli, + uint16_t mid) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + DLIST_REMOVE(cli->seqnum, c); + TALLOC_FREE(c); + return true; + } + } + + return false; +} + +static uint32_t cli_state_get_seqnum(struct cli_state *cli, uint16_t mid) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + uint32_t seqnum = c->seqnum; + if (!c->persistent) { + DLIST_REMOVE(cli->seqnum, c); + TALLOC_FREE(c); + } + return seqnum; + } + } + + return 0; +} + /**************************************************************************** Recv an smb. ****************************************************************************/ @@ -142,6 +215,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) bool cli_receive_smb(struct cli_state *cli) { ssize_t len; + uint16_t mid; + uint32_t seqnum; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) @@ -177,7 +252,10 @@ bool cli_receive_smb(struct cli_state *cli) return false; } - if (!cli_check_sign_mac(cli, cli->inbuf)) { + mid = SVAL(cli->inbuf,smb_mid); + seqnum = cli_state_get_seqnum(cli, mid); + + if (!cli_check_sign_mac(cli, cli->inbuf, seqnum+1)) { /* * If we get a signature failure in sessionsetup, then * the server sometimes just reflects the sent signature @@ -264,12 +342,20 @@ bool cli_send_smb(struct cli_state *cli) ssize_t ret; char *buf_out = cli->outbuf; bool enc_on = cli_encryption_on(cli); + uint32_t seqnum; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) return false; - cli_calculate_sign_mac(cli, cli->outbuf); + cli_calculate_sign_mac(cli, cli->outbuf, &seqnum); + + if (!cli_state_set_seqnum(cli, cli->mid, seqnum)) { + DEBUG(0,("Failed to store mid[%u]/seqnum[%u]\n", + (unsigned int)cli->mid, + (unsigned int)seqnum)); + return false; + } if (enc_on) { NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, @@ -506,6 +592,7 @@ struct cli_state *cli_initialise_ex(int signing_state) cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); + cli->seqnum = 0; cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = false; @@ -556,9 +643,12 @@ struct cli_state *cli_initialise_ex(int signing_state) #endif /* initialise signing */ - cli->sign_info.allow_smb_signing = allow_smb_signing; - cli->sign_info.mandatory_signing = mandatory_signing; - cli_null_set_signing(cli); + cli->signing_state = smb_signing_init(cli, + allow_smb_signing, + mandatory_signing); + if (!cli->signing_state) { + goto error; + } cli->initialised = 1; @@ -641,7 +731,6 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); - cli_free_signing_context(cli); data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); @@ -740,7 +829,6 @@ static void cli_echo_recv_helper(struct async_req *req) cli_req->data.echo.num_echos -= 1; if (cli_req->data.echo.num_echos == 0) { - client_set_trans_sign_state_off(cli_req->cli, cli_req->mid); async_req_done(req); return; } @@ -782,8 +870,6 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, } req = talloc_get_type_abort(result->private_data, struct cli_request); - client_set_trans_sign_state_on(cli, req->mid); - req->data.echo.num_echos = num_echos; req->data.echo.data.data = talloc_move(req, &data_copy); req->data.echo.data.length = data.length; diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c index 6644bc0d60..0d0e926e6c 100644 --- a/source3/libsmb/clisigning.c +++ b/source3/libsmb/clisigning.c @@ -1,8 +1,9 @@ -/* +/* Unix SMB/CIFS implementation. SMB Signing Code Copyright (C) Jeremy Allison 2003. Copyright (C) Andrew Bartlett 2002-2003 + Copyright (C) Stefan Metzmacher 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 @@ -20,654 +21,67 @@ #include "includes.h" -/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ -struct outstanding_packet_lookup { - struct outstanding_packet_lookup *prev, *next; - uint16 mid; - uint32 reply_seq_num; - bool can_delete; /* Set to False in trans state. */ -}; - -struct smb_basic_signing_context { - DATA_BLOB mac_key; - uint32 send_seq_num; - struct outstanding_packet_lookup *outstanding_packet_list; -}; - -static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num) -{ - struct outstanding_packet_lookup *t; - - /* Ensure we only add a mid once. */ - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - return False; - } - } - - t = SMB_XMALLOC_P(struct outstanding_packet_lookup); - ZERO_STRUCTP(t); - - t->mid = mid; - t->reply_seq_num = reply_seq_num; - t->can_delete = True; - - /* - * Add to the *start* of the list not the end of the list. - * This ensures that the *last* send sequence with this mid - * is returned by preference. - * This can happen if the mid wraps and one of the early - * mid numbers didn't get a reply and is still lurking on - * the list. JRA. Found by Fran Fabrizio . - */ - - DLIST_ADD(*list, t); - DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", - (unsigned int)reply_seq_num, (unsigned int)mid )); - return True; -} - -static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - *reply_seq_num = t->reply_seq_num; - DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", - (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - if (t->can_delete) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - } - return True; - } - } - return False; -} - -static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - t->can_delete = can_delete_entry; - return True; - } - } - return False; -} - -/*********************************************************** - SMB signing - Common code before we set a new signing implementation -************************************************************/ - -static bool cli_set_smb_signing_common(struct cli_state *cli) -{ - if (!cli->sign_info.allow_smb_signing) { - return False; - } - - if (!cli->sign_info.negotiated_smb_signing - && !cli->sign_info.mandatory_signing) { - return False; - } - - if (cli->sign_info.doing_signing) { - return False; - } - - if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(&cli->sign_info); - - /* These calls are INCOMPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - return True; -} - -/*********************************************************** - SMB signing - Common code for 'real' implementations -************************************************************/ - -static bool set_smb_signing_real_common(struct smb_sign_info *si) -{ - if (si->mandatory_signing) { - DEBUG(5, ("Mandatory SMB signing enabled!\n")); - } - - si->doing_signing = True; - DEBUG(5, ("SMB signing enabled!\n")); - - return True; -} - -static void mark_packet_signed(char *outbuf) -{ - uint16 flags2; - flags2 = SVAL(outbuf,smb_flg2); - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(outbuf,smb_flg2, flags2); -} - -/*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. -************************************************************/ - -static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - /* we can't zero out the sig, as we might be trying to send a - session request - which is NBT-level, not SMB level and doesn't - have the field */ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ - -static bool null_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - return True; -} - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ - -static void null_free_signing_context(struct smb_sign_info *si) -{ - return; -} - -/** - SMB signing - NULL implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ - -static bool null_set_signing(struct smb_sign_info *si) -{ - si->signing_context = NULL; - - si->sign_outgoing_message = null_sign_outgoing_message; - si->check_incoming_message = null_check_incoming_message; - si->free_signing_context = null_free_signing_context; - - return True; -} - -/** - * Free the signing context - */ - -static void free_signing_context(struct smb_sign_info *si) -{ - if (si->free_signing_context) { - si->free_signing_context(si); - si->signing_context = NULL; - } - - null_set_signing(si); -} - - -static bool signing_good(const char *inbuf, struct smb_sign_info *si, - bool good, uint32 seq, bool must_be_ok) -{ - if (good) { - - if (!si->doing_signing) { - si->doing_signing = True; - } - - if (!si->seen_valid) { - si->seen_valid = True; - } - - } else { - if (!si->mandatory_signing && !si->seen_valid) { - - if (!must_be_ok) { - return True; - } - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" - "isn't sending correct signatures. Turning off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else if (!must_be_ok) { - /* This packet is known to be unsigned */ - return True; - } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (seq) - DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); - return False; - } - } - return True; -} - -/*********************************************************** - SMB signing - Simple implementation - calculate a MAC on the packet -************************************************************/ - -static void simple_packet_signature(struct smb_basic_signing_context *data, - const uchar *buf, uint32 seq_number, - unsigned char calc_md5_mac[16]) -{ - const size_t offset_end_of_sig = (smb_ss_field + 8); - unsigned char sequence_buf[8]; - struct MD5Context md5_ctx; -#if 0 - /* JRA - apparently this is incorrect. */ - unsigned char key_buf[16]; -#endif - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - * - * We do this here, to avoid modifying the packet. - */ - - DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); - - SIVAL(sequence_buf, 0, seq_number); - SIVAL(sequence_buf, 4, 0); - - /* Calculate the 16 byte MAC - but don't alter the data in the - incoming packet. - - This makes for a bit of fussing about, but it's not too bad. - */ - MD5Init(&md5_ctx); - - /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); -#if 0 - /* JRA - apparently this is incorrect. */ - /* NB. When making and verifying SMB signatures, Windows apparently - zero-pads the key to 128 bits if it isn't long enough. - From Nalin Dahyabhai */ - if (data->mac_key.length < sizeof(key_buf)) { - memset(key_buf, 0, sizeof(key_buf)); - MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); - } -#endif - - /* copy in the first bit of the SMB header */ - MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); - - /* copy in the sequence number, instead of the signature */ - MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); - - /* copy in the rest of the packet in, skipping the signature */ - MD5Update(&md5_ctx, buf + offset_end_of_sig, - smb_len(buf) - (offset_end_of_sig - 4)); - - /* calculate the MD5 sig */ - MD5Final(calc_md5_mac, &md5_ctx); -} - - -/*********************************************************** - SMB signing - Client implementation - send the MAC. -************************************************************/ - -static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) - return; - - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - simple_packet_signature(data, (const unsigned char *)outbuf, - data->send_seq_num, calc_md5_mac); - - DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, calc_md5_mac, 8); - - memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signatures...*/ - - /* Instead of re-introducing the trans_info_conect we - used to have here, we use the fact that during a - SMBtrans/SMBtrans2/SMBnttrans send that the mid stays - constant. This means that calling store_sequence_for_reply() - will return False for all trans secondaries, as the mid is already - on the stored sequence list. As the send_seqence_number must - remain constant for all primary+secondary trans sends, we - only increment the send sequence number when we successfully - add a new entry to the outstanding sequence list. This means - I can isolate the fix here rather than re-adding the trans - signing on/off calls in libsmb/clitrans2.c JRA. - */ - - if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { - data->send_seq_num += 2; - } -} - -/*********************************************************** - SMB signing - Client implementation - check a MAC sent by server. -************************************************************/ - -static bool client_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - bool good; - uint32 reply_seq_number; - unsigned char calc_md5_mac[16]; - unsigned char *server_sent_mac; - - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) - return True; - - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); - return False; - } - - if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { - DEBUG(1, ("client_check_incoming_message: received message " - "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) )); - return False; - } - - simple_packet_signature(data, (const unsigned char *)inbuf, - reply_seq_number, calc_md5_mac); - - server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; - good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - - if (!good) { - DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, calc_md5_mac, 8); - - DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, server_sent_mac, 8); -#if 1 /* JRATEST */ - { - int i; - for (i = -5; i < 5; i++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac); - if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); - break; - } - } - } -#endif /* JRATEST */ - - } else { - DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, server_sent_mac, 8); - } - return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); -} - -/*********************************************************** - SMB signing - Simple implementation - free signing context -************************************************************/ - -static void simple_free_signing_context(struct smb_sign_info *si) -{ - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - struct outstanding_packet_lookup *list; - struct outstanding_packet_lookup *next; - - for (list = data->outstanding_packet_list; list; list = next) { - next = list->next; - DLIST_REMOVE(data->outstanding_packet_list, list); - SAFE_FREE(list); - } - - data_blob_free(&data->mac_key); - - SAFE_FREE(si->signing_context); - - return; -} - -/*********************************************************** - SMB signing - Simple implementation - setup the MAC key. -************************************************************/ - bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) { - struct smb_basic_signing_context *data; - - if (!user_session_key.length) - return False; - - if (!cli_set_smb_signing_common(cli)) { - return False; - } - - if (!set_smb_signing_real_common(&cli->sign_info)) { - return False; - } - - data = SMB_XMALLOC_P(struct smb_basic_signing_context); - memset(data, '\0', sizeof(*data)); - - cli->sign_info.signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); - - DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, user_session_key.data, user_session_key.length); + bool ok; - if (response.length) { - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); - DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, response.data, response.length); - } else { - DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); + ok = smb_signing_activate(cli->signing_state, + user_session_key, + response); + if (!ok) { + return false; } - dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + cli->readbraw_supported = false; + cli->writebraw_supported = false; - /* Initialise the sequence number */ - data->send_seq_num = 0; - - /* Initialise the list of outstanding packets */ - data->outstanding_packet_list = NULL; - - cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; - cli->sign_info.check_incoming_message = client_check_incoming_message; - cli->sign_info.free_signing_context = simple_free_signing_context; - - return True; -} - -/*********************************************************** - SMB signing - TEMP implementation - calculate a MAC to send. -************************************************************/ - -static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - /* I wonder what BSRSPYL stands for - but this is what MS - actually sends! */ - memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); - return; + return true; } -/*********************************************************** - SMB signing - TEMP implementation - check a MAC sent by server. -************************************************************/ - -static bool temp_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, bool foo) +bool cli_temp_set_signing(struct cli_state *cli) { - return True; + return smb_signing_set_bsrspyl(cli->signing_state); } -/*********************************************************** - SMB signing - TEMP implementation - free signing context -************************************************************/ - -static void temp_free_signing_context(struct smb_sign_info *si) +void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum) { - return; + *seqnum = smb_signing_next_seqnum(cli->signing_state, false); + smb_signing_sign_pdu(cli->signing_state, (uint8_t *)buf, *seqnum); } -/*********************************************************** - SMB signing - NULL implementation - setup the MAC key. -************************************************************/ - -bool cli_null_set_signing(struct cli_state *cli) +bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum) { - return null_set_signing(&cli->sign_info); -} + bool ok; -/*********************************************************** - SMB signing - temp implementation - setup the MAC key. -************************************************************/ + ok = smb_signing_check_pdu(cli->signing_state, + (const uint8_t *)buf, + seqnum); -bool cli_temp_set_signing(struct cli_state *cli) -{ - if (!cli_set_smb_signing_common(cli)) { - return False; + if (!ok) { + return false; } - cli->sign_info.signing_context = NULL; - - cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; - cli->sign_info.check_incoming_message = temp_check_incoming_message; - cli->sign_info.free_signing_context = temp_free_signing_context; - - return True; -} - -void cli_free_signing_context(struct cli_state *cli) -{ - free_signing_context(&cli->sign_info); + return true; } -/** - * Sign a packet with the current mechanism - */ - -void cli_calculate_sign_mac(struct cli_state *cli, char *buf) +void cli_set_signing_negotiated(struct cli_state *cli) { - cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); + smb_signing_set_negotiated(cli->signing_state); } -/** - * Check a packet with the current mechanism - * @return False if we had an established signing connection - * which had a bad checksum, True otherwise. - */ - -bool cli_check_sign_mac(struct cli_state *cli, char *buf) -{ - if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { - free_signing_context(&cli->sign_info); - return False; - } - return True; -} - -/*********************************************************** - Enter trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +bool client_is_signing_on(struct cli_state *cli) { - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { - return False; - } - - return True; + return smb_signing_is_active(cli->signing_state); } -/*********************************************************** - Leave trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +bool client_is_signing_allowed(struct cli_state *cli) { - uint32 reply_seq_num; - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { - return False; - } - - /* Now delete the stored mid entry. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { - return False; - } - - return True; + return smb_signing_is_allowed(cli->signing_state); } -/*********************************************************** - Is client signing on ? -************************************************************/ - -bool client_is_signing_on(struct cli_state *cli) +bool client_is_signing_mandatory(struct cli_state *cli) { - struct smb_sign_info *si = &cli->sign_info; - return si->doing_signing; + return smb_signing_is_mandatory(cli->signing_state); } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 0266c0307e..c566972b21 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -94,14 +94,12 @@ bool cli_send_trans(struct cli_state *cli, int trans, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); + cli_state_seqnum_persistent(cli, mid); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); + cli_state_seqnum_remove(cli, mid); return(False); } @@ -137,12 +135,11 @@ bool cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); - client_set_trans_sign_state_off(cli, mid); cli->mid = mid; if (!cli_send_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } - client_set_trans_sign_state_on(cli, mid); tot_data += this_ldata; tot_param += this_lparam; @@ -165,10 +162,14 @@ bool cli_receive_trans(struct cli_state *cli,int trans, unsigned int this_data,this_param; NTSTATUS status; bool ret = False; + uint16_t mid; *data_len = *param_len = 0; + mid = SVAL(cli->inbuf,smb_mid); + if (!cli_receive_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } @@ -179,6 +180,7 @@ bool cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); + cli_state_seqnum_remove(cli, mid); return False; } @@ -331,6 +333,8 @@ bool cli_receive_trans(struct cli_state *cli,int trans, out: + cli_state_seqnum_remove(cli, mid); + if (ret) { /* Ensure the last 2 bytes of param and data are 2 null * bytes. These are malloc'ed, but not included in any @@ -344,7 +348,6 @@ bool cli_receive_trans(struct cli_state *cli,int trans, } } - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -412,14 +415,12 @@ bool cli_send_nt_trans(struct cli_state *cli, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); + cli_state_seqnum_persistent(cli, mid); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); + cli_state_seqnum_remove(cli, mid); return(False); } @@ -454,12 +455,11 @@ bool cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); - client_set_trans_sign_state_off(cli, mid); cli->mid = mid; if (!cli_send_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } - client_set_trans_sign_state_on(cli, mid); tot_data += this_ldata; tot_param += this_lparam; @@ -483,10 +483,14 @@ bool cli_receive_nt_trans(struct cli_state *cli, uint8 eclass; uint32 ecode; bool ret = False; + uint16_t mid; *data_len = *param_len = 0; + mid = SVAL(cli->inbuf,smb_mid); + if (!cli_receive_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } @@ -496,6 +500,7 @@ bool cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); + cli_state_seqnum_remove(cli, mid); return(False); } @@ -669,6 +674,8 @@ bool cli_receive_nt_trans(struct cli_state *cli, out: + cli_state_seqnum_remove(cli, mid); + if (ret) { /* Ensure the last 2 bytes of param and data are 2 null * bytes. These are malloc'ed, but not included in any @@ -682,7 +689,6 @@ bool cli_receive_nt_trans(struct cli_state *cli, } } - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -696,6 +702,7 @@ struct cli_trans_state { struct event_context *ev; uint8_t cmd; uint16_t mid; + uint32_t seqnum; const char *pipe_name; uint16_t fid; uint16_t function; @@ -919,6 +926,7 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, cli_req = talloc_get_type_abort(result->private_data, struct cli_request); state->mid = cli_req->mid; + state->seqnum = cli_req->seqnum; } else { uint16_t num_bytes = talloc_get_size(bytes); /* @@ -939,12 +947,10 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, cli_req->recv_helper.fn = cli_trans_recv_helper; cli_req->recv_helper.priv = state; cli_req->mid = state->mid; - client_set_trans_sign_state_off(state->cli, state->mid); cli_chain_uncork(state->cli); + state->seqnum = cli_req->seqnum; } - client_set_trans_sign_state_on(state->cli, state->mid); - fail: TALLOC_FREE(frame); return result; @@ -953,6 +959,8 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, static void cli_trans_ship_rest(struct async_req *req, struct cli_trans_state *state) { + struct cli_request *cli_req; + state->secondary_request_ctx = talloc_new(state); if (state->secondary_request_ctx == NULL) { async_req_nterror(req, NT_STATUS_NO_MEMORY); @@ -961,14 +969,19 @@ static void cli_trans_ship_rest(struct async_req *req, while ((state->param_sent < state->num_param) || (state->data_sent < state->num_data)) { - struct async_req *cli_req; + struct async_req *subreq; - cli_req = cli_ship_trans(state->secondary_request_ctx, state); - if (cli_req == NULL) { + subreq = cli_ship_trans(state->secondary_request_ctx, state); + if (subreq == NULL) { async_req_nterror(req, NT_STATUS_NO_MEMORY); return; } } + + cli_req = talloc_get_type_abort(req->private_data, + struct cli_request); + + cli_req->seqnum = state->seqnum; } static NTSTATUS cli_pull_trans(struct async_req *req, @@ -1174,7 +1187,6 @@ static void cli_trans_recv_helper(struct async_req *req) if ((state->rparam.total == state->rparam.received) && (state->rdata.total == state->rdata.received)) { - client_set_trans_sign_state_off(state->cli, state->mid); async_req_done(req); } } -- cgit From 97a086d5c4e84616065cbbc68d47d82de0fe0db5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 6 Mar 2009 16:35:34 +0100 Subject: selftest/Samba3: Test smb signing against the member server metze --- selftest/target/Samba3.pm | 1 + source3/selftest/tests.sh | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 78aafa7533..0b176d601c 100644 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -144,6 +144,7 @@ sub setup_member($$$) my $member_options = " security = domain + server signing = on "; my $ret = $self->provision($prefix, "LOCALMEMBER3", diff --git a/source3/selftest/tests.sh b/source3/selftest/tests.sh index f88dab0337..ea59f0ee8e 100755 --- a/source3/selftest/tests.sh +++ b/source3/selftest/tests.sh @@ -120,6 +120,10 @@ plantest "blackbox.smbclient_s3.plain" dc BINDIR="$BINDIR" script/tests/test_smb plantest "blackbox.smbclient_s3.plain member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD plantest "blackbox.smbclient_s3.plain domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD +# sign, only the member server allows signing +plantest "blackbox.smbclient_s3.sign member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD "--signing=required" +plantest "blackbox.smbclient_s3.sign domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD "--signing=required" + # encrypted plantest "blackbox.smbclient_s3.crypt" dc BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$USERNAME \$PASSWORD "-e" -- cgit From f4aec7b5907065a2f48d1b19065c6673aff6a190 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 13:02:57 +0100 Subject: ѕ3/winbind_pam: fix gcc 4.4 compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source3/winbindd/winbindd_pam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 15d1b7e2bf..54bcac2b04 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1854,7 +1854,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp) || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) { - if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB || + if (!(state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) || state->request.extra_len != state->request.data.auth_crap.nt_resp_len) { DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", state->request.data.auth_crap.lm_resp_len, -- cgit From a087310b336bf1b6b2827b27d32071876c23f3a9 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Thu, 19 Mar 2009 01:16:46 +0100 Subject: remove non standard way to point to ctdb path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we can provide the path to ctdb via the --with-ctdb=... configure flag like we do it with other packageѕ, too. There is no need for another redundnant Makefile hack to point the ctdb header location Signed-off-by: Michael Adam --- source3/Makefile.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 46216c7f08..673636f787 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -158,7 +158,7 @@ CODEPAGEDIR = @codepagedir@ # the directory where pid files go PIDDIR = @piddir@ -FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) -I$(CTDBDIR)/include $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 -I../source4 +FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 -I../source4 PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DPRIVATE_DIR=\"$(PRIVATE_DIR)\" \ @@ -173,7 +173,6 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DMODULESDIR=\"$(MODULESDIR)\" \ -DLOGFILEBASE=\"$(LOGFILEBASE)\" \ -DSHLIBEXT=\"@SHLIBEXT@\" \ - -DCTDBDIR=\"$(CTDBDIR)\" \ -DNCALRPCDIR=\"$(NCALRPCDIR)\" \ -DCONFIGDIR=\"$(CONFIGDIR)\" \ -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \ -- cgit From 2dc8ce59b28d3a028551ac5087f31cf83d04e064 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Wed, 18 Mar 2009 22:19:06 +0100 Subject: don't set -O twice Signed-off-by: Michael Adam --- source3/configure.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index cfc2473a82..12808eb6f5 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -157,8 +157,6 @@ if test "x$CFLAGS" = x; then fi if test "x$debug" = "xyes" ; then CFLAGS="${CFLAGS} -g" -else - CFLAGS="${CFLAGS} -O" fi m4_include(../lib/socket_wrapper/config.m4) -- cgit From a4cc3e253852794f477ef5d836537b50111d0e42 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 23 Mar 2009 14:22:37 +0100 Subject: s3:build: prevent from setting "-O -g", check for $debug first. This makes configure actually behave as the comments describe. The reversal of order was introduced by mistake in 90ea8ae9b1ed3b7ed1c93076517e026e629ea1aa Michael --- source3/configure.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 12808eb6f5..5f1a5efe7d 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -152,12 +152,12 @@ AC_SUBST(NSCD_LIBS) # do this here since AC_CACHE_CHECK apparently sets the CFLAGS to "-g -O2" # if it has no value. This prevent *very* large debug binaries from occurring # by default. -if test "x$CFLAGS" = x; then - CFLAGS="-O" -fi if test "x$debug" = "xyes" ; then CFLAGS="${CFLAGS} -g" fi +if test "x$CFLAGS" = x; then + CFLAGS="-O" +fi m4_include(../lib/socket_wrapper/config.m4) m4_include(../lib/nss_wrapper/config.m4) -- cgit From dfa93041abca0778a9988b384ddeaee234b324a2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 20 Mar 2009 14:39:19 +0100 Subject: Disable dns_sd by default --- source3/configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 5f1a5efe7d..f8b76a01b4 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -5973,10 +5973,10 @@ AC_SUBST(FLAGS1) # Check if user wants DNS service discovery support AC_ARG_ENABLE(dnssd, -[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=auto)])]) +[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=no)])]) AC_SUBST(DNSSD_LIBS) -if test x"$enable_dnssd" != x"no"; then +if test x"$enable_dnssd" == x"yes"; then have_dnssd_support=yes AC_CHECK_HEADERS(dns_sd.h) -- cgit From 4c1794c41c0595b2a62a1b4d96f7592ef746a76d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 20 Mar 2009 14:53:10 +0100 Subject: Add avahi detection to configure --- source3/Makefile.in | 1 + source3/configure.in | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index 673636f787..cc4c8f70b5 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -73,6 +73,7 @@ WINBIND_NSS_EXTRA_LIBS=@WINBIND_NSS_EXTRA_LIBS@ WINBIND_NSS_PTHREAD=@WINBIND_NSS_PTHREAD@ PAM_WINBIND_EXTRA_LIBS=@PAM_WINBIND_EXTRA_LIBS@ DNSSD_LIBS=@DNSSD_LIBS@ +AVAHI_LIBS=@AVAHI_LIBS@ POPT_LIBS=@POPTLIBS@ LIBTALLOC_LIBS=@LIBTALLOC_LIBS@ LIBTDB_LIBS=@LIBTDB_LIBS@ diff --git a/source3/configure.in b/source3/configure.in index f8b76a01b4..444f93f4c7 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6004,6 +6004,42 @@ if test x"$enable_dnssd" == x"yes"; then fi +################################################# +# Check if user wants avahi support + +AC_ARG_ENABLE(avahi, +[AS_HELP_STRING([--enable-avahi], [Enable Avahi support (default=auto)])]) + +AC_SUBST(AVAHI_LIBS) +if test x"$enable_avahi" != x"no"; then + have_avahi_support=yes + + AC_CHECK_HEADERS(avahi-common/watch.h) + if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then + have_avahi_support=no + fi + + AC_CHECK_HEADERS(avahi-client/client.h) + if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then + have_avahi_support=no + fi + + AC_CHECK_LIB_EXT(avahi-client, AVAHI_LIBS, avahi_client_new) + if test x"$ac_cv_lib_ext_avahi_client_avahi_client_new" != x"yes"; then + have_avahi_support=no + fi + + if test x"$have_avahi_support" = x"yes"; then + AC_DEFINE(WITH_AVAHI_SUPPORT, 1, + [Whether to enable avahi support]) + else + if test x"$enable_avahi" = x"yes"; then + AC_MSG_ERROR(avahi support not available) + fi + fi + +fi + ################################################# # Check to see if we should use the included iniparser -- cgit From 93e13fe3e07c1915a84f7a7a810a1d85a21bcfe7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 20 Mar 2009 14:55:05 +0100 Subject: Add tevent avahi binding --- source3/Makefile.in | 8 +- source3/configure.in | 2 +- source3/include/proto.h | 5 + source3/lib/avahi.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 source3/lib/avahi.c diff --git a/source3/Makefile.in b/source3/Makefile.in index cc4c8f70b5..329ded0716 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -255,6 +255,8 @@ AFS_OBJ = lib/afs.o AFS_SETTOKEN_OBJ = lib/afs_settoken.o +AVAHI_OBJ = @AVAHI_OBJ@ + SERVER_MUTEX_OBJ = lib/server_mutex.o PASSCHANGE_OBJ = libsmb/passchange.o @@ -743,7 +745,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ - $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ + $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@ \ @@ -1387,7 +1389,7 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE @echo Linking $@ @$(CC) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ - $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \ + $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \ $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ $(WINBIND_LIBS) $(ZLIB_LIBS) @@ -1573,7 +1575,7 @@ bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SH bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \ + @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(AVAHI_LIBS) \ $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(DNSSD_LIBS) \ $(ACL_LIBS) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \ @SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ diff --git a/source3/configure.in b/source3/configure.in index 444f93f4c7..103edaf369 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6032,12 +6032,12 @@ if test x"$enable_avahi" != x"no"; then if test x"$have_avahi_support" = x"yes"; then AC_DEFINE(WITH_AVAHI_SUPPORT, 1, [Whether to enable avahi support]) + AC_SUBST(AVAHI_OBJ, lib/avahi.o) else if test x"$enable_avahi" = x"yes"; then AC_MSG_ERROR(avahi support not available) fi fi - fi ################################################# diff --git a/source3/include/proto.h b/source3/include/proto.h index d93c4a5125..a8c4b14fff 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7230,6 +7230,11 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid); NTSTATUS nss_info_template_init( void ); +/* The following definitions come from lib/avahi.c */ + +struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, + struct tevent_context *ev); + /* Misc protos */ #endif /* _PROTO_H_ */ diff --git a/source3/lib/avahi.c b/source3/lib/avahi.c new file mode 100644 index 0000000000..ac9867a1fc --- /dev/null +++ b/source3/lib/avahi.c @@ -0,0 +1,268 @@ +/* + Unix SMB/CIFS implementation. + Connect avahi to lib/tevents + Copyright (C) Volker Lendecke 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" + +#include + +struct avahi_poll_context { + struct tevent_context *ev; + AvahiWatch **watches; + AvahiTimeout **timeouts; +}; + +struct AvahiWatch { + struct avahi_poll_context *ctx; + struct tevent_fd *fde; + int fd; + AvahiWatchEvent latest_event; + AvahiWatchCallback callback; + void *userdata; +}; + +struct AvahiTimeout { + struct avahi_poll_context *ctx; + struct tevent_timer *te; + AvahiTimeoutCallback callback; + void *userdata; +}; + +static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event) +{ + return ((event & AVAHI_WATCH_IN) ? TEVENT_FD_READ : 0) + | ((event & AVAHI_WATCH_OUT) ? TEVENT_FD_WRITE : 0); +} + +static void avahi_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *private_data); + +static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd, + AvahiWatchEvent event, + AvahiWatchCallback callback, + void *userdata) +{ + struct avahi_poll_context *ctx = talloc_get_type_abort( + api->userdata, struct avahi_poll_context); + int num_watches = talloc_array_length(ctx->watches); + AvahiWatch **tmp, *watch_ctx; + + tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1); + if (tmp == NULL) { + return NULL; + } + ctx->watches = tmp; + + watch_ctx = talloc(tmp, AvahiWatch); + if (watch_ctx == NULL) { + goto fail; + } + ctx->watches[num_watches] = watch_ctx; + + watch_ctx->ctx = ctx; + watch_ctx->fde = tevent_add_fd(ctx->ev, watch_ctx, fd, + avahi_flags_map_to_tevent(event), + avahi_fd_handler, watch_ctx); + if (watch_ctx->fde == NULL) { + goto fail; + } + watch_ctx->callback = callback; + watch_ctx->userdata = userdata; + return watch_ctx; + + fail: + TALLOC_FREE(watch_ctx); + ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *, + num_watches); + return NULL; +} + +static void avahi_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *private_data) +{ + AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch); + + watch_ctx->latest_event = + ((flags & TEVENT_FD_READ) ? AVAHI_WATCH_IN : 0) + | ((flags & TEVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0); + + watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event, + watch_ctx->userdata); +} + +static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event) +{ + tevent_fd_set_flags(w->fde, avahi_flags_map_to_tevent(event)); +} + +static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w) +{ + return w->latest_event; +} + +static void avahi_watch_free(AvahiWatch *w) +{ + int i, num_watches; + AvahiWatch **watches = w->ctx->watches; + struct avahi_poll_context *ctx; + + num_watches = talloc_array_length(watches); + + for (i=0; ictx; + TALLOC_FREE(w); + memmove(&watches[i], &watches[i+1], + sizeof(*watches) * (num_watches - i - 1)); + ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *, + num_watches - 1); +} + +static void avahi_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data); + +static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api, + const struct timeval *tv, + AvahiTimeoutCallback callback, + void *userdata) +{ + struct avahi_poll_context *ctx = talloc_get_type_abort( + api->userdata, struct avahi_poll_context); + int num_timeouts = talloc_array_length(ctx->timeouts); + AvahiTimeout **tmp, *timeout_ctx; + + tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *, + num_timeouts + 1); + if (tmp == NULL) { + return NULL; + } + ctx->timeouts = tmp; + + timeout_ctx = talloc(tmp, AvahiTimeout); + if (timeout_ctx == NULL) { + goto fail; + } + ctx->timeouts[num_timeouts] = timeout_ctx; + + timeout_ctx->ctx = ctx; + if (tv == NULL) { + timeout_ctx->te = NULL; + } else { + timeout_ctx->te = tevent_add_timer(ctx->ev, timeout_ctx, + *tv, avahi_timeout_handler, + timeout_ctx); + if (timeout_ctx->te == NULL) { + goto fail; + } + } + timeout_ctx->callback = callback; + timeout_ctx->userdata = userdata; + return timeout_ctx; + + fail: + TALLOC_FREE(timeout_ctx); + ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *, + num_timeouts); + return NULL; +} + +static void avahi_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + AvahiTimeout *timeout_ctx = talloc_get_type_abort( + private_data, AvahiTimeout); + + TALLOC_FREE(timeout_ctx->te); + timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata); +} + +static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv) +{ + TALLOC_FREE(t->te); + + t->te = tevent_add_timer(t->ctx->ev, t, *tv, avahi_timeout_handler, t); + /* + * No failure mode defined here + */ + SMB_ASSERT(t->te != NULL); +} + +static void avahi_timeout_free(AvahiTimeout *t) +{ + int i, num_timeouts; + AvahiTimeout **timeouts = t->ctx->timeouts; + struct avahi_poll_context *ctx; + + num_timeouts = talloc_array_length(timeouts); + + for (i=0; ictx; + TALLOC_FREE(t); + memmove(&timeouts[i], &timeouts[i+1], + sizeof(*timeouts) * (num_timeouts - i - 1)); + ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *, + num_timeouts - 1); +} + +struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, + struct tevent_context *ev) +{ + struct AvahiPoll *result; + struct avahi_poll_context *ctx; + + result = talloc(mem_ctx, struct AvahiPoll); + if (result == NULL) { + return result; + } + ctx = talloc_zero(result, struct avahi_poll_context); + if (ctx == NULL) { + TALLOC_FREE(result); + return NULL; + } + ctx->ev = ev; + + result->watch_new = avahi_watch_new; + result->watch_update = avahi_watch_update; + result->watch_get_events = avahi_watch_get_events; + result->watch_free = avahi_watch_free; + result->timeout_new = avahi_timeout_new; + result->timeout_update = avahi_timeout_update; + result->timeout_free = avahi_timeout_free; + result->userdata = ctx; + + return result; +} -- cgit From 63aae58fdcd9110ba294ac7335d4a4e40136aa8b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Mar 2009 15:59:33 +0100 Subject: Use avahi to register _smb._tcp in smbd --- source3/configure.in | 2 +- source3/include/proto.h | 5 ++ source3/smbd/avahi_register.c | 170 ++++++++++++++++++++++++++++++++++++++++++ source3/smbd/server.c | 11 +++ 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 source3/smbd/avahi_register.c diff --git a/source3/configure.in b/source3/configure.in index 103edaf369..1cf8d9ca4a 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6032,7 +6032,7 @@ if test x"$enable_avahi" != x"no"; then if test x"$have_avahi_support" = x"yes"; then AC_DEFINE(WITH_AVAHI_SUPPORT, 1, [Whether to enable avahi support]) - AC_SUBST(AVAHI_OBJ, lib/avahi.o) + AC_SUBST(AVAHI_OBJ, "lib/avahi.o smbd/avahi_register.o") else if test x"$enable_avahi" = x"yes"; then AC_MSG_ERROR(avahi support not available) diff --git a/source3/include/proto.h b/source3/include/proto.h index a8c4b14fff..c8dce13916 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7235,6 +7235,11 @@ NTSTATUS nss_info_template_init( void ); struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, struct tevent_context *ev); +/* The following definitions come from smbd/avahi_register.c */ + +void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + uint16_t port); + /* Misc protos */ #endif /* _PROTO_H_ */ diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c new file mode 100644 index 0000000000..1903b0ef96 --- /dev/null +++ b/source3/smbd/avahi_register.c @@ -0,0 +1,170 @@ +/* + * Unix SMB/CIFS implementation. + * Register _smb._tcp with avahi + * + * Copyright (C) Volker Lendecke 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" + +#include +#include +#include + +struct avahi_state_struct { + struct AvahiPoll *poll; + AvahiClient *client; + AvahiEntryGroup *entry_group; + uint16_t port; +}; + +static void avahi_entry_group_callback(AvahiEntryGroup *g, + AvahiEntryGroupState status, + void *userdata) +{ + struct avahi_state_struct *state = talloc_get_type_abort( + userdata, struct avahi_state_struct); + int error; + + switch (status) { + case AVAHI_ENTRY_GROUP_ESTABLISHED: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_ESTABLISHED\n")); + break; + case AVAHI_ENTRY_GROUP_FAILURE: + error = avahi_client_errno(state->client); + + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_FAILURE: %s\n", + avahi_strerror(error))); + break; + case AVAHI_ENTRY_GROUP_COLLISION: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_COLLISION\n")); + break; + case AVAHI_ENTRY_GROUP_UNCOMMITED: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_UNCOMMITED\n")); + break; + case AVAHI_ENTRY_GROUP_REGISTERING: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_REGISTERING\n")); + break; + } +} + +static void avahi_client_callback(AvahiClient *c, AvahiClientState status, + void *userdata) +{ + struct avahi_state_struct *state = talloc_get_type_abort( + userdata, struct avahi_state_struct); + int error; + + switch (status) { + case AVAHI_CLIENT_S_RUNNING: + DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n")); + + state->entry_group = avahi_entry_group_new( + c, avahi_entry_group_callback, state); + if (state->entry_group == NULL) { + error = avahi_client_errno(c); + DEBUG(10, ("avahi_entry_group_new failed: %s\n", + avahi_strerror(error))); + break; + } + if (avahi_entry_group_add_service( + state->entry_group, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, 0, global_myname(), + "_smb._tcp", NULL, NULL, state->port, NULL) < 0) { + error = avahi_client_errno(c); + DEBUG(10, ("avahi_entry_group_add_service failed: " + "%s\n", avahi_strerror(error))); + avahi_entry_group_free(state->entry_group); + state->entry_group = NULL; + break; + } + if (avahi_entry_group_commit(state->entry_group) < 0) { + error = avahi_client_errno(c); + DEBUG(10, ("avahi_entry_group_commit failed: " + "%s\n", avahi_strerror(error))); + avahi_entry_group_free(state->entry_group); + state->entry_group = NULL; + break; + } + break; + case AVAHI_CLIENT_FAILURE: + error = avahi_client_errno(c); + + DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_FAILURE: %s\n", + avahi_strerror(error))); + + if (error != AVAHI_ERR_DISCONNECTED) { + break; + } + avahi_client_free(c); + state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL, + avahi_client_callback, state, + &error); + if (state->client == NULL) { + DEBUG(10, ("avahi_client_new failed: %s\n", + avahi_strerror(error))); + break; + } + break; + case AVAHI_CLIENT_S_COLLISION: + DEBUG(10, ("avahi_client_callback: " + "AVAHI_CLIENT_S_COLLISION\n")); + break; + case AVAHI_CLIENT_S_REGISTERING: + DEBUG(10, ("avahi_client_callback: " + "AVAHI_CLIENT_S_REGISTERING\n")); + break; + case AVAHI_CLIENT_CONNECTING: + DEBUG(10, ("avahi_client_callback: " + "AVAHI_CLIENT_CONNECTING\n")); + break; + } +} + +void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + uint16_t port) +{ + struct avahi_state_struct *state; + int error; + + state = talloc(mem_ctx, struct avahi_state_struct); + if (state == NULL) { + return state; + } + state->port = port; + state->poll = tevent_avahi_poll(state, ev); + if (state->poll == NULL) { + goto fail; + } + state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL, + avahi_client_callback, state, + &error); + if (state->client == NULL) { + DEBUG(10, ("avahi_client_new failed: %s\n", + avahi_strerror(error))); + goto fail; + } + return state; + + fail: + TALLOC_FREE(state); + return NULL; +} diff --git a/source3/smbd/server.c b/source3/smbd/server.c index d27f98281b..67836f785b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -643,8 +643,19 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent, #endif if (dns_port != 0) { +#ifdef WITH_DNSSD_SUPPORT smbd_setup_mdns_registration(smbd_event_context(), parent, dns_port); +#endif +#ifdef WITH_AVAHI_SUPPORT + void *avahi_conn; + + avahi_conn = avahi_start_register( + smbd_event_context(), smbd_event_context(), dns_port); + if (avahi_conn == NULL) { + DEBUG(10, ("avahi_start_register failed\n")); + } +#endif } return true; -- cgit From 33d9f46674a270a0715213c17581deef192826e1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 23 Mar 2009 17:36:46 +0100 Subject: libreplace: use libreplace_SAVE_CPPFLAGS instead of SAVE_CPPFLAGS This fixes Samba3's double listing of -I options in CFLAGS, since samba3's configure wraps the call to AC_LIBREPLACE_NETWORK_CHECKS into a SAVE_CPPFLAGS="${CPPFLAGS}" .. CPPFLAGS="${SAVE_CPPFLAGS}" sequence... :-) Michael --- lib/replace/libreplace_network.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/replace/libreplace_network.m4 b/lib/replace/libreplace_network.m4 index 3bac72d136..2af02312ab 100644 --- a/lib/replace/libreplace_network.m4 +++ b/lib/replace/libreplace_network.m4 @@ -170,7 +170,7 @@ fi # The following tests need LIBS="${LIBREPLACE_NETWORK_LIBS}" old_LIBS=$LIBS LIBS="${LIBREPLACE_NETWORK_LIBS}" -SAVE_CPPFLAGS="$CPPFLAGS" +libreplace_SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$libreplacedir" AC_CHECK_FUNCS(socketpair,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} socketpair.o"]) @@ -381,7 +381,7 @@ if test x"$libreplace_cv_HAVE_IPV6" = x"yes"; then fi LIBS=$old_LIBS -CPPFLAGS="$SAVE_CPPFLAGS" +CPPFLAGS="$libreplace_SAVE_CPPFLAGS" LIBREPLACEOBJ="${LIBREPLACEOBJ} ${LIBREPLACE_NETWORK_OBJS}" -- cgit From 36b957b5b7a1f70e39eeef224820739f24b999c9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 23 Mar 2009 17:47:26 +0100 Subject: s3:build: make SHOWFLAGS target phony and add alias showflags Michael --- source3/Makefile.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index 329ded0716..b28109ec60 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1281,6 +1281,10 @@ everything:: all libtalloc libsmbclient libnetapi debug2html smbfilter talloctor .SUFFIXES: .SUFFIXES: .c .o .lo +.PHONY: showflags SHOWFLAGS + +showflags: SHOWFLAGS + SHOWFLAGS:: @echo "Using CFLAGS = $(CFLAGS)" @echo " PICFLAG = $(PICFLAG)" -- cgit From 866afd5d0b1a4a9429f5cdeae01409a15770b6e3 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 23 Mar 2009 11:55:58 -0700 Subject: s3: Remove redundant comment --- source3/param/loadparm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 8460fea567..66fb8bf1bc 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -9542,10 +9542,6 @@ const char *lp_printcapname(void) return PRINTCAP_NAME; } -/******************************************************************* - Ensure we don't use sendfile if server smb signing is active. -********************************************************************/ - static uint32 spoolss_state; bool lp_disable_spoolss( void ) -- cgit From 130582f170cdcc2b6eb2a950ca4ebda916c8399a Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 23 Mar 2009 11:57:13 -0700 Subject: s3 OneFS: Remove usage of non-existant function The function was removed in: c16c90a1cb3b0e2ceadd3dea835a4e69acfc2fae --- source3/modules/onefs_open.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index c5030f4ab8..5a488f894c 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -386,15 +386,6 @@ static void defer_open(struct share_mode_lock *lck, exit_server("push_deferred_smb_message failed"); } add_deferred_open(lck, req->mid, request_time, state->id); - - /* - * Push the MID of this packet on the signing queue. - * We only do this once, the first time we push the packet - * onto the deferred open queue, as this has a side effect - * of incrementing the response sequence number. - */ - - srv_defer_sign_response(req->mid); } static void schedule_defer_open(struct share_mode_lock *lck, -- cgit From 2a8f367b0ff567223144bd41e97684301d540f57 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Mar 2009 16:28:39 +1100 Subject: the start of a possibleInferiors test suite we haven't implemented possibleInferiors yet. This test is meant to help us understand how it works. It tries to construct possibleInferiors via searches on other attributes, and compares it to the servers constructed possibleInferiors attribute for each class in the servers schema. see [MS-ADTS] section 3.1.1.4.5.21 --- .../samdb/ldb_modules/tests/possibleinferiors.py | 155 +++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100755 source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py diff --git a/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py new file mode 100755 index 0000000000..0e74456dac --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py @@ -0,0 +1,155 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Andrew Tridgell 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 . +# + +"""Tests the possibleInferiors generation in the schema_fsmo ldb module""" + +import optparse +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 +import ldb + +parser = optparse.OptionParser("possibleinferiors.py []") +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)) + +opts, args = parser.parse_args() + +if len(args) < 1: + parser.print_usage() + sys.exit(1) + +url = args[0] +if (len(args) > 1): + objectclass = args[1] +else: + objectclass = None + +def uniq_list(alist): + """return a unique list""" + set = {} + return [set.setdefault(e,e) for e in alist if e not in set] + + +lp_ctx = sambaopts.get_loadparm() + +creds = credopts.get_credentials(lp_ctx) +db = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"]) + +# get the rootDSE +res = db.search(base="", expression="", + scope=ldb.SCOPE_BASE, + attrs=["schemaNamingContext"]) +rootDse = res[0] + +schema_base = rootDse["schemaNamingContext"][0] + +def possible_inferiors_search(db, oc): + """return the possible inferiors via a search for the possibleInferiors attribute""" + res = db.search(base=schema_base, + expression=("ldapdisplayname=%s" % oc), + attrs=["possibleInferiors"]) + + poss=[] + if len(res) == 0 or res[0].get("possibleInferiors") is None: + return poss + for item in res[0]["possibleInferiors"]: + poss.append(str(item)) + poss = uniq_list(poss) + poss.sort() + return poss; + + + +# see [MS-ADTS] section 3.1.1.4.5.21 +# for this algorithm + +# !systemOnly=TRUE +# !objectClassCategory=2 +# !objectClassCategory=3 + +def POSSINFERIORS(db, oc): + """returns a list of possible inferiors to a class. Returned list has the ldapdisplayname, systemOnly and objectClassCategory for each element""" + expanded = [oc] + res = db.search(base=schema_base, + expression=("subclassof=%s" % str(oc["ldapdisplayname"][0])), + attrs=["ldapdisplayname", "systemOnly", "objectClassCategory"]) + for r in res: + expanded.extend(POSSINFERIORS(db,r)) + return expanded + +def possible_inferiors_constructed(db, oc): + """return the possbible inferiors via a recursive search and match""" + res = db.search(base=schema_base, + expression=("(&(objectclass=classSchema)(|(posssuperiors=%s)(systemposssuperiors=%s)))" % (oc,oc)), + attrs=["ldapdisplayname", "systemOnly", "objectClassCategory"]) + + poss = [] + for r in res: + poss.extend(POSSINFERIORS(db,r)) + + poss2 = [] + for p in poss: + if (not (p["systemOnly"][0] == "TRUE" or + int(p["objectClassCategory"][0]) == 2 or + int(p["objectClassCategory"][0]) == 3)): + poss2.append(p["ldapdisplayname"][0]) + + poss2 = uniq_list(poss2) + poss2.sort() + return poss2 + +def test_class(db, oc): + """test to see if one objectclass returns the correct possibleInferiors""" + poss1 = possible_inferiors_search(db, oc) + poss2 = possible_inferiors_constructed(db, oc) + if poss1 != poss2: + print "Returned incorrect list for objectclass %s" % oc + print poss1 + print poss2 + for i in range(0,min(len(poss1),len(poss2))): + print "%30s %30s" % (poss1[i], poss2[i]) + exit(1) + +def get_object_classes(db): + """return a list of all object classes""" + res = db.search(base=schema_base, + expression="objectClass=classSchema", + attrs=["ldapdisplayname"]) + list=[] + for item in res: + list.append(item["ldapdisplayname"][0]) + return list + +if objectclass is None: + for oc in get_object_classes(db): + print "testing objectClass %s" % oc + test_class(db,oc) +else: + test_class(db,objectclass) + +print "Lists match OK" -- cgit From 87b428e424e2e3cca975ecd0efed327e72950a1d Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 12:26:03 +0100 Subject: s3:dsgetdcname: use parentheses in if condition to make negation clear MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Günther Deschner --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 3491544175..1064a63d97 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -311,7 +311,7 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response * /**************************************************************** ****************************************************************/ -#define RETURN_ON_FALSE(x) if (!x) return false; +#define RETURN_ON_FALSE(x) if (!(x)) return false; static bool check_cldap_reply_required_flags(uint32_t ret_flags, uint32_t req_flags) -- cgit From c388efdbcb9ef1ecd5a81f7731ce56c7f79b2579 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Mar 2009 11:02:40 +0100 Subject: s3: add missing prototype for auth_wbc_init(). Guenther --- source3/include/proto.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index c8dce13916..d15e45a874 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -150,6 +150,10 @@ bool is_trusted_domain(const char* dom_name); NTSTATUS auth_winbind_init(void); +/* The following definitions come from auth/auth_wbc.c */ + +NTSTATUS auth_wbc_init(void); + /* The following definitions come from auth/pampass.c */ bool smb_pam_claim_session(char *user, char *tty, char *rhost); -- cgit From 8d901caf353ce99dfdde4e9e8ad5937f91df7c49 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 23:25:53 +0100 Subject: move dcerpc.idl to main directory. Guenther --- librpc/idl/dcerpc.idl | 306 ++++++++++++++++++++++++++++++++++++++++++ source4/librpc/config.mk | 4 +- source4/librpc/idl/dcerpc.idl | 306 ------------------------------------------ 3 files changed, 308 insertions(+), 308 deletions(-) create mode 100644 librpc/idl/dcerpc.idl delete mode 100644 source4/librpc/idl/dcerpc.idl diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl new file mode 100644 index 0000000000..3ec416d5c6 --- /dev/null +++ b/librpc/idl/dcerpc.idl @@ -0,0 +1,306 @@ +#include "idl_types.h" + +/* + the base dcerpc packet definitions - not traditionally coded as IDL, + but given that pidl can handle it nicely it simplifies things a lot + to do it this way + + see http://www.opengroup.org/onlinepubs/9629399/chap12.htm for packet + layouts +*/ +import "misc.idl"; + +interface dcerpc +{ + typedef struct { + uint16 context_id; + uint8 num_transfer_syntaxes; + ndr_syntax_id abstract_syntax; + ndr_syntax_id transfer_syntaxes[num_transfer_syntaxes]; + } dcerpc_ctx_list; + + typedef struct { + uint16 max_xmit_frag; + uint16 max_recv_frag; + uint32 assoc_group_id; + uint8 num_contexts; + dcerpc_ctx_list ctx_list[num_contexts]; + [flag(NDR_ALIGN4)] DATA_BLOB _pad; + [flag(NDR_REMAINING)] DATA_BLOB auth_info; + } dcerpc_bind; + + const uint8 DCERPC_REQUEST_LENGTH = 24; + + typedef struct { + } dcerpc_empty; + + typedef [nodiscriminant] union { + [default] dcerpc_empty empty; + [case(LIBNDR_FLAG_OBJECT_PRESENT)] GUID object; + } dcerpc_object; + + typedef struct { + uint32 alloc_hint; + uint16 context_id; + uint16 opnum; + [switch_is(ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)] dcerpc_object object; + [flag(NDR_ALIGN8)] DATA_BLOB _pad; + [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier; + } dcerpc_request; + + const int DCERPC_BIND_REASON_ASYNTAX = 1; + const int DCERPC_BIND_PROVIDER_REJECT = 2; + const int DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED = 4; + const int DCERPC_BIND_REASON_INVALID_AUTH_TYPE = 8; + + typedef struct { + uint16 result; + uint16 reason; + ndr_syntax_id syntax; + } dcerpc_ack_ctx; + + typedef struct { + uint16 max_xmit_frag; + uint16 max_recv_frag; + uint32 assoc_group_id; + [value(strlen(secondary_address)+1)] uint16 secondary_address_size; + [charset(DOS)] uint8 secondary_address[secondary_address_size]; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + uint8 num_results; + dcerpc_ack_ctx ctx_list[num_results]; + [flag(NDR_REMAINING)] DATA_BLOB auth_info; + } dcerpc_bind_ack; + + typedef struct { + uint32 num_versions; + uint32 versions[num_versions]; + } dcerpc_bind_nak_versions; + + typedef [nodiscriminant] union { + [case(DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED)] dcerpc_bind_nak_versions v; + [default] ; + } dcerpc_bind_nak_versions_ctr; + + typedef struct { + uint16 reject_reason; + [switch_is(reject_reason)] dcerpc_bind_nak_versions_ctr versions; + } dcerpc_bind_nak; + + const uint8 DCERPC_RESPONSE_LENGTH = 24; + + typedef struct { + uint32 alloc_hint; + uint16 context_id; + uint8 cancel_count; + [flag(NDR_ALIGN8)] DATA_BLOB _pad; + [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier; + } dcerpc_response; + + + const int DCERPC_FAULT_OP_RNG_ERROR = 0x1c010002; + const int DCERPC_FAULT_UNK_IF = 0x1c010003; + const int DCERPC_FAULT_NDR = 0x000006f7; + const int DCERPC_FAULT_INVALID_TAG = 0x1c000006; + const int DCERPC_FAULT_CONTEXT_MISMATCH = 0x1c00001a; + const int DCERPC_FAULT_OTHER = 0x00000001; + const int DCERPC_FAULT_ACCESS_DENIED = 0x00000005; + const int DCERPC_FAULT_CANT_PERFORM = 0x000006d8; + + /* we return this fault when we haven't yet run the test + to see what fault w2k3 returns in this case */ + const int DCERPC_FAULT_TODO = 0x00000042; + + typedef struct { + uint32 alloc_hint; + uint16 context_id; + uint8 cancel_count; + uint32 status; + [flag(NDR_REMAINING)] DATA_BLOB _pad; + } dcerpc_fault; + + /* the auth types we know about */ + typedef [enum8bit] enum { + DCERPC_AUTH_TYPE_NONE = 0, + /* this seems to be not krb5! */ + DCERPC_AUTH_TYPE_KRB5_1 = 1, + DCERPC_AUTH_TYPE_SPNEGO = 9, + DCERPC_AUTH_TYPE_NTLMSSP = 10, + DCERPC_AUTH_TYPE_KRB5 = 16, + DCERPC_AUTH_TYPE_DPA = 17, + DCERPC_AUTH_TYPE_MSN = 18, + DCERPC_AUTH_TYPE_DIGEST = 21, + DCERPC_AUTH_TYPE_SCHANNEL = 68, + DCERPC_AUTH_TYPE_MSMQ = 100 + } dcerpc_AuthType; + + typedef [enum8bit] enum { + DCERPC_AUTH_LEVEL_NONE = 1, + DCERPC_AUTH_LEVEL_CONNECT = 2, + DCERPC_AUTH_LEVEL_CALL = 3, + DCERPC_AUTH_LEVEL_PACKET = 4, + DCERPC_AUTH_LEVEL_INTEGRITY = 5, + DCERPC_AUTH_LEVEL_PRIVACY = 6 + } dcerpc_AuthLevel; + + const uint8 DCERPC_AUTH_LEVEL_DEFAULT = DCERPC_AUTH_LEVEL_CONNECT; + + typedef [public] struct { + dcerpc_AuthType auth_type; + dcerpc_AuthLevel auth_level; + uint8 auth_pad_length; + uint8 auth_reserved; + uint32 auth_context_id; + [flag(NDR_REMAINING)] DATA_BLOB credentials; + } dcerpc_auth; + + const uint8 DCERPC_AUTH_TRAILER_LENGTH = 8; + + typedef [public] struct { + uint32 _pad; + [flag(NDR_REMAINING)] DATA_BLOB auth_info; + } dcerpc_auth3; + + typedef [public] struct { + uint32 _pad; + [flag(NDR_REMAINING)] DATA_BLOB auth_info; + } dcerpc_orphaned; + + typedef [public] struct { + uint32 _pad; + [flag(NDR_REMAINING)] DATA_BLOB auth_info; + } dcerpc_co_cancel; + + typedef [public] struct { + uint32 version; + uint32 id; + } dcerpc_cl_cancel; + + typedef [public] struct { + uint32 version; + uint32 id; + boolean32 server_is_accepting; + } dcerpc_cancel_ack; + + typedef [public] struct { + uint32 version; + uint8 _pad1; + uint16 window_size; + uint32 max_tdsu; + uint32 max_frag_size; + uint16 serial_no; + uint16 selack_size; + uint32 selack[selack_size]; + } dcerpc_fack; + + typedef [public] struct { + } dcerpc_ack; + + typedef [public] struct { + } dcerpc_ping; + + typedef [public] struct { + } dcerpc_shutdown; + + typedef [public] struct { + } dcerpc_working; + + typedef [enum8bit] enum { + DCERPC_PKT_REQUEST = 0, /* Ordinary request. */ + DCERPC_PKT_PING = 1, /* Connectionless is server alive ? */ + DCERPC_PKT_RESPONSE = 2, /* Ordinary reply. */ + DCERPC_PKT_FAULT = 3, /* Fault in processing of call. */ + DCERPC_PKT_WORKING = 4, /* Connectionless reply to a ping when server busy. */ + DCERPC_PKT_NOCALL = 5, /* Connectionless reply to a ping when server has lost part of clients call. */ + DCERPC_PKT_REJECT = 6, /* Refuse a request with a code. */ + DCERPC_PKT_ACK = 7, /* Connectionless client to server code. */ + DCERPC_PKT_CL_CANCEL = 8, /* Connectionless cancel. */ + DCERPC_PKT_FACK = 9, /* Connectionless fragment ack. Both client and server send. */ + DCERPC_PKT_CANCEL_ACK = 10, /* Server ACK to client cancel request. */ + DCERPC_PKT_BIND = 11, /* Bind to interface. */ + DCERPC_PKT_BIND_ACK = 12, /* Server ack of bind. */ + DCERPC_PKT_BIND_NAK = 13, /* Server nack of bind. */ + DCERPC_PKT_ALTER = 14, /* Alter auth. */ + DCERPC_PKT_ALTER_RESP = 15, /* Reply to alter auth. */ + DCERPC_PKT_AUTH3 = 16, /* not the real name! this is undocumented! */ + DCERPC_PKT_SHUTDOWN = 17, /* Server to client request to shutdown. */ + DCERPC_PKT_CO_CANCEL = 18, /* Connection-oriented cancel request. */ + DCERPC_PKT_ORPHANED = 19 /* Client telling server it's aborting a partially sent request or telling server to stop sending replies. */ + } dcerpc_pkt_type; + + typedef [nodiscriminant] union { + [case(DCERPC_PKT_REQUEST)] dcerpc_request request; + [case(DCERPC_PKT_PING)] dcerpc_ping ping; + [case(DCERPC_PKT_RESPONSE)] dcerpc_response response; + [case(DCERPC_PKT_FAULT)] dcerpc_fault fault; + [case(DCERPC_PKT_WORKING)] dcerpc_working working; + [case(DCERPC_PKT_NOCALL)] dcerpc_fack nocall; + [case(DCERPC_PKT_REJECT)] dcerpc_fault reject; + [case(DCERPC_PKT_ACK)] dcerpc_ack ack; + [case(DCERPC_PKT_CL_CANCEL)] dcerpc_cl_cancel cl_cancel; + [case(DCERPC_PKT_FACK)] dcerpc_fack fack; + [case(DCERPC_PKT_CANCEL_ACK)] dcerpc_cancel_ack cancel_ack; + [case(DCERPC_PKT_BIND)] dcerpc_bind bind; + [case(DCERPC_PKT_BIND_ACK)] dcerpc_bind_ack bind_ack; + [case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak; + [case(DCERPC_PKT_ALTER)] dcerpc_bind alter; + [case(DCERPC_PKT_ALTER_RESP)] dcerpc_bind_ack alter_resp; + [case(DCERPC_PKT_SHUTDOWN)] dcerpc_shutdown shutdown; + [case(DCERPC_PKT_CO_CANCEL)] dcerpc_co_cancel co_cancel; + [case(DCERPC_PKT_ORPHANED)] dcerpc_orphaned orphaned; + [case(DCERPC_PKT_AUTH3)] dcerpc_auth3 auth3; + } dcerpc_payload; + + /* pfc_flags values */ + const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */ + const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */ + const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */ + const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */ + const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */ + const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */ + const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */ + const uint8 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80; /* on valid guid is in the optional object field */ + + /* these offsets are needed by the signing code */ + const uint8 DCERPC_PFC_OFFSET = 3; + const uint8 DCERPC_DREP_OFFSET = 4; + const uint8 DCERPC_FRAG_LEN_OFFSET = 8; + const uint8 DCERPC_AUTH_LEN_OFFSET = 10; + + /* little-endian flag */ + const uint8 DCERPC_DREP_LE = 0x10; + + typedef [public] struct { + uint8 rpc_vers; /* RPC version */ + uint8 rpc_vers_minor; /* Minor version */ + dcerpc_pkt_type ptype; /* Packet type */ + uint8 pfc_flags; /* Fragmentation flags */ + uint8 drep[4]; /* NDR data representation */ + uint16 frag_length; /* Total length of fragment */ + uint16 auth_length; /* authenticator length */ + uint32 call_id; /* Call identifier */ + [switch_is(ptype)] dcerpc_payload u; + } ncacn_packet; + + typedef [public] struct { + uint8 rpc_vers; /* RPC version (4) */ + uint8 ptype; + uint8 pfc_flags; + uint8 ncadg_flags; + uint8 drep[3]; + uint8 serial_high; + GUID object; + GUID iface; + GUID activity; + uint32 server_boot; /* Server boot time */ + uint32 iface_version; + uint32 seq_num; + uint16 opnum; + uint16 ihint; + uint16 ahint; + uint16 len; + uint16 fragnum; + uint8 auth_proto; + uint8 serial_low; + [switch_is(ptype)] dcerpc_payload u; + } ncadg_packet; +} diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 2f1b14dc37..64a4750ab7 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -595,9 +595,9 @@ RPC_NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc_c.o [SUBSYSTEM::NDR_DCERPC] PUBLIC_DEPENDENCIES = LIBNDR -NDR_DCERPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcerpc.o +NDR_DCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_dcerpc.o -PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/dcerpc.h gen_ndr/ndr_dcerpc.h) +PUBLIC_HEADERS += ../librpc/gen_ndr/dcerpc.h ../librpc/gen_ndr/ndr_dcerpc.h ################################################ # Start SUBSYSTEM dcerpc diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl deleted file mode 100644 index 7c0abe6ab8..0000000000 --- a/source4/librpc/idl/dcerpc.idl +++ /dev/null @@ -1,306 +0,0 @@ -#include "idl_types.h" - -/* - the base dcerpc packet definitions - not traditionally coded as IDL, - but given that pidl can handle it nicely it simplifies things a lot - to do it this way - - see http://www.opengroup.org/onlinepubs/9629399/chap12.htm for packet - layouts -*/ -import "misc.idl"; - -interface dcerpc -{ - typedef struct { - uint16 context_id; - uint8 num_transfer_syntaxes; - ndr_syntax_id abstract_syntax; - ndr_syntax_id transfer_syntaxes[num_transfer_syntaxes]; - } dcerpc_ctx_list; - - typedef struct { - uint16 max_xmit_frag; - uint16 max_recv_frag; - uint32 assoc_group_id; - uint8 num_contexts; - dcerpc_ctx_list ctx_list[num_contexts]; - [flag(NDR_ALIGN4)] DATA_BLOB _pad; - [flag(NDR_REMAINING)] DATA_BLOB auth_info; - } dcerpc_bind; - - const uint8 DCERPC_REQUEST_LENGTH = 24; - - typedef struct { - } dcerpc_empty; - - typedef [nodiscriminant] union { - [default] dcerpc_empty empty; - [case(LIBNDR_FLAG_OBJECT_PRESENT)] GUID object; - } dcerpc_object; - - typedef struct { - uint32 alloc_hint; - uint16 context_id; - uint16 opnum; - [switch_is(ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)] dcerpc_object object; - [flag(NDR_ALIGN8)] DATA_BLOB _pad; - [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier; - } dcerpc_request; - - const int DCERPC_BIND_REASON_ASYNTAX = 1; - const int DCERPC_BIND_PROVIDER_REJECT = 2; - const int DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED = 4; - const int DCERPC_BIND_REASON_INVALID_AUTH_TYPE = 8; - - typedef struct { - uint16 result; - uint16 reason; - ndr_syntax_id syntax; - } dcerpc_ack_ctx; - - typedef struct { - uint16 max_xmit_frag; - uint16 max_recv_frag; - uint32 assoc_group_id; - [value(strlen(secondary_address)+1)] uint16 secondary_address_size; - [charset(DOS)] uint8 secondary_address[secondary_address_size]; - [flag(NDR_ALIGN4)] DATA_BLOB _pad1; - uint8 num_results; - dcerpc_ack_ctx ctx_list[num_results]; - [flag(NDR_REMAINING)] DATA_BLOB auth_info; - } dcerpc_bind_ack; - - typedef struct { - uint32 num_versions; - uint32 versions[num_versions]; - } dcerpc_bind_nak_versions; - - typedef [nodiscriminant] union { - [case(DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED)] dcerpc_bind_nak_versions v; - [default] ; - } dcerpc_bind_nak_versions_ctr; - - typedef struct { - uint16 reject_reason; - [switch_is(reject_reason)] dcerpc_bind_nak_versions_ctr versions; - } dcerpc_bind_nak; - - const uint8 DCERPC_RESPONSE_LENGTH = 24; - - typedef struct { - uint32 alloc_hint; - uint16 context_id; - uint8 cancel_count; - [flag(NDR_ALIGN8)] DATA_BLOB _pad; - [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier; - } dcerpc_response; - - - const int DCERPC_FAULT_OP_RNG_ERROR = 0x1c010002; - const int DCERPC_FAULT_UNK_IF = 0x1c010003; - const int DCERPC_FAULT_NDR = 0x000006f7; - const int DCERPC_FAULT_INVALID_TAG = 0x1c000006; - const int DCERPC_FAULT_CONTEXT_MISMATCH = 0x1c00001a; - const int DCERPC_FAULT_OTHER = 0x00000001; - const int DCERPC_FAULT_ACCESS_DENIED = 0x00000005; - const int DCERPC_FAULT_CANT_PERFORM = 0x000006d8; - - /* we return this fault when we haven't yet run the test - to see what fault w2k3 returns in this case */ - const int DCERPC_FAULT_TODO = 0x00000042; - - typedef struct { - uint32 alloc_hint; - uint16 context_id; - uint8 cancel_count; - uint32 status; - [flag(NDR_REMAINING)] DATA_BLOB _pad; - } dcerpc_fault; - - /* the auth types we know about */ - typedef [enum8bit] enum { - DCERPC_AUTH_TYPE_NONE = 0, - /* this seems to be not krb5! */ - DCERPC_AUTH_TYPE_KRB5_1 = 1, - DCERPC_AUTH_TYPE_SPNEGO = 9, - DCERPC_AUTH_TYPE_NTLMSSP = 10, - DCERPC_AUTH_TYPE_KRB5 = 16, - DCERPC_AUTH_TYPE_DPA = 17, - DCERPC_AUTH_TYPE_MSN = 18, - DCERPC_AUTH_TYPE_DIGEST = 21, - DCERPC_AUTH_TYPE_SCHANNEL = 68, - DCERPC_AUTH_TYPE_MSMQ = 100 - } dcerpc_AuthType; - - typedef [enum8bit] enum { - DCERPC_AUTH_LEVEL_NONE = 1, - DCERPC_AUTH_LEVEL_CONNECT = 2, - DCERPC_AUTH_LEVEL_CALL = 3, - DCERPC_AUTH_LEVEL_PACKET = 4, - DCERPC_AUTH_LEVEL_INTEGRITY = 5, - DCERPC_AUTH_LEVEL_PRIVACY = 6 - } dcerpc_AuthLevel; - - const uint8 DCERPC_AUTH_LEVEL_DEFAULT = DCERPC_AUTH_LEVEL_CONNECT; - - typedef [public] struct { - dcerpc_AuthType auth_type; - dcerpc_AuthLevel auth_level; - uint8 auth_pad_length; - uint8 auth_reserved; - uint32 auth_context_id; - [flag(NDR_REMAINING)] DATA_BLOB credentials; - } dcerpc_auth; - - const uint8 DCERPC_AUTH_TRAILER_LENGTH = 8; - - typedef [public] struct { - uint32 _pad; - [flag(NDR_REMAINING)] DATA_BLOB auth_info; - } dcerpc_auth3; - - typedef [public] struct { - uint32 _pad; - [flag(NDR_REMAINING)] DATA_BLOB auth_info; - } dcerpc_orphaned; - - typedef [public] struct { - uint32 _pad; - [flag(NDR_REMAINING)] DATA_BLOB auth_info; - } dcerpc_co_cancel; - - typedef [public] struct { - uint32 version; - uint32 id; - } dcerpc_cl_cancel; - - typedef [public] struct { - uint32 version; - uint32 id; - boolean32 server_is_accepting; - } dcerpc_cancel_ack; - - typedef [public] struct { - uint32 version; - uint8 _pad1; - uint16 window_size; - uint32 max_tdsu; - uint32 max_frag_size; - uint16 serial_no; - uint16 selack_size; - uint32 selack[selack_size]; - } dcerpc_fack; - - typedef [public] struct { - } dcerpc_ack; - - typedef [public] struct { - } dcerpc_ping; - - typedef [public] struct { - } dcerpc_shutdown; - - typedef [public] struct { - } dcerpc_working; - - typedef [enum8bit] enum { - DCERPC_PKT_REQUEST = 0, /* Ordinary request. */ - DCERPC_PKT_PING = 1, /* Connectionless is server alive ? */ - DCERPC_PKT_RESPONSE = 2, /* Ordinary reply. */ - DCERPC_PKT_FAULT = 3, /* Fault in processing of call. */ - DCERPC_PKT_WORKING = 4, /* Connectionless reply to a ping when server busy. */ - DCERPC_PKT_NOCALL = 5, /* Connectionless reply to a ping when server has lost part of clients call. */ - DCERPC_PKT_REJECT = 6, /* Refuse a request with a code. */ - DCERPC_PKT_ACK = 7, /* Connectionless client to server code. */ - DCERPC_PKT_CL_CANCEL = 8, /* Connectionless cancel. */ - DCERPC_PKT_FACK = 9, /* Connectionless fragment ack. Both client and server send. */ - DCERPC_PKT_CANCEL_ACK = 10, /* Server ACK to client cancel request. */ - DCERPC_PKT_BIND = 11, /* Bind to interface. */ - DCERPC_PKT_BIND_ACK = 12, /* Server ack of bind. */ - DCERPC_PKT_BIND_NAK = 13, /* Server nack of bind. */ - DCERPC_PKT_ALTER = 14, /* Alter auth. */ - DCERPC_PKT_ALTER_RESP = 15, /* Reply to alter auth. */ - DCERPC_PKT_AUTH3 = 16, /* not the real name! this is undocumented! */ - DCERPC_PKT_SHUTDOWN = 17, /* Server to client request to shutdown. */ - DCERPC_PKT_CO_CANCEL = 18, /* Connection-oriented cancel request. */ - DCERPC_PKT_ORPHANED = 19 /* Client telling server it's aborting a partially sent request or telling server to stop sending replies. */ - } dcerpc_pkt_type; - - typedef [nodiscriminant] union { - [case(DCERPC_PKT_REQUEST)] dcerpc_request request; - [case(DCERPC_PKT_PING)] dcerpc_ping ping; - [case(DCERPC_PKT_RESPONSE)] dcerpc_response response; - [case(DCERPC_PKT_FAULT)] dcerpc_fault fault; - [case(DCERPC_PKT_WORKING)] dcerpc_working working; - [case(DCERPC_PKT_NOCALL)] dcerpc_fack nocall; - [case(DCERPC_PKT_REJECT)] dcerpc_fault reject; - [case(DCERPC_PKT_ACK)] dcerpc_ack ack; - [case(DCERPC_PKT_CL_CANCEL)] dcerpc_cl_cancel cl_cancel; - [case(DCERPC_PKT_FACK)] dcerpc_fack fack; - [case(DCERPC_PKT_CANCEL_ACK)] dcerpc_cancel_ack cancel_ack; - [case(DCERPC_PKT_BIND)] dcerpc_bind bind; - [case(DCERPC_PKT_BIND_ACK)] dcerpc_bind_ack bind_ack; - [case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak; - [case(DCERPC_PKT_ALTER)] dcerpc_bind alter; - [case(DCERPC_PKT_ALTER_RESP)] dcerpc_bind_ack alter_resp; - [case(DCERPC_PKT_SHUTDOWN)] dcerpc_shutdown shutdown; - [case(DCERPC_PKT_CO_CANCEL)] dcerpc_co_cancel co_cancel; - [case(DCERPC_PKT_ORPHANED)] dcerpc_orphaned orphaned; - [case(DCERPC_PKT_AUTH3)] dcerpc_auth3 auth3; - } dcerpc_payload; - - /* pfc_flags values */ - const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */ - const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */ - const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */ - const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */ - const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */ - const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */ - const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */ - const uint8 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80; /* on valid guid is in the optional object field */ - - /* these offsets are needed by the signing code */ - const uint8 DCERPC_PFC_OFFSET = 3; - const uint8 DCERPC_DREP_OFFSET = 4; - const uint8 DCERPC_FRAG_LEN_OFFSET = 8; - const uint8 DCERPC_AUTH_LEN_OFFSET = 10; - - /* little-endian flag */ - const uint8 DCERPC_DREP_LE = 0x10; - - typedef [public] struct { - uint8 rpc_vers; /* RPC version */ - uint8 rpc_vers_minor; /* Minor version */ - dcerpc_pkt_type ptype; /* Packet type */ - uint8 pfc_flags; /* Fragmentation flags */ - uint8 drep[4]; /* NDR data representation */ - uint16 frag_length; /* Total length of fragment */ - uint16 auth_length; /* authenticator length */ - uint32 call_id; /* Call identifier */ - [switch_is(ptype)] dcerpc_payload u; - } ncacn_packet; - - typedef [public] struct { - uint8 rpc_vers; /* RPC version (4) */ - uint8 ptype; - uint8 pfc_flags; - uint8 ncadg_flags; - uint8 drep[3]; - uint8 serial_high; - GUID object; - GUID iface; - GUID activity; - uint32 server_boot; /* Server boot time */ - uint32 iface_version; - uint32 seq_num; - uint16 opnum; - uint16 ihint; - uint16 ahint; - uint16 len; - uint16 fragnum; - uint8 auth_proto; - uint8 serial_low; - [switch_is(ptype)] dcerpc_payload u; - } ncadg_packet; -} -- cgit From 31db53c3586339b7469802a454a3b983807ec518 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 23:27:15 +0100 Subject: s3: add generated dcerpc files. Guenther --- librpc/gen_ndr/dcerpc.h | 343 ++++++++ librpc/gen_ndr/ndr_dcerpc.c | 1834 +++++++++++++++++++++++++++++++++++++++++++ librpc/gen_ndr/ndr_dcerpc.h | 65 ++ 3 files changed, 2242 insertions(+) create mode 100644 librpc/gen_ndr/dcerpc.h create mode 100644 librpc/gen_ndr/ndr_dcerpc.c create mode 100644 librpc/gen_ndr/ndr_dcerpc.h diff --git a/librpc/gen_ndr/dcerpc.h b/librpc/gen_ndr/dcerpc.h new file mode 100644 index 0000000000..78834f6d28 --- /dev/null +++ b/librpc/gen_ndr/dcerpc.h @@ -0,0 +1,343 @@ +/* header auto-generated by pidl */ + +#include + +#include "libcli/util/ntstatus.h" + +#include "librpc/gen_ndr/misc.h" +#ifndef _HEADER_dcerpc +#define _HEADER_dcerpc + +#define DCERPC_REQUEST_LENGTH ( 24 ) +#define DCERPC_BIND_REASON_ASYNTAX ( 1 ) +#define DCERPC_BIND_PROVIDER_REJECT ( 2 ) +#define DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED ( 4 ) +#define DCERPC_BIND_REASON_INVALID_AUTH_TYPE ( 8 ) +#define DCERPC_RESPONSE_LENGTH ( 24 ) +#define DCERPC_FAULT_OP_RNG_ERROR ( 0x1c010002 ) +#define DCERPC_FAULT_UNK_IF ( 0x1c010003 ) +#define DCERPC_FAULT_NDR ( 0x000006f7 ) +#define DCERPC_FAULT_INVALID_TAG ( 0x1c000006 ) +#define DCERPC_FAULT_CONTEXT_MISMATCH ( 0x1c00001a ) +#define DCERPC_FAULT_OTHER ( 0x00000001 ) +#define DCERPC_FAULT_ACCESS_DENIED ( 0x00000005 ) +#define DCERPC_FAULT_CANT_PERFORM ( 0x000006d8 ) +#define DCERPC_FAULT_TODO ( 0x00000042 ) +#define DCERPC_AUTH_LEVEL_DEFAULT ( DCERPC_AUTH_LEVEL_CONNECT ) +#define DCERPC_AUTH_TRAILER_LENGTH ( 8 ) +#define DCERPC_PFC_FLAG_FIRST ( 0x01 ) +#define DCERPC_PFC_FLAG_LAST ( 0x02 ) +#define DCERPC_PFC_FLAG_PENDING_CANCEL ( 0x04 ) +#define DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN ( DCERPC_PFC_FLAG_PENDING_CANCEL ) +#define DCERPC_PFC_FLAG_CONC_MPX ( 0x10 ) +#define DCERPC_PFC_FLAG_DID_NOT_EXECUTE ( 0x20 ) +#define DCERPC_PFC_FLAG_MAYBE ( 0x40 ) +#define DCERPC_PFC_FLAG_OBJECT_UUID ( 0x80 ) +#define DCERPC_PFC_OFFSET ( 3 ) +#define DCERPC_DREP_OFFSET ( 4 ) +#define DCERPC_FRAG_LEN_OFFSET ( 8 ) +#define DCERPC_AUTH_LEN_OFFSET ( 10 ) +#define DCERPC_DREP_LE ( 0x10 ) +struct dcerpc_ctx_list { + uint16_t context_id; + uint8_t num_transfer_syntaxes; + struct ndr_syntax_id abstract_syntax; + struct ndr_syntax_id *transfer_syntaxes; +}; + +struct dcerpc_bind { + uint16_t max_xmit_frag; + uint16_t max_recv_frag; + uint32_t assoc_group_id; + uint8_t num_contexts; + struct dcerpc_ctx_list *ctx_list; + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN4)] */ + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_empty { + char _empty_; +}; + +union dcerpc_object { + struct dcerpc_empty empty;/* [default] */ + struct GUID object;/* [case(LIBNDR_FLAG_OBJECT_PRESENT)] */ +}/* [nodiscriminant] */; + +struct dcerpc_request { + uint32_t alloc_hint; + uint16_t context_id; + uint16_t opnum; + union dcerpc_object object;/* [switch_is(ndr->flags&LIBNDR_FLAG_OBJECT_PRESENT)] */ + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN8)] */ + DATA_BLOB stub_and_verifier;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_ack_ctx { + uint16_t result; + uint16_t reason; + struct ndr_syntax_id syntax; +}; + +struct dcerpc_bind_ack { + uint16_t max_xmit_frag; + uint16_t max_recv_frag; + uint32_t assoc_group_id; + uint16_t secondary_address_size;/* [value(strlen(secondary_address)+1)] */ + const char *secondary_address;/* [charset(DOS)] */ + DATA_BLOB _pad1;/* [flag(LIBNDR_FLAG_ALIGN4)] */ + uint8_t num_results; + struct dcerpc_ack_ctx *ctx_list; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_bind_nak_versions { + uint32_t num_versions; + uint32_t *versions; +}; + +union dcerpc_bind_nak_versions_ctr { + struct dcerpc_bind_nak_versions v;/* [case(DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED)] */ +}/* [nodiscriminant] */; + +struct dcerpc_bind_nak { + uint16_t reject_reason; + union dcerpc_bind_nak_versions_ctr versions;/* [switch_is(reject_reason)] */ +}; + +struct dcerpc_response { + uint32_t alloc_hint; + uint16_t context_id; + uint8_t cancel_count; + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN8)] */ + DATA_BLOB stub_and_verifier;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_fault { + uint32_t alloc_hint; + uint16_t context_id; + uint8_t cancel_count; + uint32_t status; + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +enum dcerpc_AuthType +#ifndef USE_UINT_ENUMS + { + DCERPC_AUTH_TYPE_NONE=0, + DCERPC_AUTH_TYPE_KRB5_1=1, + DCERPC_AUTH_TYPE_SPNEGO=9, + DCERPC_AUTH_TYPE_NTLMSSP=10, + DCERPC_AUTH_TYPE_KRB5=16, + DCERPC_AUTH_TYPE_DPA=17, + DCERPC_AUTH_TYPE_MSN=18, + DCERPC_AUTH_TYPE_DIGEST=21, + DCERPC_AUTH_TYPE_SCHANNEL=68, + DCERPC_AUTH_TYPE_MSMQ=100 +} +#else + { __donnot_use_enum_dcerpc_AuthType=0x7FFFFFFF} +#define DCERPC_AUTH_TYPE_NONE ( 0 ) +#define DCERPC_AUTH_TYPE_KRB5_1 ( 1 ) +#define DCERPC_AUTH_TYPE_SPNEGO ( 9 ) +#define DCERPC_AUTH_TYPE_NTLMSSP ( 10 ) +#define DCERPC_AUTH_TYPE_KRB5 ( 16 ) +#define DCERPC_AUTH_TYPE_DPA ( 17 ) +#define DCERPC_AUTH_TYPE_MSN ( 18 ) +#define DCERPC_AUTH_TYPE_DIGEST ( 21 ) +#define DCERPC_AUTH_TYPE_SCHANNEL ( 68 ) +#define DCERPC_AUTH_TYPE_MSMQ ( 100 ) +#endif +; + +enum dcerpc_AuthLevel +#ifndef USE_UINT_ENUMS + { + DCERPC_AUTH_LEVEL_NONE=1, + DCERPC_AUTH_LEVEL_CONNECT=2, + DCERPC_AUTH_LEVEL_CALL=3, + DCERPC_AUTH_LEVEL_PACKET=4, + DCERPC_AUTH_LEVEL_INTEGRITY=5, + DCERPC_AUTH_LEVEL_PRIVACY=6 +} +#else + { __donnot_use_enum_dcerpc_AuthLevel=0x7FFFFFFF} +#define DCERPC_AUTH_LEVEL_NONE ( 1 ) +#define DCERPC_AUTH_LEVEL_CONNECT ( 2 ) +#define DCERPC_AUTH_LEVEL_CALL ( 3 ) +#define DCERPC_AUTH_LEVEL_PACKET ( 4 ) +#define DCERPC_AUTH_LEVEL_INTEGRITY ( 5 ) +#define DCERPC_AUTH_LEVEL_PRIVACY ( 6 ) +#endif +; + +struct dcerpc_auth { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint8_t auth_pad_length; + uint8_t auth_reserved; + uint32_t auth_context_id; + DATA_BLOB credentials;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_auth3 { + uint32_t _pad; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_orphaned { + uint32_t _pad; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_co_cancel { + uint32_t _pad; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_cl_cancel { + uint32_t version; + uint32_t id; +}/* [public] */; + +struct dcerpc_cancel_ack { + uint32_t version; + uint32_t id; + uint32_t server_is_accepting; +}/* [public] */; + +struct dcerpc_fack { + uint32_t version; + uint8_t _pad1; + uint16_t window_size; + uint32_t max_tdsu; + uint32_t max_frag_size; + uint16_t serial_no; + uint16_t selack_size; + uint32_t *selack; +}/* [public] */; + +struct dcerpc_ack { + char _empty_; +}/* [public] */; + +struct dcerpc_ping { + char _empty_; +}/* [public] */; + +struct dcerpc_shutdown { + char _empty_; +}/* [public] */; + +struct dcerpc_working { + char _empty_; +}/* [public] */; + +enum dcerpc_pkt_type +#ifndef USE_UINT_ENUMS + { + DCERPC_PKT_REQUEST=0, + DCERPC_PKT_PING=1, + DCERPC_PKT_RESPONSE=2, + DCERPC_PKT_FAULT=3, + DCERPC_PKT_WORKING=4, + DCERPC_PKT_NOCALL=5, + DCERPC_PKT_REJECT=6, + DCERPC_PKT_ACK=7, + DCERPC_PKT_CL_CANCEL=8, + DCERPC_PKT_FACK=9, + DCERPC_PKT_CANCEL_ACK=10, + DCERPC_PKT_BIND=11, + DCERPC_PKT_BIND_ACK=12, + DCERPC_PKT_BIND_NAK=13, + DCERPC_PKT_ALTER=14, + DCERPC_PKT_ALTER_RESP=15, + DCERPC_PKT_AUTH3=16, + DCERPC_PKT_SHUTDOWN=17, + DCERPC_PKT_CO_CANCEL=18, + DCERPC_PKT_ORPHANED=19 +} +#else + { __donnot_use_enum_dcerpc_pkt_type=0x7FFFFFFF} +#define DCERPC_PKT_REQUEST ( 0 ) +#define DCERPC_PKT_PING ( 1 ) +#define DCERPC_PKT_RESPONSE ( 2 ) +#define DCERPC_PKT_FAULT ( 3 ) +#define DCERPC_PKT_WORKING ( 4 ) +#define DCERPC_PKT_NOCALL ( 5 ) +#define DCERPC_PKT_REJECT ( 6 ) +#define DCERPC_PKT_ACK ( 7 ) +#define DCERPC_PKT_CL_CANCEL ( 8 ) +#define DCERPC_PKT_FACK ( 9 ) +#define DCERPC_PKT_CANCEL_ACK ( 10 ) +#define DCERPC_PKT_BIND ( 11 ) +#define DCERPC_PKT_BIND_ACK ( 12 ) +#define DCERPC_PKT_BIND_NAK ( 13 ) +#define DCERPC_PKT_ALTER ( 14 ) +#define DCERPC_PKT_ALTER_RESP ( 15 ) +#define DCERPC_PKT_AUTH3 ( 16 ) +#define DCERPC_PKT_SHUTDOWN ( 17 ) +#define DCERPC_PKT_CO_CANCEL ( 18 ) +#define DCERPC_PKT_ORPHANED ( 19 ) +#endif +; + +union dcerpc_payload { + struct dcerpc_request request;/* [case(DCERPC_PKT_REQUEST)] */ + struct dcerpc_ping ping;/* [case(DCERPC_PKT_PING)] */ + struct dcerpc_response response;/* [case(DCERPC_PKT_RESPONSE)] */ + struct dcerpc_fault fault;/* [case(DCERPC_PKT_FAULT)] */ + struct dcerpc_working working;/* [case(DCERPC_PKT_WORKING)] */ + struct dcerpc_fack nocall;/* [case(DCERPC_PKT_NOCALL)] */ + struct dcerpc_fault reject;/* [case(DCERPC_PKT_REJECT)] */ + struct dcerpc_ack ack;/* [case(DCERPC_PKT_ACK)] */ + struct dcerpc_cl_cancel cl_cancel;/* [case(DCERPC_PKT_CL_CANCEL)] */ + struct dcerpc_fack fack;/* [case(DCERPC_PKT_FACK)] */ + struct dcerpc_cancel_ack cancel_ack;/* [case(DCERPC_PKT_CANCEL_ACK)] */ + struct dcerpc_bind bind;/* [case(DCERPC_PKT_BIND)] */ + struct dcerpc_bind_ack bind_ack;/* [case(DCERPC_PKT_BIND_ACK)] */ + struct dcerpc_bind_nak bind_nak;/* [case(DCERPC_PKT_BIND_NAK)] */ + struct dcerpc_bind alter;/* [case(DCERPC_PKT_ALTER)] */ + struct dcerpc_bind_ack alter_resp;/* [case(DCERPC_PKT_ALTER_RESP)] */ + struct dcerpc_shutdown shutdown;/* [case(DCERPC_PKT_SHUTDOWN)] */ + struct dcerpc_co_cancel co_cancel;/* [case(DCERPC_PKT_CO_CANCEL)] */ + struct dcerpc_orphaned orphaned;/* [case(DCERPC_PKT_ORPHANED)] */ + struct dcerpc_auth3 auth3;/* [case(DCERPC_PKT_AUTH3)] */ +}/* [nodiscriminant] */; + +struct ncacn_packet { + uint8_t rpc_vers; + uint8_t rpc_vers_minor; + enum dcerpc_pkt_type ptype; + uint8_t pfc_flags; + uint8_t drep[4]; + uint16_t frag_length; + uint16_t auth_length; + uint32_t call_id; + union dcerpc_payload u;/* [switch_is(ptype)] */ +}/* [public] */; + +struct ncadg_packet { + uint8_t rpc_vers; + uint8_t ptype; + uint8_t pfc_flags; + uint8_t ncadg_flags; + uint8_t drep[3]; + uint8_t serial_high; + struct GUID object; + struct GUID iface; + struct GUID activity; + uint32_t server_boot; + uint32_t iface_version; + uint32_t seq_num; + uint16_t opnum; + uint16_t ihint; + uint16_t ahint; + uint16_t len; + uint16_t fragnum; + uint8_t auth_proto; + uint8_t serial_low; + union dcerpc_payload u;/* [switch_is(ptype)] */ +}/* [public] */; + +#endif /* _HEADER_dcerpc */ diff --git a/librpc/gen_ndr/ndr_dcerpc.c b/librpc/gen_ndr/ndr_dcerpc.c new file mode 100644 index 0000000000..c510967c7a --- /dev/null +++ b/librpc/gen_ndr/ndr_dcerpc.c @@ -0,0 +1,1834 @@ +/* parser auto-generated by pidl */ + +#include "includes.h" +#include "../librpc/gen_ndr/ndr_dcerpc.h" + +#include "librpc/gen_ndr/ndr_misc.h" +static enum ndr_err_code ndr_push_dcerpc_ctx_list(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ctx_list *r) +{ + uint32_t cntr_transfer_syntaxes_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->num_transfer_syntaxes)); + NDR_CHECK(ndr_push_ndr_syntax_id(ndr, NDR_SCALARS, &r->abstract_syntax)); + for (cntr_transfer_syntaxes_0 = 0; cntr_transfer_syntaxes_0 < r->num_transfer_syntaxes; cntr_transfer_syntaxes_0++) { + NDR_CHECK(ndr_push_ndr_syntax_id(ndr, NDR_SCALARS, &r->transfer_syntaxes[cntr_transfer_syntaxes_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_ctx_list(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ctx_list *r) +{ + uint32_t cntr_transfer_syntaxes_0; + TALLOC_CTX *_mem_save_transfer_syntaxes_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_transfer_syntaxes)); + NDR_CHECK(ndr_pull_ndr_syntax_id(ndr, NDR_SCALARS, &r->abstract_syntax)); + NDR_PULL_ALLOC_N(ndr, r->transfer_syntaxes, r->num_transfer_syntaxes); + _mem_save_transfer_syntaxes_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->transfer_syntaxes, 0); + for (cntr_transfer_syntaxes_0 = 0; cntr_transfer_syntaxes_0 < r->num_transfer_syntaxes; cntr_transfer_syntaxes_0++) { + NDR_CHECK(ndr_pull_ndr_syntax_id(ndr, NDR_SCALARS, &r->transfer_syntaxes[cntr_transfer_syntaxes_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_transfer_syntaxes_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ctx_list(struct ndr_print *ndr, const char *name, const struct dcerpc_ctx_list *r) +{ + uint32_t cntr_transfer_syntaxes_0; + ndr_print_struct(ndr, name, "dcerpc_ctx_list"); + ndr->depth++; + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint8(ndr, "num_transfer_syntaxes", r->num_transfer_syntaxes); + ndr_print_ndr_syntax_id(ndr, "abstract_syntax", &r->abstract_syntax); + ndr->print(ndr, "%s: ARRAY(%d)", "transfer_syntaxes", (int)r->num_transfer_syntaxes); + ndr->depth++; + for (cntr_transfer_syntaxes_0=0;cntr_transfer_syntaxes_0num_transfer_syntaxes;cntr_transfer_syntaxes_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_transfer_syntaxes_0) != -1) { + ndr_print_ndr_syntax_id(ndr, "transfer_syntaxes", &r->transfer_syntaxes[cntr_transfer_syntaxes_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind *r) +{ + uint32_t cntr_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_xmit_frag)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_recv_frag)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->assoc_group_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->num_contexts)); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_contexts; cntr_ctx_list_0++) { + NDR_CHECK(ndr_push_dcerpc_ctx_list(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind *r) +{ + uint32_t cntr_ctx_list_0; + TALLOC_CTX *_mem_save_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_xmit_frag)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_recv_frag)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->assoc_group_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_contexts)); + NDR_PULL_ALLOC_N(ndr, r->ctx_list, r->num_contexts); + _mem_save_ctx_list_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->ctx_list, 0); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_contexts; cntr_ctx_list_0++) { + NDR_CHECK(ndr_pull_dcerpc_ctx_list(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ctx_list_0, 0); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind(struct ndr_print *ndr, const char *name, const struct dcerpc_bind *r) +{ + uint32_t cntr_ctx_list_0; + ndr_print_struct(ndr, name, "dcerpc_bind"); + ndr->depth++; + ndr_print_uint16(ndr, "max_xmit_frag", r->max_xmit_frag); + ndr_print_uint16(ndr, "max_recv_frag", r->max_recv_frag); + ndr_print_uint32(ndr, "assoc_group_id", r->assoc_group_id); + ndr_print_uint8(ndr, "num_contexts", r->num_contexts); + ndr->print(ndr, "%s: ARRAY(%d)", "ctx_list", (int)r->num_contexts); + ndr->depth++; + for (cntr_ctx_list_0=0;cntr_ctx_list_0num_contexts;cntr_ctx_list_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_ctx_list_0) != -1) { + ndr_print_dcerpc_ctx_list(ndr, "ctx_list", &r->ctx_list[cntr_ctx_list_0]); + free(idx_0); + } + } + ndr->depth--; + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_empty(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_empty *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_empty(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_empty *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_empty(struct ndr_print *ndr, const char *name, const struct dcerpc_empty *r) +{ + ndr_print_struct(ndr, name, "dcerpc_empty"); + ndr->depth++; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_object(struct ndr_push *ndr, int ndr_flags, const union dcerpc_object *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + default: { + NDR_CHECK(ndr_push_dcerpc_empty(ndr, NDR_SCALARS, &r->empty)); + break; } + + case LIBNDR_FLAG_OBJECT_PRESENT: { + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->object)); + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + default: + break; + + case LIBNDR_FLAG_OBJECT_PRESENT: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_object(struct ndr_pull *ndr, int ndr_flags, union dcerpc_object *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + default: { + NDR_CHECK(ndr_pull_dcerpc_empty(ndr, NDR_SCALARS, &r->empty)); + break; } + + case LIBNDR_FLAG_OBJECT_PRESENT: { + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->object)); + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + default: + break; + + case LIBNDR_FLAG_OBJECT_PRESENT: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_object(struct ndr_print *ndr, const char *name, const union dcerpc_object *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "dcerpc_object"); + switch (level) { + default: + ndr_print_dcerpc_empty(ndr, "empty", &r->empty); + break; + + case LIBNDR_FLAG_OBJECT_PRESENT: + ndr_print_GUID(ndr, "object", &r->object); + break; + + } +} + +static enum ndr_err_code ndr_push_dcerpc_request(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_request *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->alloc_hint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->opnum)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)); + NDR_CHECK(ndr_push_dcerpc_object(ndr, NDR_SCALARS, &r->object)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_request(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_request *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->alloc_hint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->opnum)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)); + NDR_CHECK(ndr_pull_dcerpc_object(ndr, NDR_SCALARS, &r->object)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_request(struct ndr_print *ndr, const char *name, const struct dcerpc_request *r) +{ + ndr_print_struct(ndr, name, "dcerpc_request"); + ndr->depth++; + ndr_print_uint32(ndr, "alloc_hint", r->alloc_hint); + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint16(ndr, "opnum", r->opnum); + ndr_print_set_switch_value(ndr, &r->object, ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT); + ndr_print_dcerpc_object(ndr, "object", &r->object); + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "stub_and_verifier", r->stub_and_verifier); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_ack_ctx(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ack_ctx *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->result)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->reason)); + NDR_CHECK(ndr_push_ndr_syntax_id(ndr, NDR_SCALARS, &r->syntax)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_ack_ctx(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ack_ctx *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->result)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->reason)); + NDR_CHECK(ndr_pull_ndr_syntax_id(ndr, NDR_SCALARS, &r->syntax)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ack_ctx(struct ndr_print *ndr, const char *name, const struct dcerpc_ack_ctx *r) +{ + ndr_print_struct(ndr, name, "dcerpc_ack_ctx"); + ndr->depth++; + ndr_print_uint16(ndr, "result", r->result); + ndr_print_uint16(ndr, "reason", r->reason); + ndr_print_ndr_syntax_id(ndr, "syntax", &r->syntax); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind_ack *r) +{ + uint32_t cntr_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_xmit_frag)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_recv_frag)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->assoc_group_id)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen(r->secondary_address) + 1)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->secondary_address, strlen(r->secondary_address) + 1, sizeof(uint8_t), CH_DOS)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad1)); + ndr->flags = _flags_save_DATA_BLOB; + } + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->num_results)); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_results; cntr_ctx_list_0++) { + NDR_CHECK(ndr_push_dcerpc_ack_ctx(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind_ack *r) +{ + uint32_t cntr_ctx_list_0; + TALLOC_CTX *_mem_save_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_xmit_frag)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_recv_frag)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->assoc_group_id)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->secondary_address_size)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->secondary_address, r->secondary_address_size, sizeof(uint8_t), CH_DOS)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad1)); + ndr->flags = _flags_save_DATA_BLOB; + } + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_results)); + NDR_PULL_ALLOC_N(ndr, r->ctx_list, r->num_results); + _mem_save_ctx_list_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->ctx_list, 0); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_results; cntr_ctx_list_0++) { + NDR_CHECK(ndr_pull_dcerpc_ack_ctx(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ctx_list_0, 0); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_ack *r) +{ + uint32_t cntr_ctx_list_0; + ndr_print_struct(ndr, name, "dcerpc_bind_ack"); + ndr->depth++; + ndr_print_uint16(ndr, "max_xmit_frag", r->max_xmit_frag); + ndr_print_uint16(ndr, "max_recv_frag", r->max_recv_frag); + ndr_print_uint32(ndr, "assoc_group_id", r->assoc_group_id); + ndr_print_uint16(ndr, "secondary_address_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen(r->secondary_address) + 1:r->secondary_address_size); + ndr_print_string(ndr, "secondary_address", r->secondary_address); + ndr_print_DATA_BLOB(ndr, "_pad1", r->_pad1); + ndr_print_uint8(ndr, "num_results", r->num_results); + ndr->print(ndr, "%s: ARRAY(%d)", "ctx_list", (int)r->num_results); + ndr->depth++; + for (cntr_ctx_list_0=0;cntr_ctx_list_0num_results;cntr_ctx_list_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_ctx_list_0) != -1) { + ndr_print_dcerpc_ack_ctx(ndr, "ctx_list", &r->ctx_list[cntr_ctx_list_0]); + free(idx_0); + } + } + ndr->depth--; + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind_nak_versions(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind_nak_versions *r) +{ + uint32_t cntr_versions_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_versions)); + for (cntr_versions_0 = 0; cntr_versions_0 < r->num_versions; cntr_versions_0++) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->versions[cntr_versions_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_nak_versions(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind_nak_versions *r) +{ + uint32_t cntr_versions_0; + TALLOC_CTX *_mem_save_versions_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_versions)); + NDR_PULL_ALLOC_N(ndr, r->versions, r->num_versions); + _mem_save_versions_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->versions, 0); + for (cntr_versions_0 = 0; cntr_versions_0 < r->num_versions; cntr_versions_0++) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->versions[cntr_versions_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_versions_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_nak_versions(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak_versions *r) +{ + uint32_t cntr_versions_0; + ndr_print_struct(ndr, name, "dcerpc_bind_nak_versions"); + ndr->depth++; + ndr_print_uint32(ndr, "num_versions", r->num_versions); + ndr->print(ndr, "%s: ARRAY(%d)", "versions", (int)r->num_versions); + ndr->depth++; + for (cntr_versions_0=0;cntr_versions_0num_versions;cntr_versions_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_versions_0) != -1) { + ndr_print_uint32(ndr, "versions", r->versions[cntr_versions_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind_nak_versions_ctr(struct ndr_push *ndr, int ndr_flags, const union dcerpc_bind_nak_versions_ctr *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: { + NDR_CHECK(ndr_push_dcerpc_bind_nak_versions(ndr, NDR_SCALARS, &r->v)); + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_nak_versions_ctr(struct ndr_pull *ndr, int ndr_flags, union dcerpc_bind_nak_versions_ctr *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: { + NDR_CHECK(ndr_pull_dcerpc_bind_nak_versions(ndr, NDR_SCALARS, &r->v)); + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_nak_versions_ctr(struct ndr_print *ndr, const char *name, const union dcerpc_bind_nak_versions_ctr *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "dcerpc_bind_nak_versions_ctr"); + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: + ndr_print_dcerpc_bind_nak_versions(ndr, "v", &r->v); + break; + + default: + break; + + } +} + +static enum ndr_err_code ndr_push_dcerpc_bind_nak(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind_nak *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->reject_reason)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->versions, r->reject_reason)); + NDR_CHECK(ndr_push_dcerpc_bind_nak_versions_ctr(ndr, NDR_SCALARS, &r->versions)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_dcerpc_bind_nak_versions_ctr(ndr, NDR_BUFFERS, &r->versions)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_nak(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind_nak *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->reject_reason)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->versions, r->reject_reason)); + NDR_CHECK(ndr_pull_dcerpc_bind_nak_versions_ctr(ndr, NDR_SCALARS, &r->versions)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_dcerpc_bind_nak_versions_ctr(ndr, NDR_BUFFERS, &r->versions)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_nak(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak *r) +{ + ndr_print_struct(ndr, name, "dcerpc_bind_nak"); + ndr->depth++; + ndr_print_uint16(ndr, "reject_reason", r->reject_reason); + ndr_print_set_switch_value(ndr, &r->versions, r->reject_reason); + ndr_print_dcerpc_bind_nak_versions_ctr(ndr, "versions", &r->versions); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_response(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_response *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->alloc_hint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->cancel_count)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_response(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_response *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->alloc_hint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->cancel_count)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_response(struct ndr_print *ndr, const char *name, const struct dcerpc_response *r) +{ + ndr_print_struct(ndr, name, "dcerpc_response"); + ndr->depth++; + ndr_print_uint32(ndr, "alloc_hint", r->alloc_hint); + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint8(ndr, "cancel_count", r->cancel_count); + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "stub_and_verifier", r->stub_and_verifier); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_fault(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_fault *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->alloc_hint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->cancel_count)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->status)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_fault(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_fault *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->alloc_hint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->cancel_count)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->status)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_fault(struct ndr_print *ndr, const char *name, const struct dcerpc_fault *r) +{ + ndr_print_struct(ndr, name, "dcerpc_fault"); + ndr->depth++; + ndr_print_uint32(ndr, "alloc_hint", r->alloc_hint); + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint8(ndr, "cancel_count", r->cancel_count); + ndr_print_uint32(ndr, "status", r->status); + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_AuthType(struct ndr_push *ndr, int ndr_flags, enum dcerpc_AuthType r) +{ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_AuthType(struct ndr_pull *ndr, int ndr_flags, enum dcerpc_AuthType *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_AuthType(struct ndr_print *ndr, const char *name, enum dcerpc_AuthType r) +{ + const char *val = NULL; + + switch (r) { + case DCERPC_AUTH_TYPE_NONE: val = "DCERPC_AUTH_TYPE_NONE"; break; + case DCERPC_AUTH_TYPE_KRB5_1: val = "DCERPC_AUTH_TYPE_KRB5_1"; break; + case DCERPC_AUTH_TYPE_SPNEGO: val = "DCERPC_AUTH_TYPE_SPNEGO"; break; + case DCERPC_AUTH_TYPE_NTLMSSP: val = "DCERPC_AUTH_TYPE_NTLMSSP"; break; + case DCERPC_AUTH_TYPE_KRB5: val = "DCERPC_AUTH_TYPE_KRB5"; break; + case DCERPC_AUTH_TYPE_DPA: val = "DCERPC_AUTH_TYPE_DPA"; break; + case DCERPC_AUTH_TYPE_MSN: val = "DCERPC_AUTH_TYPE_MSN"; break; + case DCERPC_AUTH_TYPE_DIGEST: val = "DCERPC_AUTH_TYPE_DIGEST"; break; + case DCERPC_AUTH_TYPE_SCHANNEL: val = "DCERPC_AUTH_TYPE_SCHANNEL"; break; + case DCERPC_AUTH_TYPE_MSMQ: val = "DCERPC_AUTH_TYPE_MSMQ"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +static enum ndr_err_code ndr_push_dcerpc_AuthLevel(struct ndr_push *ndr, int ndr_flags, enum dcerpc_AuthLevel r) +{ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_AuthLevel(struct ndr_pull *ndr, int ndr_flags, enum dcerpc_AuthLevel *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_AuthLevel(struct ndr_print *ndr, const char *name, enum dcerpc_AuthLevel r) +{ + const char *val = NULL; + + switch (r) { + case DCERPC_AUTH_LEVEL_NONE: val = "DCERPC_AUTH_LEVEL_NONE"; break; + case DCERPC_AUTH_LEVEL_CONNECT: val = "DCERPC_AUTH_LEVEL_CONNECT"; break; + case DCERPC_AUTH_LEVEL_CALL: val = "DCERPC_AUTH_LEVEL_CALL"; break; + case DCERPC_AUTH_LEVEL_PACKET: val = "DCERPC_AUTH_LEVEL_PACKET"; break; + case DCERPC_AUTH_LEVEL_INTEGRITY: val = "DCERPC_AUTH_LEVEL_INTEGRITY"; break; + case DCERPC_AUTH_LEVEL_PRIVACY: val = "DCERPC_AUTH_LEVEL_PRIVACY"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_auth(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_dcerpc_AuthType(ndr, NDR_SCALARS, r->auth_type)); + NDR_CHECK(ndr_push_dcerpc_AuthLevel(ndr, NDR_SCALARS, r->auth_level)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->auth_pad_length)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->auth_reserved)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->auth_context_id)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->credentials)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_auth(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_dcerpc_AuthType(ndr, NDR_SCALARS, &r->auth_type)); + NDR_CHECK(ndr_pull_dcerpc_AuthLevel(ndr, NDR_SCALARS, &r->auth_level)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->auth_pad_length)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->auth_reserved)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->auth_context_id)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->credentials)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_auth(struct ndr_print *ndr, const char *name, const struct dcerpc_auth *r) +{ + ndr_print_struct(ndr, name, "dcerpc_auth"); + ndr->depth++; + ndr_print_dcerpc_AuthType(ndr, "auth_type", r->auth_type); + ndr_print_dcerpc_AuthLevel(ndr, "auth_level", r->auth_level); + ndr_print_uint8(ndr, "auth_pad_length", r->auth_pad_length); + ndr_print_uint8(ndr, "auth_reserved", r->auth_reserved); + ndr_print_uint32(ndr, "auth_context_id", r->auth_context_id); + ndr_print_DATA_BLOB(ndr, "credentials", r->credentials); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_auth3(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_auth3(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_auth3(struct ndr_print *ndr, const char *name, const struct dcerpc_auth3 *r) +{ + ndr_print_struct(ndr, name, "dcerpc_auth3"); + ndr->depth++; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_orphaned(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_orphaned *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_orphaned(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_orphaned *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_orphaned(struct ndr_print *ndr, const char *name, const struct dcerpc_orphaned *r) +{ + ndr_print_struct(ndr, name, "dcerpc_orphaned"); + ndr->depth++; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_co_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_co_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_co_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_co_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_co_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_co_cancel *r) +{ + ndr_print_struct(ndr, name, "dcerpc_co_cancel"); + ndr->depth++; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_cl_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cl_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->id)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_cl_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cl_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->id)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_cl_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_cl_cancel *r) +{ + ndr_print_struct(ndr, name, "dcerpc_cl_cancel"); + ndr->depth++; + ndr_print_uint32(ndr, "version", r->version); + ndr_print_uint32(ndr, "id", r->id); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_cancel_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cancel_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->id)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->server_is_accepting)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_cancel_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cancel_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->id)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->server_is_accepting)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_cancel_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_cancel_ack *r) +{ + ndr_print_struct(ndr, name, "dcerpc_cancel_ack"); + ndr->depth++; + ndr_print_uint32(ndr, "version", r->version); + ndr_print_uint32(ndr, "id", r->id); + ndr_print_uint32(ndr, "server_is_accepting", r->server_is_accepting); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_fack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_fack *r) +{ + uint32_t cntr_selack_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->_pad1)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->window_size)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->max_tdsu)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->max_frag_size)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->serial_no)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->selack_size)); + for (cntr_selack_0 = 0; cntr_selack_0 < r->selack_size; cntr_selack_0++) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->selack[cntr_selack_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_fack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_fack *r) +{ + uint32_t cntr_selack_0; + TALLOC_CTX *_mem_save_selack_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->_pad1)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->window_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->max_tdsu)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->max_frag_size)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->serial_no)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->selack_size)); + NDR_PULL_ALLOC_N(ndr, r->selack, r->selack_size); + _mem_save_selack_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->selack, 0); + for (cntr_selack_0 = 0; cntr_selack_0 < r->selack_size; cntr_selack_0++) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->selack[cntr_selack_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_selack_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_fack(struct ndr_print *ndr, const char *name, const struct dcerpc_fack *r) +{ + uint32_t cntr_selack_0; + ndr_print_struct(ndr, name, "dcerpc_fack"); + ndr->depth++; + ndr_print_uint32(ndr, "version", r->version); + ndr_print_uint8(ndr, "_pad1", r->_pad1); + ndr_print_uint16(ndr, "window_size", r->window_size); + ndr_print_uint32(ndr, "max_tdsu", r->max_tdsu); + ndr_print_uint32(ndr, "max_frag_size", r->max_frag_size); + ndr_print_uint16(ndr, "serial_no", r->serial_no); + ndr_print_uint16(ndr, "selack_size", r->selack_size); + ndr->print(ndr, "%s: ARRAY(%d)", "selack", (int)r->selack_size); + ndr->depth++; + for (cntr_selack_0=0;cntr_selack_0selack_size;cntr_selack_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_selack_0) != -1) { + ndr_print_uint32(ndr, "selack", r->selack[cntr_selack_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_ack *r) +{ + ndr_print_struct(ndr, name, "dcerpc_ack"); + ndr->depth++; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_ping(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ping *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_ping(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ping *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ping(struct ndr_print *ndr, const char *name, const struct dcerpc_ping *r) +{ + ndr_print_struct(ndr, name, "dcerpc_ping"); + ndr->depth++; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_shutdown(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_shutdown *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_shutdown(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_shutdown *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_shutdown(struct ndr_print *ndr, const char *name, const struct dcerpc_shutdown *r) +{ + ndr_print_struct(ndr, name, "dcerpc_shutdown"); + ndr->depth++; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_working(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_working *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_working(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_working *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_working(struct ndr_print *ndr, const char *name, const struct dcerpc_working *r) +{ + ndr_print_struct(ndr, name, "dcerpc_working"); + ndr->depth++; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_pkt_type(struct ndr_push *ndr, int ndr_flags, enum dcerpc_pkt_type r) +{ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_pkt_type(struct ndr_pull *ndr, int ndr_flags, enum dcerpc_pkt_type *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_pkt_type(struct ndr_print *ndr, const char *name, enum dcerpc_pkt_type r) +{ + const char *val = NULL; + + switch (r) { + case DCERPC_PKT_REQUEST: val = "DCERPC_PKT_REQUEST"; break; + case DCERPC_PKT_PING: val = "DCERPC_PKT_PING"; break; + case DCERPC_PKT_RESPONSE: val = "DCERPC_PKT_RESPONSE"; break; + case DCERPC_PKT_FAULT: val = "DCERPC_PKT_FAULT"; break; + case DCERPC_PKT_WORKING: val = "DCERPC_PKT_WORKING"; break; + case DCERPC_PKT_NOCALL: val = "DCERPC_PKT_NOCALL"; break; + case DCERPC_PKT_REJECT: val = "DCERPC_PKT_REJECT"; break; + case DCERPC_PKT_ACK: val = "DCERPC_PKT_ACK"; break; + case DCERPC_PKT_CL_CANCEL: val = "DCERPC_PKT_CL_CANCEL"; break; + case DCERPC_PKT_FACK: val = "DCERPC_PKT_FACK"; break; + case DCERPC_PKT_CANCEL_ACK: val = "DCERPC_PKT_CANCEL_ACK"; break; + case DCERPC_PKT_BIND: val = "DCERPC_PKT_BIND"; break; + case DCERPC_PKT_BIND_ACK: val = "DCERPC_PKT_BIND_ACK"; break; + case DCERPC_PKT_BIND_NAK: val = "DCERPC_PKT_BIND_NAK"; break; + case DCERPC_PKT_ALTER: val = "DCERPC_PKT_ALTER"; break; + case DCERPC_PKT_ALTER_RESP: val = "DCERPC_PKT_ALTER_RESP"; break; + case DCERPC_PKT_AUTH3: val = "DCERPC_PKT_AUTH3"; break; + case DCERPC_PKT_SHUTDOWN: val = "DCERPC_PKT_SHUTDOWN"; break; + case DCERPC_PKT_CO_CANCEL: val = "DCERPC_PKT_CO_CANCEL"; break; + case DCERPC_PKT_ORPHANED: val = "DCERPC_PKT_ORPHANED"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +static enum ndr_err_code ndr_push_dcerpc_payload(struct ndr_push *ndr, int ndr_flags, const union dcerpc_payload *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DCERPC_PKT_REQUEST: { + NDR_CHECK(ndr_push_dcerpc_request(ndr, NDR_SCALARS, &r->request)); + break; } + + case DCERPC_PKT_PING: { + NDR_CHECK(ndr_push_dcerpc_ping(ndr, NDR_SCALARS, &r->ping)); + break; } + + case DCERPC_PKT_RESPONSE: { + NDR_CHECK(ndr_push_dcerpc_response(ndr, NDR_SCALARS, &r->response)); + break; } + + case DCERPC_PKT_FAULT: { + NDR_CHECK(ndr_push_dcerpc_fault(ndr, NDR_SCALARS, &r->fault)); + break; } + + case DCERPC_PKT_WORKING: { + NDR_CHECK(ndr_push_dcerpc_working(ndr, NDR_SCALARS, &r->working)); + break; } + + case DCERPC_PKT_NOCALL: { + NDR_CHECK(ndr_push_dcerpc_fack(ndr, NDR_SCALARS, &r->nocall)); + break; } + + case DCERPC_PKT_REJECT: { + NDR_CHECK(ndr_push_dcerpc_fault(ndr, NDR_SCALARS, &r->reject)); + break; } + + case DCERPC_PKT_ACK: { + NDR_CHECK(ndr_push_dcerpc_ack(ndr, NDR_SCALARS, &r->ack)); + break; } + + case DCERPC_PKT_CL_CANCEL: { + NDR_CHECK(ndr_push_dcerpc_cl_cancel(ndr, NDR_SCALARS, &r->cl_cancel)); + break; } + + case DCERPC_PKT_FACK: { + NDR_CHECK(ndr_push_dcerpc_fack(ndr, NDR_SCALARS, &r->fack)); + break; } + + case DCERPC_PKT_CANCEL_ACK: { + NDR_CHECK(ndr_push_dcerpc_cancel_ack(ndr, NDR_SCALARS, &r->cancel_ack)); + break; } + + case DCERPC_PKT_BIND: { + NDR_CHECK(ndr_push_dcerpc_bind(ndr, NDR_SCALARS, &r->bind)); + break; } + + case DCERPC_PKT_BIND_ACK: { + NDR_CHECK(ndr_push_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->bind_ack)); + break; } + + case DCERPC_PKT_BIND_NAK: { + NDR_CHECK(ndr_push_dcerpc_bind_nak(ndr, NDR_SCALARS, &r->bind_nak)); + break; } + + case DCERPC_PKT_ALTER: { + NDR_CHECK(ndr_push_dcerpc_bind(ndr, NDR_SCALARS, &r->alter)); + break; } + + case DCERPC_PKT_ALTER_RESP: { + NDR_CHECK(ndr_push_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->alter_resp)); + break; } + + case DCERPC_PKT_SHUTDOWN: { + NDR_CHECK(ndr_push_dcerpc_shutdown(ndr, NDR_SCALARS, &r->shutdown)); + break; } + + case DCERPC_PKT_CO_CANCEL: { + NDR_CHECK(ndr_push_dcerpc_co_cancel(ndr, NDR_SCALARS, &r->co_cancel)); + break; } + + case DCERPC_PKT_ORPHANED: { + NDR_CHECK(ndr_push_dcerpc_orphaned(ndr, NDR_SCALARS, &r->orphaned)); + break; } + + case DCERPC_PKT_AUTH3: { + NDR_CHECK(ndr_push_dcerpc_auth3(ndr, NDR_SCALARS, &r->auth3)); + break; } + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DCERPC_PKT_REQUEST: + break; + + case DCERPC_PKT_PING: + break; + + case DCERPC_PKT_RESPONSE: + break; + + case DCERPC_PKT_FAULT: + break; + + case DCERPC_PKT_WORKING: + break; + + case DCERPC_PKT_NOCALL: + break; + + case DCERPC_PKT_REJECT: + break; + + case DCERPC_PKT_ACK: + break; + + case DCERPC_PKT_CL_CANCEL: + break; + + case DCERPC_PKT_FACK: + break; + + case DCERPC_PKT_CANCEL_ACK: + break; + + case DCERPC_PKT_BIND: + break; + + case DCERPC_PKT_BIND_ACK: + break; + + case DCERPC_PKT_BIND_NAK: + NDR_CHECK(ndr_push_dcerpc_bind_nak(ndr, NDR_BUFFERS, &r->bind_nak)); + break; + + case DCERPC_PKT_ALTER: + break; + + case DCERPC_PKT_ALTER_RESP: + break; + + case DCERPC_PKT_SHUTDOWN: + break; + + case DCERPC_PKT_CO_CANCEL: + break; + + case DCERPC_PKT_ORPHANED: + break; + + case DCERPC_PKT_AUTH3: + break; + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_payload(struct ndr_pull *ndr, int ndr_flags, union dcerpc_payload *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + case DCERPC_PKT_REQUEST: { + NDR_CHECK(ndr_pull_dcerpc_request(ndr, NDR_SCALARS, &r->request)); + break; } + + case DCERPC_PKT_PING: { + NDR_CHECK(ndr_pull_dcerpc_ping(ndr, NDR_SCALARS, &r->ping)); + break; } + + case DCERPC_PKT_RESPONSE: { + NDR_CHECK(ndr_pull_dcerpc_response(ndr, NDR_SCALARS, &r->response)); + break; } + + case DCERPC_PKT_FAULT: { + NDR_CHECK(ndr_pull_dcerpc_fault(ndr, NDR_SCALARS, &r->fault)); + break; } + + case DCERPC_PKT_WORKING: { + NDR_CHECK(ndr_pull_dcerpc_working(ndr, NDR_SCALARS, &r->working)); + break; } + + case DCERPC_PKT_NOCALL: { + NDR_CHECK(ndr_pull_dcerpc_fack(ndr, NDR_SCALARS, &r->nocall)); + break; } + + case DCERPC_PKT_REJECT: { + NDR_CHECK(ndr_pull_dcerpc_fault(ndr, NDR_SCALARS, &r->reject)); + break; } + + case DCERPC_PKT_ACK: { + NDR_CHECK(ndr_pull_dcerpc_ack(ndr, NDR_SCALARS, &r->ack)); + break; } + + case DCERPC_PKT_CL_CANCEL: { + NDR_CHECK(ndr_pull_dcerpc_cl_cancel(ndr, NDR_SCALARS, &r->cl_cancel)); + break; } + + case DCERPC_PKT_FACK: { + NDR_CHECK(ndr_pull_dcerpc_fack(ndr, NDR_SCALARS, &r->fack)); + break; } + + case DCERPC_PKT_CANCEL_ACK: { + NDR_CHECK(ndr_pull_dcerpc_cancel_ack(ndr, NDR_SCALARS, &r->cancel_ack)); + break; } + + case DCERPC_PKT_BIND: { + NDR_CHECK(ndr_pull_dcerpc_bind(ndr, NDR_SCALARS, &r->bind)); + break; } + + case DCERPC_PKT_BIND_ACK: { + NDR_CHECK(ndr_pull_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->bind_ack)); + break; } + + case DCERPC_PKT_BIND_NAK: { + NDR_CHECK(ndr_pull_dcerpc_bind_nak(ndr, NDR_SCALARS, &r->bind_nak)); + break; } + + case DCERPC_PKT_ALTER: { + NDR_CHECK(ndr_pull_dcerpc_bind(ndr, NDR_SCALARS, &r->alter)); + break; } + + case DCERPC_PKT_ALTER_RESP: { + NDR_CHECK(ndr_pull_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->alter_resp)); + break; } + + case DCERPC_PKT_SHUTDOWN: { + NDR_CHECK(ndr_pull_dcerpc_shutdown(ndr, NDR_SCALARS, &r->shutdown)); + break; } + + case DCERPC_PKT_CO_CANCEL: { + NDR_CHECK(ndr_pull_dcerpc_co_cancel(ndr, NDR_SCALARS, &r->co_cancel)); + break; } + + case DCERPC_PKT_ORPHANED: { + NDR_CHECK(ndr_pull_dcerpc_orphaned(ndr, NDR_SCALARS, &r->orphaned)); + break; } + + case DCERPC_PKT_AUTH3: { + NDR_CHECK(ndr_pull_dcerpc_auth3(ndr, NDR_SCALARS, &r->auth3)); + break; } + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case DCERPC_PKT_REQUEST: + break; + + case DCERPC_PKT_PING: + break; + + case DCERPC_PKT_RESPONSE: + break; + + case DCERPC_PKT_FAULT: + break; + + case DCERPC_PKT_WORKING: + break; + + case DCERPC_PKT_NOCALL: + break; + + case DCERPC_PKT_REJECT: + break; + + case DCERPC_PKT_ACK: + break; + + case DCERPC_PKT_CL_CANCEL: + break; + + case DCERPC_PKT_FACK: + break; + + case DCERPC_PKT_CANCEL_ACK: + break; + + case DCERPC_PKT_BIND: + break; + + case DCERPC_PKT_BIND_ACK: + break; + + case DCERPC_PKT_BIND_NAK: + NDR_CHECK(ndr_pull_dcerpc_bind_nak(ndr, NDR_BUFFERS, &r->bind_nak)); + break; + + case DCERPC_PKT_ALTER: + break; + + case DCERPC_PKT_ALTER_RESP: + break; + + case DCERPC_PKT_SHUTDOWN: + break; + + case DCERPC_PKT_CO_CANCEL: + break; + + case DCERPC_PKT_ORPHANED: + break; + + case DCERPC_PKT_AUTH3: + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_payload(struct ndr_print *ndr, const char *name, const union dcerpc_payload *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "dcerpc_payload"); + switch (level) { + case DCERPC_PKT_REQUEST: + ndr_print_dcerpc_request(ndr, "request", &r->request); + break; + + case DCERPC_PKT_PING: + ndr_print_dcerpc_ping(ndr, "ping", &r->ping); + break; + + case DCERPC_PKT_RESPONSE: + ndr_print_dcerpc_response(ndr, "response", &r->response); + break; + + case DCERPC_PKT_FAULT: + ndr_print_dcerpc_fault(ndr, "fault", &r->fault); + break; + + case DCERPC_PKT_WORKING: + ndr_print_dcerpc_working(ndr, "working", &r->working); + break; + + case DCERPC_PKT_NOCALL: + ndr_print_dcerpc_fack(ndr, "nocall", &r->nocall); + break; + + case DCERPC_PKT_REJECT: + ndr_print_dcerpc_fault(ndr, "reject", &r->reject); + break; + + case DCERPC_PKT_ACK: + ndr_print_dcerpc_ack(ndr, "ack", &r->ack); + break; + + case DCERPC_PKT_CL_CANCEL: + ndr_print_dcerpc_cl_cancel(ndr, "cl_cancel", &r->cl_cancel); + break; + + case DCERPC_PKT_FACK: + ndr_print_dcerpc_fack(ndr, "fack", &r->fack); + break; + + case DCERPC_PKT_CANCEL_ACK: + ndr_print_dcerpc_cancel_ack(ndr, "cancel_ack", &r->cancel_ack); + break; + + case DCERPC_PKT_BIND: + ndr_print_dcerpc_bind(ndr, "bind", &r->bind); + break; + + case DCERPC_PKT_BIND_ACK: + ndr_print_dcerpc_bind_ack(ndr, "bind_ack", &r->bind_ack); + break; + + case DCERPC_PKT_BIND_NAK: + ndr_print_dcerpc_bind_nak(ndr, "bind_nak", &r->bind_nak); + break; + + case DCERPC_PKT_ALTER: + ndr_print_dcerpc_bind(ndr, "alter", &r->alter); + break; + + case DCERPC_PKT_ALTER_RESP: + ndr_print_dcerpc_bind_ack(ndr, "alter_resp", &r->alter_resp); + break; + + case DCERPC_PKT_SHUTDOWN: + ndr_print_dcerpc_shutdown(ndr, "shutdown", &r->shutdown); + break; + + case DCERPC_PKT_CO_CANCEL: + ndr_print_dcerpc_co_cancel(ndr, "co_cancel", &r->co_cancel); + break; + + case DCERPC_PKT_ORPHANED: + ndr_print_dcerpc_orphaned(ndr, "orphaned", &r->orphaned); + break; + + case DCERPC_PKT_AUTH3: + ndr_print_dcerpc_auth3(ndr, "auth3", &r->auth3); + break; + + default: + ndr_print_bad_level(ndr, name, level); + } +} + +_PUBLIC_ enum ndr_err_code ndr_push_ncacn_packet(struct ndr_push *ndr, int ndr_flags, const struct ncacn_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->rpc_vers)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->rpc_vers_minor)); + NDR_CHECK(ndr_push_dcerpc_pkt_type(ndr, NDR_SCALARS, r->ptype)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->pfc_flags)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->drep, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->frag_length)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->auth_length)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->call_id)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_ncacn_packet(struct ndr_pull *ndr, int ndr_flags, struct ncacn_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->rpc_vers)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->rpc_vers_minor)); + NDR_CHECK(ndr_pull_dcerpc_pkt_type(ndr, NDR_SCALARS, &r->ptype)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->pfc_flags)); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->drep, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->frag_length)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->auth_length)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->call_id)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_ncacn_packet(struct ndr_print *ndr, const char *name, const struct ncacn_packet *r) +{ + ndr_print_struct(ndr, name, "ncacn_packet"); + ndr->depth++; + ndr_print_uint8(ndr, "rpc_vers", r->rpc_vers); + ndr_print_uint8(ndr, "rpc_vers_minor", r->rpc_vers_minor); + ndr_print_dcerpc_pkt_type(ndr, "ptype", r->ptype); + ndr_print_uint8(ndr, "pfc_flags", r->pfc_flags); + ndr_print_array_uint8(ndr, "drep", r->drep, 4); + ndr_print_uint16(ndr, "frag_length", r->frag_length); + ndr_print_uint16(ndr, "auth_length", r->auth_length); + ndr_print_uint32(ndr, "call_id", r->call_id); + ndr_print_set_switch_value(ndr, &r->u, r->ptype); + ndr_print_dcerpc_payload(ndr, "u", &r->u); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_ncadg_packet(struct ndr_push *ndr, int ndr_flags, const struct ncadg_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->rpc_vers)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->ptype)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->pfc_flags)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->ncadg_flags)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->drep, 3)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->serial_high)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->iface)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->activity)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->server_boot)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->iface_version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->seq_num)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->opnum)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->ihint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->ahint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->len)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->fragnum)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->auth_proto)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->serial_low)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_ncadg_packet(struct ndr_pull *ndr, int ndr_flags, struct ncadg_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->rpc_vers)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->ptype)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->pfc_flags)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->ncadg_flags)); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->drep, 3)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->serial_high)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->iface)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->activity)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->server_boot)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->iface_version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->seq_num)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->opnum)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->ihint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->ahint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->len)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->fragnum)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->auth_proto)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->serial_low)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_ncadg_packet(struct ndr_print *ndr, const char *name, const struct ncadg_packet *r) +{ + ndr_print_struct(ndr, name, "ncadg_packet"); + ndr->depth++; + ndr_print_uint8(ndr, "rpc_vers", r->rpc_vers); + ndr_print_uint8(ndr, "ptype", r->ptype); + ndr_print_uint8(ndr, "pfc_flags", r->pfc_flags); + ndr_print_uint8(ndr, "ncadg_flags", r->ncadg_flags); + ndr_print_array_uint8(ndr, "drep", r->drep, 3); + ndr_print_uint8(ndr, "serial_high", r->serial_high); + ndr_print_GUID(ndr, "object", &r->object); + ndr_print_GUID(ndr, "iface", &r->iface); + ndr_print_GUID(ndr, "activity", &r->activity); + ndr_print_uint32(ndr, "server_boot", r->server_boot); + ndr_print_uint32(ndr, "iface_version", r->iface_version); + ndr_print_uint32(ndr, "seq_num", r->seq_num); + ndr_print_uint16(ndr, "opnum", r->opnum); + ndr_print_uint16(ndr, "ihint", r->ihint); + ndr_print_uint16(ndr, "ahint", r->ahint); + ndr_print_uint16(ndr, "len", r->len); + ndr_print_uint16(ndr, "fragnum", r->fragnum); + ndr_print_uint8(ndr, "auth_proto", r->auth_proto); + ndr_print_uint8(ndr, "serial_low", r->serial_low); + ndr_print_set_switch_value(ndr, &r->u, r->ptype); + ndr_print_dcerpc_payload(ndr, "u", &r->u); + ndr->depth--; +} + diff --git a/librpc/gen_ndr/ndr_dcerpc.h b/librpc/gen_ndr/ndr_dcerpc.h new file mode 100644 index 0000000000..9baa089d8a --- /dev/null +++ b/librpc/gen_ndr/ndr_dcerpc.h @@ -0,0 +1,65 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "../librpc/gen_ndr/dcerpc.h" + +#ifndef _HEADER_NDR_dcerpc +#define _HEADER_NDR_dcerpc + +#define NDR_DCERPC_CALL_COUNT (0) +void ndr_print_dcerpc_ctx_list(struct ndr_print *ndr, const char *name, const struct dcerpc_ctx_list *r); +void ndr_print_dcerpc_bind(struct ndr_print *ndr, const char *name, const struct dcerpc_bind *r); +void ndr_print_dcerpc_empty(struct ndr_print *ndr, const char *name, const struct dcerpc_empty *r); +void ndr_print_dcerpc_object(struct ndr_print *ndr, const char *name, const union dcerpc_object *r); +void ndr_print_dcerpc_request(struct ndr_print *ndr, const char *name, const struct dcerpc_request *r); +void ndr_print_dcerpc_ack_ctx(struct ndr_print *ndr, const char *name, const struct dcerpc_ack_ctx *r); +void ndr_print_dcerpc_bind_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_ack *r); +void ndr_print_dcerpc_bind_nak_versions(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak_versions *r); +void ndr_print_dcerpc_bind_nak_versions_ctr(struct ndr_print *ndr, const char *name, const union dcerpc_bind_nak_versions_ctr *r); +void ndr_print_dcerpc_bind_nak(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak *r); +void ndr_print_dcerpc_response(struct ndr_print *ndr, const char *name, const struct dcerpc_response *r); +void ndr_print_dcerpc_fault(struct ndr_print *ndr, const char *name, const struct dcerpc_fault *r); +void ndr_print_dcerpc_AuthType(struct ndr_print *ndr, const char *name, enum dcerpc_AuthType r); +void ndr_print_dcerpc_AuthLevel(struct ndr_print *ndr, const char *name, enum dcerpc_AuthLevel r); +enum ndr_err_code ndr_push_dcerpc_auth(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth *r); +enum ndr_err_code ndr_pull_dcerpc_auth(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth *r); +void ndr_print_dcerpc_auth(struct ndr_print *ndr, const char *name, const struct dcerpc_auth *r); +enum ndr_err_code ndr_push_dcerpc_auth3(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth3 *r); +enum ndr_err_code ndr_pull_dcerpc_auth3(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth3 *r); +void ndr_print_dcerpc_auth3(struct ndr_print *ndr, const char *name, const struct dcerpc_auth3 *r); +enum ndr_err_code ndr_push_dcerpc_orphaned(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_orphaned *r); +enum ndr_err_code ndr_pull_dcerpc_orphaned(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_orphaned *r); +void ndr_print_dcerpc_orphaned(struct ndr_print *ndr, const char *name, const struct dcerpc_orphaned *r); +enum ndr_err_code ndr_push_dcerpc_co_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_co_cancel *r); +enum ndr_err_code ndr_pull_dcerpc_co_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_co_cancel *r); +void ndr_print_dcerpc_co_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_co_cancel *r); +enum ndr_err_code ndr_push_dcerpc_cl_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cl_cancel *r); +enum ndr_err_code ndr_pull_dcerpc_cl_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cl_cancel *r); +void ndr_print_dcerpc_cl_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_cl_cancel *r); +enum ndr_err_code ndr_push_dcerpc_cancel_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cancel_ack *r); +enum ndr_err_code ndr_pull_dcerpc_cancel_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cancel_ack *r); +void ndr_print_dcerpc_cancel_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_cancel_ack *r); +enum ndr_err_code ndr_push_dcerpc_fack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_fack *r); +enum ndr_err_code ndr_pull_dcerpc_fack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_fack *r); +void ndr_print_dcerpc_fack(struct ndr_print *ndr, const char *name, const struct dcerpc_fack *r); +enum ndr_err_code ndr_push_dcerpc_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ack *r); +enum ndr_err_code ndr_pull_dcerpc_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ack *r); +void ndr_print_dcerpc_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_ack *r); +enum ndr_err_code ndr_push_dcerpc_ping(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ping *r); +enum ndr_err_code ndr_pull_dcerpc_ping(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ping *r); +void ndr_print_dcerpc_ping(struct ndr_print *ndr, const char *name, const struct dcerpc_ping *r); +enum ndr_err_code ndr_push_dcerpc_shutdown(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_shutdown *r); +enum ndr_err_code ndr_pull_dcerpc_shutdown(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_shutdown *r); +void ndr_print_dcerpc_shutdown(struct ndr_print *ndr, const char *name, const struct dcerpc_shutdown *r); +enum ndr_err_code ndr_push_dcerpc_working(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_working *r); +enum ndr_err_code ndr_pull_dcerpc_working(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_working *r); +void ndr_print_dcerpc_working(struct ndr_print *ndr, const char *name, const struct dcerpc_working *r); +void ndr_print_dcerpc_pkt_type(struct ndr_print *ndr, const char *name, enum dcerpc_pkt_type r); +void ndr_print_dcerpc_payload(struct ndr_print *ndr, const char *name, const union dcerpc_payload *r); +enum ndr_err_code ndr_push_ncacn_packet(struct ndr_push *ndr, int ndr_flags, const struct ncacn_packet *r); +enum ndr_err_code ndr_pull_ncacn_packet(struct ndr_pull *ndr, int ndr_flags, struct ncacn_packet *r); +void ndr_print_ncacn_packet(struct ndr_print *ndr, const char *name, const struct ncacn_packet *r); +enum ndr_err_code ndr_push_ncadg_packet(struct ndr_push *ndr, int ndr_flags, const struct ncadg_packet *r); +enum ndr_err_code ndr_pull_ncadg_packet(struct ndr_pull *ndr, int ndr_flags, struct ncadg_packet *r); +void ndr_print_ncadg_packet(struct ndr_print *ndr, const char *name, const struct ncadg_packet *r); +#endif /* _HEADER_NDR_dcerpc */ -- cgit From de2a7c8e4caa4898a3ff5cfd85d21cddec8188f2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 21 Mar 2009 00:10:14 +0100 Subject: s3: use generated dcerpc code. Guenther --- source3/Makefile.in | 3 ++- source3/include/rpc_dce.h | 10 ---------- source3/include/smb.h | 2 ++ 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index b28109ec60..ec52d85508 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -284,7 +284,8 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \ ../librpc/ndr/ndr_sec_helper.o \ librpc/ndr/ndr_string.o \ ../librpc/ndr/uuid.o \ - librpc/ndr/util.o + librpc/ndr/util.o \ + ../librpc/gen_ndr/ndr_dcerpc.o RPCCLIENT_NDR_OBJ = rpc_client/ndr.o diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index 580b14f1d8..ca58040757 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -81,16 +81,6 @@ enum RPC_PKT_TYPE { #define RPC_PIPE_AUTH_SEAL_LEVEL 0x6 #endif -#define DCERPC_FAULT_OP_RNG_ERROR 0x1c010002 -#define DCERPC_FAULT_UNK_IF 0x1c010003 -#define DCERPC_FAULT_INVALID_TAG 0x1c000006 -#define DCERPC_FAULT_CONTEXT_MISMATCH 0x1c00001a -#define DCERPC_FAULT_OTHER 0x00000001 -#define DCERPC_FAULT_ACCESS_DENIED 0x00000005 -#define DCERPC_FAULT_CANT_PERFORM 0x000006d8 -#define DCERPC_FAULT_NDR 0x000006f7 - - /* Netlogon schannel auth type and level */ #define SCHANNEL_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } #define SCHANNEL_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } diff --git a/source3/include/smb.h b/source3/include/smb.h index 84aa36a364..01e6ddf64c 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -252,6 +252,8 @@ struct id_map { #include "librpc/gen_ndr/drsuapi.h" #include "librpc/gen_ndr/drsblobs.h" #include "librpc/gen_ndr/spoolss.h" +#include "librpc/gen_ndr/dcerpc.h" +#include "librpc/gen_ndr/ndr_dcerpc.h" struct lsa_dom_info { bool valid; -- cgit From f91565544f96be60cb6464d739008f8241e55d5c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Mar 2009 11:07:16 +0100 Subject: Fix bug 6097 A client sent a SID with authority 0 and 0 sub-authorities. W2k3 replies with NT_STATUS_INVALID_SID, even if other SIDs in the list are valid. Thanks to Pavel for the bug report! --- source3/passdb/lookup_sid.c | 2 +- source3/rpc_server/srv_lsa_nt.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 9c20042a62..a5c2d50366 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -804,7 +804,7 @@ NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids, } else { /* This is a normal SID with rid component */ if (!sid_split_rid(&sid, &rid)) { - result = NT_STATUS_INVALID_PARAMETER; + result = NT_STATUS_INVALID_SID; goto fail; } } diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index ed54c3a86e..5fdcaf2d4a 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -827,6 +827,10 @@ NTSTATUS _lsa_LookupSids(pipes_struct *p, &names, &mapped_count); + if (NT_STATUS_IS_ERR(status)) { + return status; + } + /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */ names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName, num_sids); -- cgit From 6a2e71b12dbfed195859f0fc521ec5a5c145e1f5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 1 Mar 2009 22:25:51 +0100 Subject: Add tevent_req_simple_recv_ntstatus() --- lib/util/tevent_ntstatus.c | 10 ++++++++++ lib/util/tevent_ntstatus.h | 1 + 2 files changed, 11 insertions(+) diff --git a/lib/util/tevent_ntstatus.c b/lib/util/tevent_ntstatus.c index 1a34e9c749..4e4339989a 100644 --- a/lib/util/tevent_ntstatus.c +++ b/lib/util/tevent_ntstatus.c @@ -49,3 +49,13 @@ bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status) } return true; } + +NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} diff --git a/lib/util/tevent_ntstatus.h b/lib/util/tevent_ntstatus.h index 84c275fb13..d7194a9b73 100644 --- a/lib/util/tevent_ntstatus.h +++ b/lib/util/tevent_ntstatus.h @@ -28,5 +28,6 @@ bool tevent_req_nterror(struct tevent_req *req, NTSTATUS status); bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *pstatus); +NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req); #endif -- cgit From 1dd08834586484f0a463ba9378e03f742871d517 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 21:37:27 +0100 Subject: Convert rpc_read to tevent_req --- source3/rpc_client/cli_pipe.c | 69 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 57f49fb83a..f27278de45 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -209,16 +209,17 @@ struct rpc_read_state { static void rpc_read_done(struct async_req *subreq); -static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_transport *transport, - uint8_t *data, size_t size) +static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_cli_transport *transport, + uint8_t *data, size_t size) { - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_read_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -235,33 +236,33 @@ static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_read_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_read_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_read_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_read_state *state = tevent_req_data( + req, struct rpc_read_state); NTSTATUS status; ssize_t received; status = state->transport->read_recv(subreq, &received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->num_read += received; if (state->num_read == state->size) { - async_req_done(req); + tevent_req_done(req); return; } @@ -269,16 +270,16 @@ static void rpc_read_done(struct async_req *subreq) state->data + state->num_read, state->size - state->num_read, state->transport->priv); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } subreq->async.fn = rpc_read_done; subreq->async.priv = req; } -static NTSTATUS rpc_read_recv(struct async_req *req) +static NTSTATUS rpc_read_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } struct rpc_write_state { @@ -399,8 +400,8 @@ struct get_complete_frag_state { prs_struct *pdu; }; -static void get_complete_frag_got_header(struct async_req *subreq); -static void get_complete_frag_got_rest(struct async_req *subreq); +static void get_complete_frag_got_header(struct tevent_req *subreq); +static void get_complete_frag_got_rest(struct tevent_req *subreq); static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -408,7 +409,8 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, struct rpc_hdr_info *prhdr, prs_struct *pdu) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct get_complete_frag_state *state; uint32_t pdu_len; NTSTATUS status; @@ -437,8 +439,8 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = get_complete_frag_got_header; - subreq->async.priv = result; + tevent_req_set_callback(subreq, get_complete_frag_got_header, + result); return result; } @@ -463,8 +465,8 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = get_complete_frag_got_rest; - subreq->async.priv = result; + tevent_req_set_callback(subreq, get_complete_frag_got_rest, + result); return result; } @@ -477,10 +479,10 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, return NULL; } -static void get_complete_frag_got_header(struct async_req *subreq) +static void get_complete_frag_got_header(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct get_complete_frag_state *state = talloc_get_type_abort( req->private_data, struct get_complete_frag_state); NTSTATUS status; @@ -515,14 +517,13 @@ static void get_complete_frag_got_header(struct async_req *subreq) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = get_complete_frag_got_rest; - subreq->async.priv = req; + tevent_req_set_callback(subreq, get_complete_frag_got_rest, req); } -static void get_complete_frag_got_rest(struct async_req *subreq) +static void get_complete_frag_got_rest(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); NTSTATUS status; status = rpc_read_recv(subreq); -- cgit From 7573bb758e843912335af7ee3a60b21a31b5118e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 21:49:19 +0100 Subject: Convert rpc_write to tevent_req --- source3/rpc_client/cli_pipe.c | 111 ++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f27278de45..7dcd103456 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -292,16 +292,17 @@ struct rpc_write_state { static void rpc_write_done(struct async_req *subreq); -static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_transport *transport, - const uint8_t *data, size_t size) +static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_cli_transport *transport, + const uint8_t *data, size_t size) { - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_write_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -317,33 +318,33 @@ static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_write_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_write_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_write_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_write_state *state = tevent_req_data( + req, struct rpc_write_state); NTSTATUS status; ssize_t written; status = state->transport->write_recv(subreq, &written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->num_written += written; if (state->num_written == state->size) { - async_req_done(req); + tevent_req_done(req); return; } @@ -351,16 +352,16 @@ static void rpc_write_done(struct async_req *subreq) state->data + state->num_written, state->size - state->num_written, state->transport->priv); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } subreq->async.fn = rpc_write_done; subreq->async.priv = req; } -static NTSTATUS rpc_write_recv(struct async_req *req) +static NTSTATUS rpc_write_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } @@ -1039,7 +1040,7 @@ struct cli_api_pipe_state { }; static void cli_api_pipe_trans_done(struct async_req *subreq); -static void cli_api_pipe_write_done(struct async_req *subreq); +static void cli_api_pipe_write_done(struct tevent_req *subreq); static void cli_api_pipe_read_done(struct async_req *subreq); static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, @@ -1049,6 +1050,7 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, uint32_t max_rdata_len) { struct async_req *result, *subreq; + struct tevent_req *subreq2; struct cli_api_pipe_state *state; NTSTATUS status; @@ -1086,12 +1088,11 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, * example the ncacn_ip_tcp transport, do the write/read step here. */ - subreq = rpc_write_send(state, ev, transport, data, data_len); - if (subreq == NULL) { + subreq2 = rpc_write_send(state, ev, transport, data, data_len); + if (subreq2 == NULL) { goto fail; } - subreq->async.fn = cli_api_pipe_write_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq2, cli_api_pipe_write_done, result); return result; status = NT_STATUS_INVALID_PARAMETER; @@ -1123,12 +1124,13 @@ static void cli_api_pipe_trans_done(struct async_req *subreq) async_req_done(req); } -static void cli_api_pipe_write_done(struct async_req *subreq) +static void cli_api_pipe_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct cli_api_pipe_state *state = talloc_get_type_abort( req->private_data, struct cli_api_pipe_state); + struct async_req *subreq2; NTSTATUS status; status = rpc_write_recv(subreq); @@ -1148,14 +1150,14 @@ static void cli_api_pipe_write_done(struct async_req *subreq) * with a short read, transport->trans_send could also return less * than state->max_rdata_len. */ - subreq = state->transport->read_send(state, state->ev, state->rdata, - RPC_HEADER_LEN, - state->transport->priv); - if (async_req_nomem(subreq, req)) { + subreq2 = state->transport->read_send(state, state->ev, state->rdata, + RPC_HEADER_LEN, + state->transport->priv); + if (async_req_nomem(subreq2, req)) { return; } - subreq->async.fn = cli_api_pipe_read_done; - subreq->async.priv = req; + subreq2->async.fn = cli_api_pipe_read_done; + subreq2->async.priv = req; } static void cli_api_pipe_read_done(struct async_req *subreq) @@ -2044,7 +2046,7 @@ static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s) return 0; } -static void rpc_api_pipe_req_write_done(struct async_req *subreq); +static void rpc_api_pipe_req_write_done(struct tevent_req *subreq); static void rpc_api_pipe_req_done(struct async_req *subreq); static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, bool *is_last_frag); @@ -2056,6 +2058,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, prs_struct *req_data) { struct async_req *result, *subreq; + struct tevent_req *subreq2; struct rpc_api_pipe_req_state *state; NTSTATUS status; bool is_last_frag; @@ -2104,16 +2107,16 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, subreq->async.fn = rpc_api_pipe_req_done; subreq->async.priv = result; } else { - subreq = rpc_write_send( + subreq2 = rpc_write_send( state, ev, cli->transport, (uint8_t *)prs_data_p(&state->outgoing_frag), prs_offset(&state->outgoing_frag)); - if (subreq == NULL) { + if (subreq2 == NULL) { status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = rpc_api_pipe_req_write_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq2, rpc_api_pipe_req_write_done, + result); } return result; @@ -2210,12 +2213,13 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, return status; } -static void rpc_api_pipe_req_write_done(struct async_req *subreq) +static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct rpc_api_pipe_req_state *state = talloc_get_type_abort( req->private_data, struct rpc_api_pipe_req_state); + struct async_req *subreq2; NTSTATUS status; bool is_last_frag; @@ -2233,14 +2237,14 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq) } if (is_last_frag) { - subreq = rpc_api_pipe_send(state, state->ev, state->cli, + subreq2 = rpc_api_pipe_send(state, state->ev, state->cli, &state->outgoing_frag, RPC_RESPONSE); - if (async_req_nomem(subreq, req)) { + if (async_req_nomem(subreq2, req)) { return; } - subreq->async.fn = rpc_api_pipe_req_done; - subreq->async.priv = req; + subreq2->async.fn = rpc_api_pipe_req_done; + subreq2->async.priv = req; } else { subreq = rpc_write_send( state, state->ev, @@ -2250,8 +2254,8 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_api_pipe_req_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done, + req); } } @@ -2528,7 +2532,7 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu); -static void rpc_bind_auth3_write_done(struct async_req *subreq); +static void rpc_bind_auth3_write_done(struct tevent_req *subreq); static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, @@ -2692,7 +2696,7 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, DATA_BLOB server_response = data_blob_null; DATA_BLOB client_reply = data_blob_null; struct rpc_hdr_auth_info hdr_auth; - struct async_req *subreq; + struct tevent_req *subreq; NTSTATUS status; if ((phdr->auth_len == 0) @@ -2743,15 +2747,14 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, if (subreq == NULL) { return NT_STATUS_NO_MEMORY; } - subreq->async.fn = rpc_bind_auth3_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req); return NT_STATUS_OK; } -static void rpc_bind_auth3_write_done(struct async_req *subreq) +static void rpc_bind_auth3_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); NTSTATUS status; status = rpc_write_recv(subreq); -- cgit From 7a429fb369f608c0aaad20a89baf86aebf615440 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 21:57:19 +0100 Subject: Convert get_complete_frag to tevent_req --- source3/rpc_client/cli_pipe.c | 84 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7dcd103456..8f39e971c3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -404,20 +404,20 @@ struct get_complete_frag_state { static void get_complete_frag_got_header(struct tevent_req *subreq); static void get_complete_frag_got_rest(struct tevent_req *subreq); -static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - struct rpc_hdr_info *prhdr, - prs_struct *pdu) +static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct rpc_hdr_info *prhdr, + prs_struct *pdu) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct get_complete_frag_state *state; uint32_t pdu_len; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct get_complete_frag_state)) { + req = tevent_req_create(mem_ctx, &state, + struct get_complete_frag_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -441,8 +441,8 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, goto post_status; } tevent_req_set_callback(subreq, get_complete_frag_got_header, - result); - return result; + req); + return req; } status = parse_rpc_header(cli, prhdr, pdu); @@ -467,42 +467,43 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, goto post_status; } tevent_req_set_callback(subreq, get_complete_frag_got_rest, - result); - return result; + req); + return req; } status = NT_STATUS_OK; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + } else { + tevent_req_nterror(req, status); } - TALLOC_FREE(result); - return NULL; + return tevent_req_post(req, ev); } static void get_complete_frag_got_header(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct get_complete_frag_state *state = talloc_get_type_abort( - req->private_data, struct get_complete_frag_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct get_complete_frag_state *state = tevent_req_data( + req, struct get_complete_frag_state); NTSTATUS status; status = rpc_read_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } status = parse_rpc_header(state->cli, state->prhdr, state->pdu); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) { - async_req_nterror(req, NT_STATUS_NO_MEMORY); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -515,7 +516,7 @@ static void get_complete_frag_got_header(struct tevent_req *subreq) state, state->ev, state->cli->transport, (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN), state->prhdr->frag_len - RPC_HEADER_LEN); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, get_complete_frag_got_rest, req); @@ -523,22 +524,22 @@ static void get_complete_frag_got_header(struct tevent_req *subreq) static void get_complete_frag_got_rest(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); NTSTATUS status; status = rpc_read_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS get_complete_frag_recv(struct async_req *req) +static NTSTATUS get_complete_frag_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } /**************************************************************************** @@ -1241,7 +1242,7 @@ static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state) } static void rpc_api_pipe_trans_done(struct async_req *subreq); -static void rpc_api_pipe_got_pdu(struct async_req *subreq); +static void rpc_api_pipe_got_pdu(struct tevent_req *subreq); static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -1312,6 +1313,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq) subreq->async.priv, struct async_req); struct rpc_api_pipe_state *state = talloc_get_type_abort( req->private_data, struct rpc_api_pipe_state); + struct tevent_req *subreq2; NTSTATUS status; uint8_t *rdata = NULL; uint32_t rdata_len = 0; @@ -1345,19 +1347,18 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq) prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true); /* Ensure we have enough data for a pdu. */ - subreq = get_complete_frag_send(state, state->ev, state->cli, - &state->rhdr, &state->incoming_frag); - if (async_req_nomem(subreq, req)) { + subreq2 = get_complete_frag_send(state, state->ev, state->cli, + &state->rhdr, &state->incoming_frag); + if (async_req_nomem(subreq2, req)) { return; } - subreq->async.fn = rpc_api_pipe_got_pdu; - subreq->async.priv = req; + tevent_req_set_callback(subreq2, rpc_api_pipe_got_pdu, req); } -static void rpc_api_pipe_got_pdu(struct async_req *subreq) +static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct rpc_api_pipe_state *state = talloc_get_type_abort( req->private_data, struct rpc_api_pipe_state); NTSTATUS status; @@ -1442,8 +1443,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_api_pipe_got_pdu; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req); } static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, -- cgit From 545ed5b52e41f495a48370ba4218834337b85dd2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 22:13:44 +0100 Subject: Convert cli_api_pipe to tevent_req --- source3/rpc_client/cli_pipe.c | 103 ++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8f39e971c3..d39fb8516f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1044,19 +1044,20 @@ static void cli_api_pipe_trans_done(struct async_req *subreq); static void cli_api_pipe_write_done(struct tevent_req *subreq); static void cli_api_pipe_read_done(struct async_req *subreq); -static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_transport *transport, - uint8_t *data, size_t data_len, - uint32_t max_rdata_len) +static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_cli_transport *transport, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len) { - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct tevent_req *subreq2; struct cli_api_pipe_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct cli_api_pipe_state)) { + req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -1080,8 +1081,8 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, goto post_status; } subreq->async.fn = cli_api_pipe_trans_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; } /* @@ -1093,56 +1094,59 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, if (subreq2 == NULL) { goto fail; } - tevent_req_set_callback(subreq2, cli_api_pipe_write_done, result); - return result; + tevent_req_set_callback(subreq2, cli_api_pipe_write_done, req); + return req; status = NT_STATUS_INVALID_PARAMETER; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + } else { + tevent_req_nterror(req, status); } + return tevent_req_post(req, ev); fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void cli_api_pipe_trans_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; status = state->transport->trans_recv(subreq, state, &state->rdata, &state->rdata_len); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } static void cli_api_pipe_write_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); struct async_req *subreq2; NTSTATUS status; status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN); - if (async_req_nomem(state->rdata, req)) { + if (tevent_req_nomem(state->rdata, req)) { return; } @@ -1154,7 +1158,7 @@ static void cli_api_pipe_write_done(struct tevent_req *subreq) subreq2 = state->transport->read_send(state, state->ev, state->rdata, RPC_HEADER_LEN, state->transport->priv); - if (async_req_nomem(subreq2, req)) { + if (tevent_req_nomem(subreq2, req)) { return; } subreq2->async.fn = cli_api_pipe_read_done; @@ -1163,31 +1167,31 @@ static void cli_api_pipe_write_done(struct tevent_req *subreq) static void cli_api_pipe_read_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; ssize_t received; status = state->transport->read_recv(subreq, &received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->rdata_len = received; - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len) { - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } @@ -1241,7 +1245,7 @@ static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state) return 0; } -static void rpc_api_pipe_trans_done(struct async_req *subreq); +static void rpc_api_pipe_trans_done(struct tevent_req *subreq); static void rpc_api_pipe_got_pdu(struct tevent_req *subreq); static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, @@ -1250,7 +1254,8 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, prs_struct *data, /* Outgoing PDU */ uint8_t expected_pkt_type) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct rpc_api_pipe_state *state; uint16_t max_recv_frag; NTSTATUS status; @@ -1295,8 +1300,7 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = rpc_api_pipe_trans_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, result); return result; post_status: @@ -1307,13 +1311,12 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, return NULL; } -static void rpc_api_pipe_trans_done(struct async_req *subreq) +static void rpc_api_pipe_trans_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct rpc_api_pipe_state *state = talloc_get_type_abort( req->private_data, struct rpc_api_pipe_state); - struct tevent_req *subreq2; NTSTATUS status; uint8_t *rdata = NULL; uint32_t rdata_len = 0; @@ -1347,12 +1350,12 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq) prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true); /* Ensure we have enough data for a pdu. */ - subreq2 = get_complete_frag_send(state, state->ev, state->cli, - &state->rhdr, &state->incoming_frag); - if (async_req_nomem(subreq2, req)) { + subreq = get_complete_frag_send(state, state->ev, state->cli, + &state->rhdr, &state->incoming_frag); + if (async_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq2, rpc_api_pipe_got_pdu, req); + tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req); } static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) -- cgit From f88990ec7ec92f0b8371419bfdf777d1d624abf9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 22:33:00 +0100 Subject: Convert rpc_api_pipe to tevent_req --- source3/rpc_client/cli_pipe.c | 149 ++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 78 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d39fb8516f..b87c8a6815 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1248,20 +1248,19 @@ static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state) static void rpc_api_pipe_trans_done(struct tevent_req *subreq); static void rpc_api_pipe_got_pdu(struct tevent_req *subreq); -static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - prs_struct *data, /* Outgoing PDU */ - uint8_t expected_pkt_type) +static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + prs_struct *data, /* Outgoing PDU */ + uint8_t expected_pkt_type) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_api_pipe_state *state; uint16_t max_recv_frag; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_api_pipe_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -1297,26 +1296,25 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, (uint8_t *)prs_data_p(data), prs_offset(data), max_recv_frag); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, result); - return result; + tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req); + return req; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } - TALLOC_FREE(result); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + fail: + TALLOC_FREE(req); return NULL; } static void rpc_api_pipe_trans_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct rpc_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_state *state = tevent_req_data( + req, struct rpc_api_pipe_state); NTSTATUS status; uint8_t *rdata = NULL; uint32_t rdata_len = 0; @@ -1326,14 +1324,14 @@ static void rpc_api_pipe_trans_done(struct tevent_req *subreq) TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status))); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } if (rdata == NULL) { DEBUG(3,("rpc_api_pipe: %s failed to return data.\n", rpccli_pipe_txt(debug_ctx(), state->cli))); - async_req_done(req); + tevent_req_done(req); return; } @@ -1344,7 +1342,7 @@ static void rpc_api_pipe_trans_done(struct tevent_req *subreq) */ rdata_copy = (char *)memdup(rdata, rdata_len); TALLOC_FREE(rdata); - if (async_req_nomem(rdata_copy, req)) { + if (tevent_req_nomem(rdata_copy, req)) { return; } prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true); @@ -1352,7 +1350,7 @@ static void rpc_api_pipe_trans_done(struct tevent_req *subreq) /* Ensure we have enough data for a pdu. */ subreq = get_complete_frag_send(state, state->ev, state->cli, &state->rhdr, &state->incoming_frag); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req); @@ -1360,10 +1358,10 @@ static void rpc_api_pipe_trans_done(struct tevent_req *subreq) static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct rpc_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_state *state = tevent_req_data( + req, struct rpc_api_pipe_state); NTSTATUS status; char *rdata = NULL; uint32_t rdata_len = 0; @@ -1373,7 +1371,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("get_complete_frag failed: %s\n", nt_errstr(status))); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -1388,7 +1386,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) nt_errstr(status))); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -1412,13 +1410,13 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) "%s\n", state->incoming_pdu.bigendian_data?"big":"little", state->incoming_frag.bigendian_data?"big":"little")); - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } /* Now copy the data portion out of the pdu into rbuf. */ if (!prs_force_grow(&state->incoming_pdu, rdata_len)) { - async_req_nterror(req, NT_STATUS_NO_MEMORY); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1429,7 +1427,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr, &state->incoming_frag); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -1437,26 +1435,26 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n", rpccli_pipe_txt(debug_ctx(), state->cli), (unsigned)prs_data_size(&state->incoming_pdu))); - async_req_done(req); + tevent_req_done(req); return; } subreq = get_complete_frag_send(state, state->ev, state->cli, &state->rhdr, &state->incoming_frag); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req); } -static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, prs_struct *reply_pdu) { - struct rpc_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_state); + struct rpc_api_pipe_state *state = tevent_req_data( + req, struct rpc_api_pipe_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } @@ -2050,7 +2048,7 @@ static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s) } static void rpc_api_pipe_req_write_done(struct tevent_req *subreq); -static void rpc_api_pipe_req_done(struct async_req *subreq); +static void rpc_api_pipe_req_done(struct tevent_req *subreq); static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, bool *is_last_frag); @@ -2060,8 +2058,8 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, uint8_t op_num, prs_struct *req_data) { - struct async_req *result, *subreq; - struct tevent_req *subreq2; + struct async_req *result; + struct tevent_req *subreq; struct rpc_api_pipe_req_state *state; NTSTATUS status; bool is_last_frag; @@ -2088,8 +2086,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag, state, MARSHALL)) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } talloc_set_destructor(state, rpc_api_pipe_req_state_destructor); @@ -2104,21 +2101,19 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, &state->outgoing_frag, RPC_RESPONSE); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = rpc_api_pipe_req_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, rpc_api_pipe_req_done, + result); } else { - subreq2 = rpc_write_send( + subreq = rpc_write_send( state, ev, cli->transport, (uint8_t *)prs_data_p(&state->outgoing_frag), prs_offset(&state->outgoing_frag)); - if (subreq2 == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + if (subreq == NULL) { + goto fail; } - tevent_req_set_callback(subreq2, rpc_api_pipe_req_write_done, + tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done, result); } return result; @@ -2127,6 +2122,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, if (async_post_ntstatus(result, ev, status)) { return result; } + fail: TALLOC_FREE(result); return NULL; } @@ -2222,7 +2218,6 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) subreq, struct async_req); struct rpc_api_pipe_req_state *state = talloc_get_type_abort( req->private_data, struct rpc_api_pipe_req_state); - struct async_req *subreq2; NTSTATUS status; bool is_last_frag; @@ -2240,14 +2235,13 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) } if (is_last_frag) { - subreq2 = rpc_api_pipe_send(state, state->ev, state->cli, + subreq = rpc_api_pipe_send(state, state->ev, state->cli, &state->outgoing_frag, RPC_RESPONSE); - if (async_req_nomem(subreq2, req)) { + if (async_req_nomem(subreq, req)) { return; } - subreq2->async.fn = rpc_api_pipe_req_done; - subreq2->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); } else { subreq = rpc_write_send( state, state->ev, @@ -2262,10 +2256,10 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) } } -static void rpc_api_pipe_req_done(struct async_req *subreq) +static void rpc_api_pipe_req_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct rpc_api_pipe_req_state *state = talloc_get_type_abort( req->private_data, struct rpc_api_pipe_req_state); NTSTATUS status; @@ -2530,7 +2524,7 @@ static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state) return 0; } -static void rpc_pipe_bind_step_one_done(struct async_req *subreq); +static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, @@ -2540,14 +2534,15 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu); -static void rpc_bind_ntlmssp_api_done(struct async_req *subreq); +static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq); struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct rpc_pipe_client *cli, struct cli_pipe_auth_data *auth) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct rpc_pipe_bind_state *state; NTSTATUS status; @@ -2585,25 +2580,24 @@ struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out, RPC_BINDACK); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = rpc_pipe_bind_step_one_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, result); return result; post_status: if (async_post_ntstatus(result, ev, status)) { return result; } + fail: TALLOC_FREE(result); return NULL; } -static void rpc_pipe_bind_step_one_done(struct async_req *subreq) +static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct rpc_pipe_bind_state *state = talloc_get_type_abort( req->private_data, struct rpc_pipe_bind_state); prs_struct reply_pdu; @@ -2779,7 +2773,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, DATA_BLOB client_reply = data_blob_null; DATA_BLOB tmp_blob = data_blob_null; RPC_HDR_AUTH hdr_auth; - struct async_req *subreq; + struct tevent_req *subreq; NTSTATUS status; if ((phdr->auth_len == 0) @@ -2857,15 +2851,14 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, if (subreq == NULL) { return NT_STATUS_NO_MEMORY; } - subreq->async.fn = rpc_bind_ntlmssp_api_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req); return NT_STATUS_OK; } -static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) +static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = tevent_req_callback_data( + subreq, struct async_req); struct rpc_pipe_bind_state *state = talloc_get_type_abort( req->private_data, struct rpc_pipe_bind_state); DATA_BLOB server_spnego_response = data_blob_null; -- cgit From 1724f2ff316d20dd7e67fed59f467d4a3e187114 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 22:49:29 +0100 Subject: Convert rpc_api_pipe_req to tevent_req --- source3/include/proto.h | 12 +++---- source3/rpc_client/cli_pipe.c | 74 ++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d15e45a874..5df5435f03 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5256,12 +5256,12 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, /* The following definitions come from rpc_client/cli_pipe.c */ -struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - uint8_t op_num, - prs_struct *req_data); -NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t op_num, + prs_struct *req_data); +NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, prs_struct *reply_pdu); NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b87c8a6815..8fc05e233e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2052,20 +2052,20 @@ static void rpc_api_pipe_req_done(struct tevent_req *subreq); static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, bool *is_last_frag); -struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - uint8_t op_num, - prs_struct *req_data) +struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t op_num, + prs_struct *req_data) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_api_pipe_req_state *state; NTSTATUS status; bool is_last_frag; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_api_pipe_req_state)) { + req = tevent_req_create(mem_ctx, &state, + struct rpc_api_pipe_req_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -2103,8 +2103,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, rpc_api_pipe_req_done, - result); + tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); } else { subreq = rpc_write_send( state, ev, cli->transport, @@ -2114,16 +2113,15 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, goto fail; } tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done, - result); + req); } - return result; + return req; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } @@ -2214,23 +2212,23 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct rpc_api_pipe_req_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_req_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_req_state *state = tevent_req_data( + req, struct rpc_api_pipe_req_state); NTSTATUS status; bool is_last_frag; status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } status = prepare_next_frag(state, &is_last_frag); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -2238,7 +2236,7 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) subreq = rpc_api_pipe_send(state, state->ev, state->cli, &state->outgoing_frag, RPC_RESPONSE); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); @@ -2248,7 +2246,7 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) state->cli->transport, (uint8_t *)prs_data_p(&state->outgoing_frag), prs_offset(&state->outgoing_frag)); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done, @@ -2258,29 +2256,29 @@ static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) static void rpc_api_pipe_req_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct rpc_api_pipe_req_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_req_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_req_state *state = tevent_req_data( + req, struct rpc_api_pipe_req_state); NTSTATUS status; status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, prs_struct *reply_pdu) { - struct rpc_api_pipe_req_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_req_state); + struct rpc_api_pipe_req_state *state = tevent_req_data( + req, struct rpc_api_pipe_req_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { /* * We always have to initialize to reply pdu, even if there is * none. The rpccli_* caller routines expect this. @@ -2308,7 +2306,7 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; - struct async_req *req; + struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = event_context_init(frame); @@ -2321,9 +2319,7 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, goto fail; } - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } + tevent_req_poll(req, ev); status = rpc_api_pipe_req_recv(req, mem_ctx, out_data); fail: -- cgit From 22badee4bf7d75a4337a3826847070ebd7464ce8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 23:03:37 +0100 Subject: Convert rpc_cli_transport->read to tevent_req --- source3/include/client.h | 10 +++---- source3/rpc_client/cli_pipe.c | 37 +++++++++++--------------- source3/rpc_client/rpc_transport_np.c | 43 +++++++++++++++--------------- source3/rpc_client/rpc_transport_smbd.c | 47 +++++++++++++++------------------ source3/rpc_client/rpc_transport_sock.c | 41 ++++++++++++++-------------- 5 files changed, 85 insertions(+), 93 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index db19f34a9d..6510a14b15 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -71,14 +71,14 @@ struct rpc_cli_transport { /** * Trigger an async read from the server. May return a short read. */ - struct async_req *(*read_send)(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv); + struct tevent_req *(*read_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv); /** * Get the result from the read_send operation. */ - NTSTATUS (*read_recv)(struct async_req *req, ssize_t *preceived); + NTSTATUS (*read_recv)(struct tevent_req *req, ssize_t *preceived); /** * Trigger an async write to the server. May return a short write. diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8fc05e233e..d4abe3c4fd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -207,15 +207,14 @@ struct rpc_read_state { size_t num_read; }; -static void rpc_read_done(struct async_req *subreq); +static void rpc_read_done(struct tevent_req *subreq); static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct rpc_cli_transport *transport, uint8_t *data, size_t size) { - struct tevent_req *req; - struct async_req *subreq; + struct tevent_req *req, *subreq; struct rpc_read_state *state; req = tevent_req_create(mem_ctx, &state, struct rpc_read_state); @@ -235,8 +234,7 @@ static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_read_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_read_done, req); return req; fail: @@ -244,10 +242,10 @@ static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx, return NULL; } -static void rpc_read_done(struct async_req *subreq) +static void rpc_read_done(struct tevent_req *subreq) { - struct tevent_req *req = talloc_get_type_abort( - subreq->async.priv, struct tevent_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); struct rpc_read_state *state = tevent_req_data( req, struct rpc_read_state); NTSTATUS status; @@ -273,8 +271,7 @@ static void rpc_read_done(struct async_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_read_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_read_done, req); } static NTSTATUS rpc_read_recv(struct tevent_req *req) @@ -1042,7 +1039,7 @@ struct cli_api_pipe_state { static void cli_api_pipe_trans_done(struct async_req *subreq); static void cli_api_pipe_write_done(struct tevent_req *subreq); -static void cli_api_pipe_read_done(struct async_req *subreq); +static void cli_api_pipe_read_done(struct tevent_req *subreq); static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -1135,7 +1132,6 @@ static void cli_api_pipe_write_done(struct tevent_req *subreq) subreq, struct tevent_req); struct cli_api_pipe_state *state = tevent_req_data( req, struct cli_api_pipe_state); - struct async_req *subreq2; NTSTATUS status; status = rpc_write_recv(subreq); @@ -1155,20 +1151,19 @@ static void cli_api_pipe_write_done(struct tevent_req *subreq) * with a short read, transport->trans_send could also return less * than state->max_rdata_len. */ - subreq2 = state->transport->read_send(state, state->ev, state->rdata, - RPC_HEADER_LEN, - state->transport->priv); - if (tevent_req_nomem(subreq2, req)) { + subreq = state->transport->read_send(state, state->ev, state->rdata, + RPC_HEADER_LEN, + state->transport->priv); + if (tevent_req_nomem(subreq, req)) { return; } - subreq2->async.fn = cli_api_pipe_read_done; - subreq2->async.priv = req; + tevent_req_set_callback(subreq, cli_api_pipe_read_done, req); } -static void cli_api_pipe_read_done(struct async_req *subreq) +static void cli_api_pipe_read_done(struct tevent_req *subreq) { - struct tevent_req *req = talloc_get_type_abort( - subreq->async.priv, struct tevent_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); struct cli_api_pipe_state *state = tevent_req_data( req, struct cli_api_pipe_state); NTSTATUS status; diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 80ff384046..7da4421329 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -120,18 +120,19 @@ struct rpc_np_read_state { static void rpc_np_read_done(struct async_req *subreq); -static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) { struct rpc_transport_np_state *np_transport = talloc_get_type_abort( priv, struct rpc_transport_np_state); - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_np_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_np_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state); + if (req == NULL) { return NULL; } state->data = data; @@ -143,19 +144,19 @@ static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_np_read_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_np_read_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_np_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_read_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_np_read_state *state = tevent_req_data( + req, struct rpc_np_read_state); NTSTATUS status; uint8_t *rcvbuf; @@ -169,27 +170,27 @@ static void rpc_np_read_done(struct async_req *subreq) } if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } if (state->received > state->size) { TALLOC_FREE(subreq); - async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } memcpy(state->data, rcvbuf, state->received); - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_np_read_recv(struct async_req *req, ssize_t *preceived) +static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived) { - struct rpc_np_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_read_state); + struct rpc_np_read_state *state = tevent_req_data( + req, struct rpc_np_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *preceived = state->received; diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c index bf4aa65dae..85fe3d86ce 100644 --- a/source3/rpc_client/rpc_transport_smbd.c +++ b/source3/rpc_client/rpc_transport_smbd.c @@ -505,20 +505,20 @@ struct rpc_smbd_read_state { ssize_t received; }; -static void rpc_smbd_read_done(struct async_req *subreq); +static void rpc_smbd_read_done(struct tevent_req *subreq); -static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) { struct rpc_transport_smbd_state *transp = talloc_get_type_abort( priv, struct rpc_transport_smbd_state); - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_smbd_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_smbd_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_read_state); + if (req == NULL) { return NULL; } state->sub_transp = transp->sub_transp; @@ -533,40 +533,37 @@ static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, rpc_cli_smbd_stdout_reader, transp->conn) == NULL) { goto fail; } - - subreq->async.fn = rpc_smbd_read_done; - subreq->async.priv = result; - return result; - + tevent_req_set_callback(subreq, rpc_smbd_read_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void rpc_smbd_read_done(struct async_req *subreq) +static void rpc_smbd_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_smbd_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_smbd_read_state *state = tevent_req_data( + req, struct rpc_smbd_read_state); NTSTATUS status; status = state->sub_transp->read_recv(subreq, &state->received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_smbd_read_recv(struct async_req *req, ssize_t *preceived) +static NTSTATUS rpc_smbd_read_recv(struct tevent_req *req, ssize_t *preceived) { - struct rpc_smbd_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_read_state); + struct rpc_smbd_read_state *state = tevent_req_data( + req, struct rpc_smbd_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *preceived = state->received; diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index b1d9d8fbe1..c9fcbcc07e 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -41,19 +41,18 @@ struct rpc_sock_read_state { static void rpc_sock_read_done(struct tevent_req *subreq); -static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_sock_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_sock_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_sock_read_state); + if (req == NULL) { return NULL; } @@ -61,36 +60,36 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, rpc_sock_read_done, result); - return result; + tevent_req_set_callback(subreq, rpc_sock_read_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_sock_read_done(struct tevent_req *subreq) { - struct async_req *req = - tevent_req_callback_data(subreq, struct async_req); - struct rpc_sock_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_sock_read_state *state = tevent_req_data( + req, struct rpc_sock_read_state); int err; state->received = async_recv_recv(subreq, &err); if (state->received == -1) { - async_req_nterror(req, map_nt_error_from_unix(err)); + tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +static NTSTATUS rpc_sock_read_recv(struct tevent_req *req, ssize_t *preceived) { - struct rpc_sock_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_read_state); + struct rpc_sock_read_state *state = tevent_req_data( + req, struct rpc_sock_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *preceived = state->received; -- cgit From 8e0d9d002a4b0266c9d910bf7ce9c0510c89b09f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 23:20:03 +0100 Subject: Convert rpc_cli_transport->write to tevent_req --- source3/include/client.h | 10 +++---- source3/rpc_client/cli_pipe.c | 17 +++++------- source3/rpc_client/rpc_transport_np.c | 41 +++++++++++++++-------------- source3/rpc_client/rpc_transport_smbd.c | 46 ++++++++++++++++----------------- source3/rpc_client/rpc_transport_sock.c | 41 ++++++++++++++--------------- 5 files changed, 75 insertions(+), 80 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 6510a14b15..f0c8ecc9dd 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -83,14 +83,14 @@ struct rpc_cli_transport { /** * Trigger an async write to the server. May return a short write. */ - struct async_req *(*write_send)(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv); + struct tevent_req *(*write_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv); /** * Get the result from the read_send operation. */ - NTSTATUS (*write_recv)(struct async_req *req, ssize_t *psent); + NTSTATUS (*write_recv)(struct tevent_req *req, ssize_t *psent); /** * This is an optimization for the SMB transport. It models the diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d4abe3c4fd..dbd6930718 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -287,15 +287,14 @@ struct rpc_write_state { size_t num_written; }; -static void rpc_write_done(struct async_req *subreq); +static void rpc_write_done(struct tevent_req *subreq); static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct rpc_cli_transport *transport, const uint8_t *data, size_t size) { - struct tevent_req *req; - struct async_req *subreq; + struct tevent_req *req, *subreq; struct rpc_write_state *state; req = tevent_req_create(mem_ctx, &state, struct rpc_write_state); @@ -314,18 +313,17 @@ static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_write_done, req); return req; fail: TALLOC_FREE(req); return NULL; } -static void rpc_write_done(struct async_req *subreq) +static void rpc_write_done(struct tevent_req *subreq) { - struct tevent_req *req = talloc_get_type_abort( - subreq->async.priv, struct tevent_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); struct rpc_write_state *state = tevent_req_data( req, struct rpc_write_state); NTSTATUS status; @@ -352,8 +350,7 @@ static void rpc_write_done(struct async_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_write_done, req); } static NTSTATUS rpc_write_recv(struct tevent_req *req) diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 7da4421329..620910060a 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -51,18 +51,19 @@ struct rpc_np_write_state { static void rpc_np_write_done(struct async_req *subreq); -static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) { struct rpc_transport_np_state *np_transport = talloc_get_type_abort( priv, struct rpc_transport_np_state); - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_np_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_np_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state); + if (req == NULL) { return NULL; } state->size = size; @@ -75,37 +76,37 @@ static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_np_write_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_np_write_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_np_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_write_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_np_write_state *state = tevent_req_data( + req, struct rpc_np_write_state); NTSTATUS status; status = cli_write_andx_recv(subreq, &state->written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_np_write_recv(struct async_req *req, ssize_t *pwritten) +static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten) { - struct rpc_np_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_write_state); + struct rpc_np_write_state *state = tevent_req_data( + req, struct rpc_np_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *pwritten = state->written; diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c index 85fe3d86ce..bde8d04208 100644 --- a/source3/rpc_client/rpc_transport_smbd.c +++ b/source3/rpc_client/rpc_transport_smbd.c @@ -432,20 +432,20 @@ struct rpc_smbd_write_state { ssize_t written; }; -static void rpc_smbd_write_done(struct async_req *subreq); +static void rpc_smbd_write_done(struct tevent_req *subreq); -static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) { struct rpc_transport_smbd_state *transp = talloc_get_type_abort( priv, struct rpc_transport_smbd_state); - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_smbd_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_smbd_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_write_state); + if (req == NULL) { return NULL; } state->sub_transp = transp->sub_transp; @@ -460,40 +460,38 @@ static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, rpc_cli_smbd_stdout_reader, transp->conn) == NULL) { goto fail; } - - subreq->async.fn = rpc_smbd_write_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, rpc_smbd_write_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void rpc_smbd_write_done(struct async_req *subreq) +static void rpc_smbd_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_smbd_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_write_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_smbd_write_state *state = tevent_req_data( + req, struct rpc_smbd_write_state); NTSTATUS status; status = state->sub_transp->write_recv(subreq, &state->written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_smbd_write_recv(struct async_req *req, ssize_t *pwritten) +static NTSTATUS rpc_smbd_write_recv(struct tevent_req *req, ssize_t *pwritten) { - struct rpc_smbd_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_write_state); + struct rpc_smbd_write_state *state = tevent_req_data( + req, struct rpc_smbd_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *pwritten = state->written; diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index c9fcbcc07e..570d792c9c 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -102,55 +102,54 @@ struct rpc_sock_write_state { static void rpc_sock_write_done(struct tevent_req *subreq); -static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_sock_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_sock_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_sock_write_state); + if (req == NULL) { return NULL; } subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0); if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, rpc_sock_write_done, result); - return result; + tevent_req_set_callback(subreq, rpc_sock_write_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_sock_write_done(struct tevent_req *subreq) { - struct async_req *req = - tevent_req_callback_data(subreq, struct async_req); - struct rpc_sock_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_write_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_sock_write_state *state = tevent_req_data( + req, struct rpc_sock_write_state); int err; state->sent = async_send_recv(subreq, &err); if (state->sent == -1) { - async_req_nterror(req, map_nt_error_from_unix(err)); + tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent) +static NTSTATUS rpc_sock_write_recv(struct tevent_req *req, ssize_t *psent) { - struct rpc_sock_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_write_state); + struct rpc_sock_write_state *state = tevent_req_data( + req, struct rpc_sock_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *psent = state->sent; -- cgit From fa6283683981c61406967ede7ad48910b602f5a4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 23:30:18 +0100 Subject: Convert rpc_cli_transport->trans to tevent_req --- source3/include/client.h | 12 +++++----- source3/rpc_client/cli_pipe.c | 30 +++++++++--------------- source3/rpc_client/rpc_transport_np.c | 43 ++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 46 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index f0c8ecc9dd..73a1d7b554 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -98,15 +98,15 @@ struct rpc_cli_transport { * trip. The transport implementation is free to set this to NULL, * cli_pipe.c will fall back to the explicit write/read routines. */ - struct async_req *(*trans_send)(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t data_len, - uint32_t max_rdata_len, - void *priv); + struct tevent_req *(*trans_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len, + void *priv); /** * Get the result from the trans_send operation. */ - NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx, + NTSTATUS (*trans_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len); void *priv; }; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index dbd6930718..98278e02d9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1034,7 +1034,7 @@ struct cli_api_pipe_state { uint32_t rdata_len; }; -static void cli_api_pipe_trans_done(struct async_req *subreq); +static void cli_api_pipe_trans_done(struct tevent_req *subreq); static void cli_api_pipe_write_done(struct tevent_req *subreq); static void cli_api_pipe_read_done(struct tevent_req *subreq); @@ -1044,9 +1044,7 @@ static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, uint8_t *data, size_t data_len, uint32_t max_rdata_len) { - struct tevent_req *req; - struct async_req *subreq; - struct tevent_req *subreq2; + struct tevent_req *req, *subreq; struct cli_api_pipe_state *state; NTSTATUS status; @@ -1071,11 +1069,9 @@ static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, subreq = transport->trans_send(state, ev, data, data_len, max_rdata_len, transport->priv); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = cli_api_pipe_trans_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req); return req; } @@ -1084,31 +1080,27 @@ static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, * example the ncacn_ip_tcp transport, do the write/read step here. */ - subreq2 = rpc_write_send(state, ev, transport, data, data_len); - if (subreq2 == NULL) { + subreq = rpc_write_send(state, ev, transport, data, data_len); + if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq2, cli_api_pipe_write_done, req); + tevent_req_set_callback(subreq, cli_api_pipe_write_done, req); return req; status = NT_STATUS_INVALID_PARAMETER; post_status: - if (NT_STATUS_IS_OK(status)) { - tevent_req_done(req); - } else { - tevent_req_nterror(req, status); - } + tevent_req_nterror(req, status); return tevent_req_post(req, ev); fail: TALLOC_FREE(req); return NULL; } -static void cli_api_pipe_trans_done(struct async_req *subreq) +static void cli_api_pipe_trans_done(struct tevent_req *subreq) { - struct tevent_req *req = talloc_get_type_abort( - subreq->async.priv, struct tevent_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); struct cli_api_pipe_state *state = tevent_req_data( req, struct cli_api_pipe_state); NTSTATUS status; diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 620910060a..8b45cb4e9c 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -206,19 +206,20 @@ struct rpc_np_trans_state { static void rpc_np_trans_done(struct async_req *subreq); -static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t data_len, - uint32_t max_rdata_len, - void *priv) +static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len, + void *priv) { struct rpc_transport_np_state *np_transport = talloc_get_type_abort( priv, struct rpc_transport_np_state); - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_np_trans_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_np_trans_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state); + if (req == NULL) { return NULL; } @@ -233,40 +234,40 @@ static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_np_trans_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_np_trans_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_np_trans_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_trans_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_np_trans_state *state = tevent_req_data( + req, struct rpc_np_trans_state); NTSTATUS status; status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &state->rdata, &state->rdata_len); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_np_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len) { - struct rpc_np_trans_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_trans_state); + struct rpc_np_trans_state *state = tevent_req_data( + req, struct rpc_np_trans_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *prdata = talloc_move(mem_ctx, &state->rdata); -- cgit From 5f753e22f1f536e0e227db0f453809ad6cfacaf6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Mar 2009 23:38:04 +0100 Subject: Convert rpc_pipe_bind to tevent_req --- source3/include/proto.h | 10 ++--- source3/rpc_client/cli_pipe.c | 96 +++++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 55 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 5df5435f03..3b4b1cf3f1 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5267,11 +5267,11 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, prs_struct *out_data); -struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - struct cli_pipe_auth_data *auth); -NTSTATUS rpc_pipe_bind_recv(struct async_req *req); +struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth); +NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req); NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, struct cli_pipe_auth_data *auth); unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 98278e02d9..6b83c170f5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2505,29 +2505,28 @@ static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state) } static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); -static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, +static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu); static void rpc_bind_auth3_write_done(struct tevent_req *subreq); -static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, +static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu); static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq); -struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - struct cli_pipe_auth_data *auth) +struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth) { - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_pipe_bind_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_pipe_bind_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state); + if (req == NULL) { return NULL; } @@ -2562,24 +2561,23 @@ struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, result); - return result; + tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req); + return req; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct rpc_pipe_bind_state *state = talloc_get_type_abort( - req->private_data, struct rpc_pipe_bind_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_pipe_bind_state *state = tevent_req_data( + req, struct rpc_pipe_bind_state); prs_struct reply_pdu; struct rpc_hdr_info hdr; struct rpc_hdr_ba_info hdr_ba; @@ -2591,7 +2589,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n", rpccli_pipe_txt(debug_ctx(), state->cli), nt_errstr(status))); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -2599,7 +2597,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) { DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n")); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } @@ -2607,14 +2605,14 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall " "RPC_HDR_BA.\n")); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) { DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } @@ -2631,7 +2629,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) case PIPE_AUTH_TYPE_SCHANNEL: /* Bind complete. */ prs_mem_free(&reply_pdu); - async_req_done(req); + tevent_req_done(req); break; case PIPE_AUTH_TYPE_NTLMSSP: @@ -2640,7 +2638,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) &reply_pdu); prs_mem_free(&reply_pdu); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); } break; @@ -2650,7 +2648,7 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) &reply_pdu); prs_mem_free(&reply_pdu); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); } break; @@ -2661,11 +2659,11 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", (unsigned int)state->cli->auth->auth_type)); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); } } -static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, +static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu) @@ -2730,20 +2728,20 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, static void rpc_bind_auth3_write_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); NTSTATUS status; status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, +static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu) @@ -2837,10 +2835,10 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) { - struct async_req *req = tevent_req_callback_data( - subreq, struct async_req); - struct rpc_pipe_bind_state *state = talloc_get_type_abort( - req->private_data, struct rpc_pipe_bind_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_pipe_bind_state *state = tevent_req_data( + req, struct rpc_pipe_bind_state); DATA_BLOB server_spnego_response = data_blob_null; DATA_BLOB tmp_blob = data_blob_null; prs_struct reply_pdu; @@ -2851,7 +2849,7 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -2859,19 +2857,19 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) { DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to " "unmarshall RPC_HDR.\n")); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } if (!prs_set_offset( &reply_pdu, hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) { - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) { - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2884,7 +2882,7 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) OID_NTLMSSP, &tmp_blob)) { data_blob_free(&server_spnego_response); data_blob_free(&tmp_blob); - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2893,12 +2891,12 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli))); - async_req_done(req); + tevent_req_done(req); } -NTSTATUS rpc_pipe_bind_recv(struct async_req *req) +NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, @@ -2906,7 +2904,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; - struct async_req *req; + struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = event_context_init(frame); @@ -2919,9 +2917,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, goto fail; } - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } + tevent_req_poll(req, ev); status = rpc_pipe_bind_recv(req); fail: -- cgit From 2ff2ceffd256b7709d8ee807517f856cfdad5d9e Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 24 Mar 2009 14:59:11 +0100 Subject: wbclient: Fix use of wb_int_trans_send, queue parameter must not be NULL --- source3/lib/wbclient.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index 3cf992c7de..c22e168454 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -449,8 +449,8 @@ static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq) ZERO_STRUCT(state->wb_req); state->wb_req.cmd = WINBINDD_INTERFACE_VERSION; - subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, - &state->wb_req); + subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue, + state->wb_ctx->fd, &state->wb_req); if (tevent_req_nomem(subreq, req)) { return; } @@ -480,8 +480,8 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq) state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR; - subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, - &state->wb_req); + subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue, + state->wb_ctx->fd, &state->wb_req); if (tevent_req_nomem(subreq, req)) { return; } @@ -673,8 +673,8 @@ static void wb_trans_connect_done(struct tevent_req *subreq) return; } - subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, - state->wb_req); + subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue, + state->wb_ctx->fd, state->wb_req); if (tevent_req_nomem(subreq, req)) { return; } -- cgit From 2bc9ffa9fb5c69416b00f46a59b59e0f523634d1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Mar 2009 16:07:46 +0100 Subject: s4-install: add new location of generated dcerpc headers to headermap file. Guenther --- source4/headermap.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/headermap.txt b/source4/headermap.txt index 280d60beb2..1c86f9e934 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -86,6 +86,8 @@ librpc/gen_ndr/nbt.h: gen_ndr/nbt.h librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h +../librpc/gen_ndr/dcerpc.h: gen_ndr/dcerpc.h +../librpc/gen_ndr/ndr_dcerpc.h: gen_ndr/ndr_dcerpc.h ../librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h ../librpc/gen_ndr/ndr_misc.h: gen_ndr/ndr_misc.h ../librpc/gen_ndr/mgmt.h: gen_ndr/mgmt.h -- cgit From c653e8daaf3e842544d7f9561557d1ab9449971c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Mar 2009 21:57:01 +0100 Subject: Fix two memleaks in the encryption code ntlmssp_seal_packet creates its own signature data blob, which we then have to free. Jeremy, please check and merge appropriately (Yes, I'm asking you to do the janitor work, I want you to *look* at this :-)) Volker --- source3/libsmb/smb_seal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 795c8bc14c..2f7305c5b6 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -136,7 +136,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); - sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + ZERO_STRUCT(sig); status = ntlmssp_seal_packet(ntlmssp_state, (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ @@ -153,6 +153,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, /* First 16 data bytes are signature for SSPI compatibility. */ memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); + data_blob_free(&sig); *ppbuf_out = buf_out; return NT_STATUS_OK; } -- cgit From db5677d071fc58f38cab4ab800111455a8637edb Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Mar 2009 17:05:16 -0700 Subject: s3: parse_packet can return NULL which is then dereferenced in match_mailslot_name --- source3/libsmb/unexpected.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index df4d2119e2..d123e24aa8 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -162,6 +162,8 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, state->match_type, ip, port); + if (!p) + return 0; if ((state->match_type == NMB_PACKET && p->packet.nmb.header.name_trn_id == state->match_id) || -- cgit From ad98eae02e623a8ca8aa6a1c46d5aedea50e2e4b Mon Sep 17 00:00:00 2001 From: David Kwan Date: Fri, 20 Mar 2009 16:03:08 +0000 Subject: s3 onefs: Change error status to NT_ACCESS_DENIED for errors in SET_SECURITY_DESC --- source3/modules/onefs_acl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 6f23d608d4..8ee31abc88 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -825,7 +825,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, /* Setup owner */ if (security_info_sent & OWNER_SECURITY_INFORMATION) { if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; SMB_ASSERT(owner.id.uid >= 0); @@ -835,7 +835,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, /* Setup group */ if (security_info_sent & GROUP_SECURITY_INFORMATION) { if (!onefs_og_to_identity(psd->group_sid, &group, true, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; SMB_ASSERT(group.id.gid >= 0); @@ -846,7 +846,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) { if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; if (ignore_aces == true) security_info_sent &= ~DACL_SECURITY_INFORMATION; @@ -863,7 +863,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, if (psd->sacl) { if (!onefs_samba_acl_to_acl(psd->sacl, &saclp, &ignore_aces, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; if (ignore_aces == true) { security_info_sent &= @@ -877,7 +877,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, DEBUG(5,("Setting up SD\n")); if (aclu_initialize_sd(sd, psd->type, ownerp, groupp, (daclp ? &daclp : NULL), (saclp ? &saclp : NULL), false)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; return NT_STATUS_OK; } -- cgit From 283e135298767f128c413e0e6df75d21ec8e8e6b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Mar 2009 16:02:48 +0100 Subject: s3-spoolss: implement enumprinters_level0. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index a8d414b85e..15c137a88c 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4245,6 +4245,10 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, } switch (level) { + case 0: + result = construct_printer_info0(info, ntprinter, + &info[count].info0, snum); + break; case 1: result = construct_printer_info1(info, ntprinter, flags, &info[count].info1, snum); @@ -4290,6 +4294,22 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, return WERR_OK; } +/******************************************************************** + * handle enumeration of printers at level 0 + ********************************************************************/ + +static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *servername, + union spoolss_PrinterInfo **info, + uint32_t *count) +{ + DEBUG(4,("enum_all_printers_info_0\n")); + + return enum_all_printers_info_level(mem_ctx, 0, flags, info, count); +} + + /******************************************************************** ********************************************************************/ @@ -4513,6 +4533,10 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(name); switch (r->in.level) { + case 0: + result = enumprinters_level0(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 1: result = enumprinters_level1(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); -- cgit From ea907a7144beb29cb5c823851a98ceac8166994b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 25 Mar 2009 15:40:39 +0100 Subject: selftest: Add copyright headers --- selftest/SocketWrapper.pm | 16 +++++++++++++++- selftest/Subunit.pm | 16 ++++++++++++++++ selftest/output/buildfarm.pm | 15 +++++++++++++++ selftest/output/html.pm | 16 +++++++++++++++- selftest/output/plain.pm | 16 +++++++++++++++- selftest/selftest.pl | 14 +++++++++++++- 6 files changed, 89 insertions(+), 4 deletions(-) diff --git a/selftest/SocketWrapper.pm b/selftest/SocketWrapper.pm index e63605b8df..ef8058da79 100644 --- a/selftest/SocketWrapper.pm +++ b/selftest/SocketWrapper.pm @@ -1,7 +1,21 @@ #!/usr/bin/perl # Bootstrap Samba and run a number of tests against it. # Copyright (C) 2005-2007 Jelmer Vernooij -# Published under the GNU GPL, v3 or later. + +# 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 . + + package SocketWrapper; diff --git a/selftest/Subunit.pm b/selftest/Subunit.pm index 05e51da541..19af636d0b 100644 --- a/selftest/Subunit.pm +++ b/selftest/Subunit.pm @@ -1,3 +1,19 @@ +# Simple Perl module for parsing the Subunit protocol +# Copyright (C) 2008 Jelmer Vernooij +# +# 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 . + package Subunit; require Exporter; diff --git a/selftest/output/buildfarm.pm b/selftest/output/buildfarm.pm index cee6c1e63a..77ea26621b 100644 --- a/selftest/output/buildfarm.pm +++ b/selftest/output/buildfarm.pm @@ -1,4 +1,19 @@ #!/usr/bin/perl +# Buildfarm output for selftest +# Copyright (C) 2008 Jelmer Vernooij +# +# 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 . package output::buildfarm; diff --git a/selftest/output/html.pm b/selftest/output/html.pm index 1049527129..e490765d06 100644 --- a/selftest/output/html.pm +++ b/selftest/output/html.pm @@ -1,5 +1,19 @@ #!/usr/bin/perl - +# HTML output for selftest +# Copyright (C) 2008 Jelmer Vernooij +# +# 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 . package output::html; use Exporter; @ISA = qw(Exporter); diff --git a/selftest/output/plain.pm b/selftest/output/plain.pm index 82a73ab932..5312a9e27b 100644 --- a/selftest/output/plain.pm +++ b/selftest/output/plain.pm @@ -1,5 +1,19 @@ #!/usr/bin/perl - +# Plain text output for selftest +# Copyright (C) 2008 Jelmer Vernooij +# +# 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 . package output::plain; use Exporter; @ISA = qw(Exporter); diff --git a/selftest/selftest.pl b/selftest/selftest.pl index ef4c385d33..3653523541 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -2,7 +2,19 @@ # Bootstrap Samba and run a number of tests against it. # Copyright (C) 2005-2008 Jelmer Vernooij # Copyright (C) 2007-2009 Stefan Metzmacher -# Published under the GNU GPL, v3 or later. + +# 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 . =pod -- cgit From e3f7057b0942793543c215ab45176c4280bd7d51 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Mar 2009 15:58:20 +0100 Subject: s3-libnet: Fix Bug #6193: avoid messing with sync_context in libnet_samsync_delta(). We absolutely need to avoid messing with the sync_context as that breaks the stream of replication data coming from the DC (only replicates ~350 instead of ~4000 groups). Guenther --- source3/libnet/libnet_samsync.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c index 73d4439743..0c00b8518a 100644 --- a/source3/libnet/libnet_samsync.c +++ b/source3/libnet/libnet_samsync.c @@ -422,9 +422,6 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx, TALLOC_FREE(delta_enum_array); - /* Increment sync_context */ - sync_context += 1; - } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); out: -- cgit From 365b5cfcbeb041ce84718717f30ac02183c9af7f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Wed, 25 Mar 2009 12:53:06 -0700 Subject: Add missing newlines to debug statements --- source3/modules/onefs_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 5a488f894c..c23c176b79 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -208,14 +208,14 @@ static NTSTATUS onefs_open_file(files_struct *fsp, if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) != NO_OPLOCK) { DEBUG(0,("Oplock(%d) being requested on a stream! " - "Ignoring oplock request: base=%s, stream=%s", + "Ignoring oplock request: base=%s, stream=%s\n", oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK, base, stream)); /* Recover by requesting NO_OPLOCK instead. */ oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK; } - DEBUG(10,("Opening a stream: base=%s(%d), stream=%s", + DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n", base, fsp->base_fsp->fh->fd, stream)); base_fd = fsp->base_fsp->fh->fd; -- cgit From c42fc5e103d9d210c2f370e237a952e6df361792 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 25 Mar 2009 21:29:13 +0100 Subject: display_sec: Move to common libcli/security directory. --- libcli/security/config.mk | 2 +- libcli/security/display_sec.c | 322 ++++++++++++++++++++++++++++++++++++++ source3/Makefile.in | 2 +- source3/lib/display_sec.c | 317 ------------------------------------- source4/libcli/security/config.mk | 2 - 5 files changed, 324 insertions(+), 321 deletions(-) create mode 100644 libcli/security/display_sec.c delete mode 100644 source3/lib/display_sec.c diff --git a/libcli/security/config.mk b/libcli/security/config.mk index 56d8e138ff..7ade01510c 100644 --- a/libcli/security/config.mk +++ b/libcli/security/config.mk @@ -2,4 +2,4 @@ PRIVATE_DEPENDENCIES = TALLOC LIBSECURITY_COMMON_OBJ_FILES = $(addprefix $(libclicommonsrcdir)/security/, \ - dom_sid.o) + dom_sid.o display_sec.o secace.o secacl.o) diff --git a/libcli/security/display_sec.c b/libcli/security/display_sec.c new file mode 100644 index 0000000000..bec657da86 --- /dev/null +++ b/libcli/security/display_sec.c @@ -0,0 +1,322 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999 + + 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" +#include "librpc/gen_ndr/security.h" +#include "libcli/security/secace.h" +#include "libcli/security/dom_sid.h" +#include "librpc/ndr/libndr.h" + +/**************************************************************************** +convert a security permissions into a string +****************************************************************************/ + +char *get_sec_mask_str(TALLOC_CTX *ctx, uint32_t type) +{ + char *typestr = talloc_strdup(ctx, ""); + + if (!typestr) { + return NULL; + } + + if (type & SEC_GENERIC_ALL) { + typestr = talloc_asprintf_append(typestr, + "Generic all access "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_GENERIC_EXECUTE) { + typestr = talloc_asprintf_append(typestr, + "Generic execute access"); + if (!typestr) { + return NULL; + } + } + if (type & SEC_GENERIC_WRITE) { + typestr = talloc_asprintf_append(typestr, + "Generic write access "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_GENERIC_READ) { + typestr = talloc_asprintf_append(typestr, + "Generic read access "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_FLAG_MAXIMUM_ALLOWED) { + typestr = talloc_asprintf_append(typestr, + "MAXIMUM_ALLOWED_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_FLAG_SYSTEM_SECURITY) { + typestr = talloc_asprintf_append(typestr, + "SYSTEM_SECURITY_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_STD_SYNCHRONIZE) { + typestr = talloc_asprintf_append(typestr, + "SYNCHRONIZE_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_STD_WRITE_OWNER) { + typestr = talloc_asprintf_append(typestr, + "WRITE_OWNER_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_STD_WRITE_DAC) { + typestr = talloc_asprintf_append(typestr, + "WRITE_DAC_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_STD_READ_CONTROL) { + typestr = talloc_asprintf_append(typestr, + "READ_CONTROL_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SEC_STD_DELETE) { + typestr = talloc_asprintf_append(typestr, + "DELETE_ACCESS "); + if (!typestr) { + return NULL; + } + } + + printf("\t\tSpecific bits: 0x%lx\n", (unsigned long)type&SEC_MASK_SPECIFIC); + + return typestr; +} + +/**************************************************************************** + display sec_access structure + ****************************************************************************/ +void display_sec_access(uint32_t *info) +{ + char *mask_str = get_sec_mask_str(NULL, *info); + printf("\t\tPermissions: 0x%x: %s\n", *info, mask_str ? mask_str : ""); + talloc_free(mask_str); +} + +/**************************************************************************** + display sec_ace flags + ****************************************************************************/ +void display_sec_ace_flags(uint8_t flags) +{ + if (flags & SEC_ACE_FLAG_OBJECT_INHERIT) + printf("SEC_ACE_FLAG_OBJECT_INHERIT "); + if (flags & SEC_ACE_FLAG_CONTAINER_INHERIT) + printf(" SEC_ACE_FLAG_CONTAINER_INHERIT "); + if (flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) + printf("SEC_ACE_FLAG_NO_PROPAGATE_INHERIT "); + if (flags & SEC_ACE_FLAG_INHERIT_ONLY) + printf("SEC_ACE_FLAG_INHERIT_ONLY "); + if (flags & SEC_ACE_FLAG_INHERITED_ACE) + printf("SEC_ACE_FLAG_INHERITED_ACE "); +/* if (flags & SEC_ACE_FLAG_VALID_INHERIT) + printf("SEC_ACE_FLAG_VALID_INHERIT "); */ + if (flags & SEC_ACE_FLAG_SUCCESSFUL_ACCESS) + printf("SEC_ACE_FLAG_SUCCESSFUL_ACCESS "); + if (flags & SEC_ACE_FLAG_FAILED_ACCESS) + printf("SEC_ACE_FLAG_FAILED_ACCESS "); + + printf("\n"); +} + +/**************************************************************************** + display sec_ace object + ****************************************************************************/ +static void disp_sec_ace_object(struct security_ace_object *object) +{ + if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n"); + printf("Object GUID: %s\n", GUID_string(talloc_tos(), + &object->type.type)); + } + if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n"); + printf("Object GUID: %s\n", GUID_string(talloc_tos(), + &object->inherited_type.inherited_type)); + } +} + +/**************************************************************************** + display sec_ace structure + ****************************************************************************/ +void display_sec_ace(struct security_ace *ace) +{ + char *sid_str; + + printf("\tACE\n\t\ttype: "); + switch (ace->type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED: + printf("ACCESS ALLOWED"); + break; + case SEC_ACE_TYPE_ACCESS_DENIED: + printf("ACCESS DENIED"); + break; + case SEC_ACE_TYPE_SYSTEM_AUDIT: + printf("SYSTEM AUDIT"); + break; + case SEC_ACE_TYPE_SYSTEM_ALARM: + printf("SYSTEM ALARM"); + break; + case SEC_ACE_TYPE_ALLOWED_COMPOUND: + printf("SEC_ACE_TYPE_ALLOWED_COMPOUND"); + break; + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + printf("SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT"); + break; + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + printf("SEC_ACE_TYPE_ACCESS_DENIED_OBJECT"); + break; + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + printf("SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT"); + break; + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + printf("SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT"); + break; + default: + printf("????"); + break; + } + + printf(" (%d) flags: 0x%02x ", ace->type, ace->flags); + display_sec_ace_flags(ace->flags); + display_sec_access(&ace->access_mask); + sid_str = dom_sid_string(NULL, &ace->trustee); + printf("\t\tSID: %s\n\n", sid_str); + talloc_free(sid_str); + + if (sec_ace_object(ace->type)) { + disp_sec_ace_object(&ace->object.object); + } + +} + +/**************************************************************************** + display sec_acl structure + ****************************************************************************/ +void display_sec_acl(struct security_acl *sec_acl) +{ + int i; + + printf("\tACL\tNum ACEs:\t%d\trevision:\t%x\n", + sec_acl->num_aces, sec_acl->revision); + printf("\t---\n"); + + if (sec_acl->size != 0 && sec_acl->num_aces != 0) { + for (i = 0; i < sec_acl->num_aces; i++) { + display_sec_ace(&sec_acl->aces[i]); + } + } +} + +void display_acl_type(uint16_t type) +{ + printf("type: 0x%04x: ", type); + + if (type & SEC_DESC_OWNER_DEFAULTED) /* 0x0001 */ + printf("SEC_DESC_OWNER_DEFAULTED "); + if (type & SEC_DESC_GROUP_DEFAULTED) /* 0x0002 */ + printf("SEC_DESC_GROUP_DEFAULTED "); + if (type & SEC_DESC_DACL_PRESENT) /* 0x0004 */ + printf("SEC_DESC_DACL_PRESENT "); + if (type & SEC_DESC_DACL_DEFAULTED) /* 0x0008 */ + printf("SEC_DESC_DACL_DEFAULTED "); + if (type & SEC_DESC_SACL_PRESENT) /* 0x0010 */ + printf("SEC_DESC_SACL_PRESENT "); + if (type & SEC_DESC_SACL_DEFAULTED) /* 0x0020 */ + printf("SEC_DESC_SACL_DEFAULTED "); + if (type & SEC_DESC_DACL_TRUSTED) /* 0x0040 */ + printf("SEC_DESC_DACL_TRUSTED "); + if (type & SEC_DESC_SERVER_SECURITY) /* 0x0080 */ + printf("SEC_DESC_SERVER_SECURITY "); + if (type & SEC_DESC_DACL_AUTO_INHERIT_REQ) /* 0x0100 */ + printf("SEC_DESC_DACL_AUTO_INHERIT_REQ "); + if (type & SEC_DESC_SACL_AUTO_INHERIT_REQ) /* 0x0200 */ + printf("SEC_DESC_SACL_AUTO_INHERIT_REQ "); + if (type & SEC_DESC_DACL_AUTO_INHERITED) /* 0x0400 */ + printf("SEC_DESC_DACL_AUTO_INHERITED "); + if (type & SEC_DESC_SACL_AUTO_INHERITED) /* 0x0800 */ + printf("SEC_DESC_SACL_AUTO_INHERITED "); + if (type & SEC_DESC_DACL_PROTECTED) /* 0x1000 */ + printf("SEC_DESC_DACL_PROTECTED "); + if (type & SEC_DESC_SACL_PROTECTED) /* 0x2000 */ + printf("SEC_DESC_SACL_PROTECTED "); + if (type & SEC_DESC_RM_CONTROL_VALID) /* 0x4000 */ + printf("SEC_DESC_RM_CONTROL_VALID "); + if (type & SEC_DESC_SELF_RELATIVE) /* 0x8000 */ + printf("SEC_DESC_SELF_RELATIVE "); + + printf("\n"); +} + +/**************************************************************************** + display sec_desc structure + ****************************************************************************/ +void display_sec_desc(struct security_descriptor *sec) +{ + char *sid_str; + + if (!sec) { + printf("NULL\n"); + return; + } + + printf("revision: %d\n", sec->revision); + display_acl_type(sec->type); + + if (sec->sacl) { + printf("SACL\n"); + display_sec_acl(sec->sacl); + } + + if (sec->dacl) { + printf("DACL\n"); + display_sec_acl(sec->dacl); + } + + if (sec->owner_sid) { + sid_str = dom_sid_string(NULL, sec->owner_sid); + printf("\tOwner SID:\t%s\n", sid_str); + talloc_free(sid_str); + } + + if (sec->group_sid) { + sid_str = dom_sid_string(NULL, sec->group_sid); + printf("\tGroup SID:\t%s\n", sid_str); + talloc_free(sid_str); + } +} diff --git a/source3/Makefile.in b/source3/Makefile.in index ec52d85508..22911bf772 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -831,7 +831,7 @@ PDBEDIT_OBJ = utils/pdbedit.o $(PASSWD_UTIL_OBJ) $(PARAM_OBJ) $(PASSDB_OBJ) @LIB SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBWBCLIENT_STATIC@ -DISPLAY_SEC_OBJ= lib/display_sec.o +DISPLAY_SEC_OBJ= ../libcli/security/display_sec.o RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c deleted file mode 100644 index 6edbb27f3a..0000000000 --- a/source3/lib/display_sec.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Andrew Tridgell 1992-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999 - - 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" - -/**************************************************************************** -convert a security permissions into a string -****************************************************************************/ - -char *get_sec_mask_str(TALLOC_CTX *ctx, uint32_t type) -{ - char *typestr = talloc_strdup(ctx, ""); - - if (!typestr) { - return NULL; - } - - if (type & GENERIC_ALL_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "Generic all access "); - if (!typestr) { - return NULL; - } - } - if (type & GENERIC_EXECUTE_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "Generic execute access"); - if (!typestr) { - return NULL; - } - } - if (type & GENERIC_WRITE_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "Generic write access "); - if (!typestr) { - return NULL; - } - } - if (type & GENERIC_READ_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "Generic read access "); - if (!typestr) { - return NULL; - } - } - if (type & MAXIMUM_ALLOWED_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "MAXIMUM_ALLOWED_ACCESS "); - if (!typestr) { - return NULL; - } - } - if (type & SYSTEM_SECURITY_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "SYSTEM_SECURITY_ACCESS "); - if (!typestr) { - return NULL; - } - } - if (type & SYNCHRONIZE_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "SYNCHRONIZE_ACCESS "); - if (!typestr) { - return NULL; - } - } - if (type & WRITE_OWNER_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "WRITE_OWNER_ACCESS "); - if (!typestr) { - return NULL; - } - } - if (type & WRITE_DAC_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "WRITE_DAC_ACCESS "); - if (!typestr) { - return NULL; - } - } - if (type & READ_CONTROL_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "READ_CONTROL_ACCESS "); - if (!typestr) { - return NULL; - } - } - if (type & DELETE_ACCESS) { - typestr = talloc_asprintf_append(typestr, - "DELETE_ACCESS "); - if (!typestr) { - return NULL; - } - } - - printf("\t\tSpecific bits: 0x%lx\n", (unsigned long)type&SPECIFIC_RIGHTS_MASK); - - return typestr; -} - -/**************************************************************************** - display sec_access structure - ****************************************************************************/ -void display_sec_access(uint32_t *info) -{ - char *mask_str = get_sec_mask_str(NULL, *info); - printf("\t\tPermissions: 0x%x: %s\n", *info, mask_str ? mask_str : ""); - talloc_free(mask_str); -} - -/**************************************************************************** - display sec_ace flags - ****************************************************************************/ -void display_sec_ace_flags(uint8_t flags) -{ - if (flags & SEC_ACE_FLAG_OBJECT_INHERIT) - printf("SEC_ACE_FLAG_OBJECT_INHERIT "); - if (flags & SEC_ACE_FLAG_CONTAINER_INHERIT) - printf(" SEC_ACE_FLAG_CONTAINER_INHERIT "); - if (flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) - printf("SEC_ACE_FLAG_NO_PROPAGATE_INHERIT "); - if (flags & SEC_ACE_FLAG_INHERIT_ONLY) - printf("SEC_ACE_FLAG_INHERIT_ONLY "); - if (flags & SEC_ACE_FLAG_INHERITED_ACE) - printf("SEC_ACE_FLAG_INHERITED_ACE "); -/* if (flags & SEC_ACE_FLAG_VALID_INHERIT) - printf("SEC_ACE_FLAG_VALID_INHERIT "); */ - if (flags & SEC_ACE_FLAG_SUCCESSFUL_ACCESS) - printf("SEC_ACE_FLAG_SUCCESSFUL_ACCESS "); - if (flags & SEC_ACE_FLAG_FAILED_ACCESS) - printf("SEC_ACE_FLAG_FAILED_ACCESS "); - - printf("\n"); -} - -/**************************************************************************** - display sec_ace object - ****************************************************************************/ -static void disp_sec_ace_object(struct security_ace_object *object) -{ - if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n"); - printf("Object GUID: %s\n", GUID_string(talloc_tos(), - &object->type.type)); - } - if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { - printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n"); - printf("Object GUID: %s\n", GUID_string(talloc_tos(), - &object->inherited_type.inherited_type)); - } -} - -/**************************************************************************** - display sec_ace structure - ****************************************************************************/ -void display_sec_ace(SEC_ACE *ace) -{ - fstring sid_str; - - printf("\tACE\n\t\ttype: "); - switch (ace->type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED: - printf("ACCESS ALLOWED"); - break; - case SEC_ACE_TYPE_ACCESS_DENIED: - printf("ACCESS DENIED"); - break; - case SEC_ACE_TYPE_SYSTEM_AUDIT: - printf("SYSTEM AUDIT"); - break; - case SEC_ACE_TYPE_SYSTEM_ALARM: - printf("SYSTEM ALARM"); - break; - case SEC_ACE_TYPE_ALLOWED_COMPOUND: - printf("SEC_ACE_TYPE_ALLOWED_COMPOUND"); - break; - case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: - printf("SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT"); - break; - case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - printf("SEC_ACE_TYPE_ACCESS_DENIED_OBJECT"); - break; - case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: - printf("SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT"); - break; - case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: - printf("SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT"); - break; - default: - printf("????"); - break; - } - - printf(" (%d) flags: 0x%02x ", ace->type, ace->flags); - display_sec_ace_flags(ace->flags); - display_sec_access(&ace->access_mask); - sid_to_fstring(sid_str, &ace->trustee); - printf("\t\tSID: %s\n\n", sid_str); - - if (sec_ace_object(ace->type)) { - disp_sec_ace_object(&ace->object.object); - } - -} - -/**************************************************************************** - display sec_acl structure - ****************************************************************************/ -void display_sec_acl(SEC_ACL *sec_acl) -{ - int i; - - printf("\tACL\tNum ACEs:\t%d\trevision:\t%x\n", - sec_acl->num_aces, sec_acl->revision); - printf("\t---\n"); - - if (sec_acl->size != 0 && sec_acl->num_aces != 0) { - for (i = 0; i < sec_acl->num_aces; i++) { - display_sec_ace(&sec_acl->aces[i]); - } - } -} - -void display_acl_type(uint16_t type) -{ - fstring typestr=""; - - typestr[0] = 0; - - if (type & SEC_DESC_OWNER_DEFAULTED) /* 0x0001 */ - fstrcat(typestr, "SEC_DESC_OWNER_DEFAULTED "); - if (type & SEC_DESC_GROUP_DEFAULTED) /* 0x0002 */ - fstrcat(typestr, "SEC_DESC_GROUP_DEFAULTED "); - if (type & SEC_DESC_DACL_PRESENT) /* 0x0004 */ - fstrcat(typestr, "SEC_DESC_DACL_PRESENT "); - if (type & SEC_DESC_DACL_DEFAULTED) /* 0x0008 */ - fstrcat(typestr, "SEC_DESC_DACL_DEFAULTED "); - if (type & SEC_DESC_SACL_PRESENT) /* 0x0010 */ - fstrcat(typestr, "SEC_DESC_SACL_PRESENT "); - if (type & SEC_DESC_SACL_DEFAULTED) /* 0x0020 */ - fstrcat(typestr, "SEC_DESC_SACL_DEFAULTED "); - if (type & SEC_DESC_DACL_TRUSTED) /* 0x0040 */ - fstrcat(typestr, "SEC_DESC_DACL_TRUSTED "); - if (type & SEC_DESC_SERVER_SECURITY) /* 0x0080 */ - fstrcat(typestr, "SEC_DESC_SERVER_SECURITY "); - if (type & SEC_DESC_DACL_AUTO_INHERIT_REQ) /* 0x0100 */ - fstrcat(typestr, "SEC_DESC_DACL_AUTO_INHERIT_REQ "); - if (type & SEC_DESC_SACL_AUTO_INHERIT_REQ) /* 0x0200 */ - fstrcat(typestr, "SEC_DESC_SACL_AUTO_INHERIT_REQ "); - if (type & SEC_DESC_DACL_AUTO_INHERITED) /* 0x0400 */ - fstrcat(typestr, "SEC_DESC_DACL_AUTO_INHERITED "); - if (type & SEC_DESC_SACL_AUTO_INHERITED) /* 0x0800 */ - fstrcat(typestr, "SEC_DESC_SACL_AUTO_INHERITED "); - if (type & SEC_DESC_DACL_PROTECTED) /* 0x1000 */ - fstrcat(typestr, "SEC_DESC_DACL_PROTECTED "); - if (type & SEC_DESC_SACL_PROTECTED) /* 0x2000 */ - fstrcat(typestr, "SEC_DESC_SACL_PROTECTED "); - if (type & SEC_DESC_RM_CONTROL_VALID) /* 0x4000 */ - fstrcat(typestr, "SEC_DESC_RM_CONTROL_VALID "); - if (type & SEC_DESC_SELF_RELATIVE) /* 0x8000 */ - fstrcat(typestr, "SEC_DESC_SELF_RELATIVE "); - - printf("type: 0x%04x: %s\n", type, typestr); -} - -/**************************************************************************** - display sec_desc structure - ****************************************************************************/ -void display_sec_desc(SEC_DESC *sec) -{ - fstring sid_str; - - if (!sec) { - printf("NULL\n"); - return; - } - - printf("revision: %d\n", sec->revision); - display_acl_type(sec->type); - - if (sec->sacl) { - printf("SACL\n"); - display_sec_acl(sec->sacl); - } - - if (sec->dacl) { - printf("DACL\n"); - display_sec_acl(sec->dacl); - } - - if (sec->owner_sid) { - sid_to_fstring(sid_str, sec->owner_sid); - printf("\tOwner SID:\t%s\n", sid_str); - } - - if (sec->group_sid) { - sid_to_fstring(sid_str, sec->group_sid); - printf("\tGroup SID:\t%s\n", sid_str); - } -} diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index d6d9ad5545..9d23fe9588 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -4,7 +4,5 @@ PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY_COMMON LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ security_token.o security_descriptor.o \ access_check.o privilege.o sddl.o) \ - ../libcli/security/secace.o \ - ../libcli/security/secacl.o $(eval $(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c))) -- cgit From 8000479d181347bd6f248309168721fe3a20ad2a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Mar 2009 22:37:21 +0100 Subject: s3-registry: remove last sec_io_desc() caller. This is a temporary solution while waiting for the regf merge from s4. Guenther --- source3/registry/regfio.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index d002bd72e7..e1c04c4777 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -712,8 +712,30 @@ static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_ if ( !prs_uint32( "size", ps, depth, &sk->size)) return False; - if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth )) - return False; + { + NTSTATUS status; + TALLOC_CTX *mem_ctx = prs_get_mem_context(&hbin->ps); + DATA_BLOB blob; + + if (MARSHALLING(&hbin->ps)) { + status = marshall_sec_desc(mem_ctx, + sk->sec_desc, + &blob.data, &blob.length); + if (!NT_STATUS_IS_OK(status)) + return False; + if (!prs_copy_data_in(&hbin->ps, (const char *)blob.data, blob.length)) + return False; + } else { + blob = data_blob_const(prs_data_p(&hbin->ps), + prs_data_size(&hbin->ps)); + status = unmarshall_sec_desc(mem_ctx, + blob.data, blob.length, + &sk->sec_desc); + if (!NT_STATUS_IS_OK(status)) + return False; + prs_set_offset(&hbin->ps, blob.length); + } + } end_off = prs_offset( &hbin->ps ); -- cgit From 72636db8e5f06e887db6c34b6f88bef567c093dd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Mar 2009 22:38:58 +0100 Subject: s3: remove unused rpc_parse/parse_sec.c file. Guenther --- source3/Makefile.in | 2 +- source3/include/proto.h | 5 - source3/rpc_parse/parse_sec.c | 436 ------------------------------------------ 3 files changed, 1 insertion(+), 442 deletions(-) delete mode 100644 source3/rpc_parse/parse_sec.c diff --git a/source3/Makefile.in b/source3/Makefile.in index ec52d85508..6cdcdff822 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -319,7 +319,7 @@ RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o # this includes only the low level parse code, not stuff # that requires knowledge of security contexts -RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) rpc_parse/parse_sec.o +RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o \ rpc_client/init_netlogon.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 3b4b1cf3f1..358593b3e8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5818,11 +5818,6 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len, RPC_AUTH_SCHANNEL_CHK * chk, prs_struct *ps, int depth); -/* The following definitions come from rpc_parse/parse_sec.c */ - -bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth); -bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth); - /* The following definitions come from rpc_server/srv_eventlog_lib.c */ TDB_CONTEXT *elog_init_tdb( char *tdbfilename ); diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c deleted file mode 100644 index 91d8591a05..0000000000 --- a/source3/rpc_parse/parse_sec.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1998, - * Copyright (C) Jeremy R. Allison 1995-2005. - * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998. - * - * 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_PARSE - -/******************************************************************* - Reads or writes a SEC_ACE structure. -********************************************************************/ - -static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, - int depth) -{ - uint32 old_offset; - uint32 offset_ace_size; - uint8 type; - - if (psa == NULL) - return False; - - prs_debug(ps, depth, desc, "sec_io_ace"); - depth++; - - old_offset = prs_offset(ps); - - if (MARSHALLING(ps)) { - type = (uint8)psa->type; - } - - if(!prs_uint8("type ", ps, depth, &type)) - return False; - - if (UNMARSHALLING(ps)) { - psa->type = (enum security_ace_type)type; - } - - if(!prs_uint8("flags", ps, depth, &psa->flags)) - return False; - - if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size)) - return False; - - if(!prs_uint32("access_mask", ps, depth, &psa->access_mask)) - return False; - - /* check whether object access is present */ - if (!sec_ace_object(psa->type)) { - if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) - return False; - } else { - if (!prs_uint32("obj_flags", ps, depth, &psa->object.object.flags)) - return False; - - if (psa->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) - if (!smb_io_uuid("obj_guid", &psa->object.object.type.type, ps,depth)) - return False; - - if (psa->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) - if (!smb_io_uuid("inh_guid", &psa->object.object.inherited_type.inherited_type, ps,depth)) - return False; - - if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) - return False; - } - - /* Theorectically an ACE can have a size greater than the - sum of its components. When marshalling, pad with extra null bytes up to the - correct size. */ - - if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) { - uint32 extra_len = psa->size - (prs_offset(ps) - old_offset); - uint32 i; - uint8 c = 0; - - for (i = 0; i < extra_len; i++) { - if (!prs_uint8("ace extra space", ps, depth, &c)) - return False; - } - } - - if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SEC_ACL structure. - - First of the xx_io_xx functions that allocates its data structures - for you as it reads them. -********************************************************************/ - -static bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, - int depth) -{ - unsigned int i; - uint32 old_offset; - uint32 offset_acl_size; - SEC_ACL *psa; - uint16 revision; - - /* - * Note that the size is always a multiple of 4 bytes due to the - * nature of the data structure. Therefore the prs_align() calls - * have been removed as they through us off when doing two-layer - * marshalling such as in the printing code (RPC_BUFFER). --jerry - */ - - if (ppsa == NULL) - return False; - - psa = *ppsa; - - if(UNMARSHALLING(ps) && psa == NULL) { - /* - * This is a read and we must allocate the stuct to read into. - */ - if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL) - return False; - *ppsa = psa; - } - - prs_debug(ps, depth, desc, "sec_io_acl"); - depth++; - - old_offset = prs_offset(ps); - - if (MARSHALLING(ps)) { - revision = (uint16)psa->revision; - } - - if(!prs_uint16("revision", ps, depth, &revision)) - return False; - - if (UNMARSHALLING(ps)) { - psa->revision = (enum security_acl_revision)revision; - } - - if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size)) - return False; - - if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces)) - return False; - - if (UNMARSHALLING(ps)) { - if (psa->num_aces) { - if((psa->aces = PRS_ALLOC_MEM(ps, SEC_ACE, psa->num_aces)) == NULL) - return False; - } else { - psa->aces = NULL; - } - } - - for (i = 0; i < psa->num_aces; i++) { - fstring tmp; - slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i); - if(!sec_io_ace(tmp, &psa->aces[i], ps, depth)) - return False; - } - - /* Theorectically an ACL can have a size greater than the - sum of its components. When marshalling, pad with extra null bytes up to the - correct size. */ - - if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) { - uint32 extra_len = psa->size - (prs_offset(ps) - old_offset); - uint8 c = 0; - - for (i = 0; i < extra_len; i++) { - if (!prs_uint8("acl extra space", ps, depth, &c)) - return False; - } - } - - if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SEC_DESC structure. - If reading and the *ppsd = NULL, allocates the structure. -********************************************************************/ - -bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) -{ - uint32 old_offset; - uint32 max_offset = 0; /* after we're done, move offset to end */ - uint32 tmp_offset = 0; - uint32 off_sacl, off_dacl, off_owner_sid, off_grp_sid; - uint16 revision; - - SEC_DESC *psd; - - if (ppsd == NULL) - return False; - - psd = *ppsd; - - if (psd == NULL) { - if(UNMARSHALLING(ps)) { - if((psd = PRS_ALLOC_MEM(ps,SEC_DESC,1)) == NULL) - return False; - *ppsd = psd; - } else { - /* Marshalling - just ignore. */ - return True; - } - } - - prs_debug(ps, depth, desc, "sec_io_desc"); - depth++; - - /* start of security descriptor stored for back-calc offset purposes */ - old_offset = prs_offset(ps); - - if (MARSHALLING(ps)) { - revision = (uint16)psd->revision; - } - - if(!prs_uint16("revision", ps, depth, &revision)) - return False; - - if (UNMARSHALLING(ps)) { - psd->revision = (enum security_descriptor_revision)revision; - } - - if(!prs_uint16("type ", ps, depth, &psd->type)) - return False; - - if (MARSHALLING(ps)) { - uint32 offset = SEC_DESC_HEADER_SIZE; - - /* - * Work out the offsets here, as we write it out. - */ - - if (psd->sacl != NULL) { - off_sacl = offset; - offset += psd->sacl->size; - } else { - off_sacl = 0; - } - - if (psd->dacl != NULL) { - off_dacl = offset; - offset += psd->dacl->size; - } else { - off_dacl = 0; - } - - if (psd->owner_sid != NULL) { - off_owner_sid = offset; - offset += ndr_size_dom_sid(psd->owner_sid, NULL, 0); - } else { - off_owner_sid = 0; - } - - if (psd->group_sid != NULL) { - off_grp_sid = offset; - offset += ndr_size_dom_sid(psd->group_sid, NULL, 0); - } else { - off_grp_sid = 0; - } - } - - if(!prs_uint32("off_owner_sid", ps, depth, &off_owner_sid)) - return False; - - if(!prs_uint32("off_grp_sid ", ps, depth, &off_grp_sid)) - return False; - - if(!prs_uint32("off_sacl ", ps, depth, &off_sacl)) - return False; - - if(!prs_uint32("off_dacl ", ps, depth, &off_dacl)) - return False; - - max_offset = MAX(max_offset, prs_offset(ps)); - - if (off_owner_sid != 0) { - - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_owner_sid)) - return False; - - if (UNMARSHALLING(ps)) { - /* reading */ - if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL) - return False; - } - - if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth)) - return False; - - max_offset = MAX(max_offset, prs_offset(ps)); - - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if (psd->group_sid != 0) { - - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_grp_sid)) - return False; - - if (UNMARSHALLING(ps)) { - /* reading */ - if((psd->group_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL) - return False; - } - - if(!smb_io_dom_sid("grp_sid", psd->group_sid, ps, depth)) - return False; - - max_offset = MAX(max_offset, prs_offset(ps)); - - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if ((psd->type & SEC_DESC_SACL_PRESENT) && off_sacl) { - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_sacl)) - return False; - if(!sec_io_acl("sacl", &psd->sacl, ps, depth)) - return False; - max_offset = MAX(max_offset, prs_offset(ps)); - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if ((psd->type & SEC_DESC_DACL_PRESENT) && off_dacl != 0) { - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_dacl)) - return False; - if(!sec_io_acl("dacl", &psd->dacl, ps, depth)) - return False; - max_offset = MAX(max_offset, prs_offset(ps)); - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if(!prs_set_offset(ps, max_offset)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SEC_DESC_BUF structure. -********************************************************************/ - -bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth) -{ - uint32 off_len; - uint32 off_max_len; - uint32 old_offset; - uint32 size; - uint32 len; - SEC_DESC_BUF *psdb; - uint32 ptr; - - if (ppsdb == NULL) - return False; - - psdb = *ppsdb; - - if (UNMARSHALLING(ps) && psdb == NULL) { - if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL) - return False; - *ppsdb = psdb; - } - - prs_debug(ps, depth, desc, "sec_io_desc_buf"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32_pre("max_len", ps, depth, &psdb->sd_size, &off_max_len)) - return False; - - ptr = 1; - if(!prs_uint32 ("ptr ", ps, depth, &ptr)) - return False; - - len = ndr_size_security_descriptor(psdb->sd, NULL, 0); - if(!prs_uint32_pre("len ", ps, depth, &len, &off_len)) - return False; - - old_offset = prs_offset(ps); - - /* reading, length is non-zero; writing, descriptor is non-NULL */ - if ((UNMARSHALLING(ps) && psdb->sd_size != 0) || (MARSHALLING(ps) && psdb->sd != NULL)) { - if(!sec_io_desc("sec ", &psdb->sd, ps, depth)) - return False; - } - - if(!prs_align(ps)) - return False; - - size = prs_offset(ps) - old_offset; - if(!prs_uint32_post("max_len", ps, depth, &psdb->sd_size, off_max_len, size == 0 ? psdb->sd_size : size)) - return False; - - if(!prs_uint32_post("len ", ps, depth, &len, off_len, size)) - return False; - - return True; -} -- cgit From c86df62b4a51b2813104aece8b3813b1806aeb22 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Mar 2009 23:09:52 +0100 Subject: s3-rpc_parse: remove unused smb_io_domsid(). Guenther --- source3/include/proto.h | 1 - source3/rpc_parse/parse_misc.c | 38 -------------------------------------- 2 files changed, 39 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 358593b3e8..d619c3ba00 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5693,7 +5693,6 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth); bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth); bool smb_io_uuid(const char *desc, struct GUID *uuid, prs_struct *ps, int depth); void init_unistr(UNISTR *str, const char *buf); diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 8b4135a1e8..ffbd67befe 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -100,44 +100,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) return True; } -/******************************************************************* - Reads or writes a DOM_SID structure. -********************************************************************/ - -bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth) -{ - int i; - - if (sid == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_dom_sid"); - depth++; - - if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num)) - return False; - - if(!prs_uint8 ("num_auths ", ps, depth, (uint8 *)&sid->num_auths)) - return False; - - for (i = 0; i < 6; i++) - { - fstring tmp; - slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i); - if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i])) - return False; - } - - /* oops! XXXX should really issue a warning here... */ - if (sid->num_auths > MAXSUBAUTHS) - sid->num_auths = MAXSUBAUTHS; - - if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths)) - return False; - - return True; -} - /******************************************************************* Reads or writes a struct GUID ********************************************************************/ -- cgit From 39e6bd5b296b39c16d65e62801898e278eff49aa Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 19:35:53 +0100 Subject: s3/pam_smbpass: don't link agains KRB5LIBS pam_smbpass doesn't use the krb5 stuff Signed-off-by: Michael Adam --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 6cdcdff822..93617f05e4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -2661,7 +2661,7 @@ bin/ntlm_auth@EXEEXT@: $(BINARY_PREREQS) $(NTLM_AUTH_OBJ) $(PARAM_OBJ) \ bin/pam_smbpass.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_SMBPASS_OBJ) @LIBTALLOC_SHARED@ @LIBWBCLIENT_SHARED@ @LIBTDB_SHARED@ @echo "Linking shared library $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_OBJ) -lpam $(DYNEXP) \ - $(LIBS) $(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \ + $(LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) bin/tdbbackup@EXEEXT@: $(BINARY_PREREQS) $(TDBBACKUP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ -- cgit From 1f265548e7d17a4ed83705149dd944fcdd31134d Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 19:25:42 +0100 Subject: s3/smbd: don't link against zlib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit smbd doesn't use any zlib symbolѕ Signed-off-by: Michael Adam --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 93617f05e4..575e80c8ad 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1396,7 +1396,7 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \ $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ - $(WINBIND_LIBS) $(ZLIB_LIBS) + $(WINBIND_LIBS) bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ -- cgit From 8532faffd08bbbcfaac60fd866fa5ab255913d4a Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 19:24:35 +0100 Subject: s3/swat: don't link against zlib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit swat doesn't use any zlib symbolѕ Signed-off-by: Michael Adam --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 575e80c8ad..e60a74f3ea 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1408,7 +1408,7 @@ bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @echo Linking $@ @$(CC) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \ $(AUTH_LIBS) $(LIBS) $(PASSDB_LIBS) $(POPT_LIBS) $(KRB5LIBS) \ - $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS) + $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ -- cgit From 9e62b7f7bb60a1325b3cb0a1e2c4d6931ff93eaf Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 19:14:45 +0100 Subject: s3/cifs: don't link cifs mount helpers agains popt the mount helpers don't use any popt symbols Signed-off-by: Michael Adam --- source3/Makefile.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index e60a74f3ea..0d556c0c3c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1442,19 +1442,19 @@ bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHAR @$(CC) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) -bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @BUILD_POPT@ +bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @echo Linking $@ - @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS) + @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) -bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @BUILD_POPT@ +bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @echo Linking $@ - @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS) + @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) -bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ +bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \ -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \ - $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \ + $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \ $(LIBTDB_LIBS) $(NSCD_LIBS) bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ -- cgit From b574a09cf54b4ea5a7e0575848725bd6452d2b4d Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 23 Mar 2009 18:22:45 +0100 Subject: s3/ldbtools: don't neddlessly link against wbinbind libs Signed-off-by: Michael Adam --- source3/Makefile.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 0d556c0c3c..4ea043a046 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1618,37 +1618,37 @@ bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @L @echo Linking $@ @$(CC) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbsearch: $(BINARY_PREREQS) $(LDBSEARCH_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbadd: $(BINARY_PREREQS) $(LDBADD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBADD_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbmodify: $(BINARY_PREREQS) $(LDBMODIFY_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBMODIFY_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBDEL_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDBRENAME_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/versiontest: $(BINARY_PREREQS) lib/version_test.o $(VERSION_OBJ) @echo Linking $@ -- cgit From 04eeae74e63f2831d87a5e4e3c16d152e924c8dd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Mar 2009 01:25:40 +0100 Subject: Revert "s3/smbd: don't link against zlib" This reverts commit 1f265548e7d17a4ed83705149dd944fcdd31134d. smbd needs zlib through ../librpc/ndr/ndr_compression.c, function ndr_pull_compression_mszip_chunk(). This fails to link at least on our build farm bsd boxes. Michael --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 4ea043a046..bd17dcb629 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1396,7 +1396,7 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \ $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ - $(WINBIND_LIBS) + $(WINBIND_LIBS) $(ZLIB_LIBS) bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ -- cgit From 5adeaea664b016225518a465e3fc2ed4b8cce098 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Mar 2009 01:30:00 +0100 Subject: Revert "s3/swat: don't link against zlib" This reverts commit 8532faffd08bbbcfaac60fd866fa5ab255913d4a. swat needs zlib through ../librpc/ndr/ndr_compression.c, function ndr_pull_compression_mszip_chunk(). This fails to link at least on our build farm bsd boxes. Michael --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index bd17dcb629..1c9c0c1204 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1408,7 +1408,7 @@ bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @echo Linking $@ @$(CC) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \ $(AUTH_LIBS) $(LIBS) $(PASSDB_LIBS) $(POPT_LIBS) $(KRB5LIBS) \ - $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS) bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ -- cgit From 202228d48b6459148d328840d23322ecfac00626 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Mar 2009 21:48:37 -0700 Subject: Ensure we never enter VFS_CREATE without having initialized sbuf as invalid (if not already read via stat()). Still trying to find the build farm RAW-STREAM errors and it's happening in a openX call.... Jeremy. --- source3/smbd/nttrans.c | 4 ++++ source3/smbd/reply.c | 6 ++++++ source3/smbd/trans2.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 628fc1bd32..7e75eea6b4 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -441,6 +441,8 @@ void reply_ntcreate_and_X(struct smb_request *req) START_PROFILE(SMBntcreateX); + SET_STAT_INVALID(sbuf); + if (req->wct < 24) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; @@ -865,6 +867,8 @@ static void call_nt_transact_create(connection_struct *conn, uint8_t oplock_granted; TALLOC_CTX *ctx = talloc_tos(); + SET_STAT_INVALID(sbuf); + DEBUG(5,("call_nt_transact_create\n")); /* diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 6f19a58178..16eb4a7fd7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1606,6 +1606,8 @@ void reply_open(struct smb_request *req) START_PROFILE(SMBopen); + SET_STAT_INVALID(sbuf); + if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBopen); @@ -1741,6 +1743,8 @@ void reply_open_and_X(struct smb_request *req) return; } + SET_STAT_INVALID(sbuf); + open_flags = SVAL(req->vwv+2, 0); deny_mode = SVAL(req->vwv+3, 0); smb_attr = SVAL(req->vwv+5, 0); @@ -1945,6 +1949,7 @@ void reply_mknew(struct smb_request *req) START_PROFILE(SMBcreate); ZERO_STRUCT(ft); + SET_STAT_INVALID(sbuf); if (req->wct < 3) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -2123,6 +2128,7 @@ void reply_ctemp(struct smb_request *req) return; } + SET_STAT_INVALID(sbuf); SMB_VFS_STAT(conn,fname,&sbuf); /* We should fail if file does not exist. */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index df01a39893..04b1145e58 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -895,6 +895,8 @@ static void call_trans2open(connection_struct *conn, uint32 create_options = 0; TALLOC_CTX *ctx = talloc_tos(); + SET_STAT_INVALID(sbuf); + /* * Ensure we have enough parameters to perform the operation. */ -- cgit From a20a710c944055932402ec5dfe3a36ac3d654cbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Mar 2009 10:03:59 +0100 Subject: Avahi disables a timer by tv=NULL in avahi_timeout_update(), do not crash --- source3/lib/avahi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/lib/avahi.c b/source3/lib/avahi.c index ac9867a1fc..269b329e64 100644 --- a/source3/lib/avahi.c +++ b/source3/lib/avahi.c @@ -207,6 +207,13 @@ static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv) { TALLOC_FREE(t->te); + if (tv == NULL) { + /* + * Disable this timer + */ + return; + } + t->te = tevent_add_timer(t->ctx->ev, t, *tv, avahi_timeout_handler, t); /* * No failure mode defined here -- cgit From 24d5229a81e1067662930d42f8c59b3a0adac1e0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Mar 2009 10:11:59 +0100 Subject: s3-net: Fix Bug #6102. NetQueryDisplayInformation could return wrong information. Guenther --- source3/lib/netapi/user.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index e760a8b1de..1cbb883169 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -1497,6 +1497,9 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx, NTSTATUS status = NT_STATUS_OK; WERROR werr; + WERROR werr_tmp; + + *r->out.entries_read = 0; ZERO_STRUCT(connect_handle); ZERO_STRUCT(domain_handle); @@ -1540,15 +1543,18 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx, &total_size, &returned_size, &info); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); + werr = ntstatus_to_werror(status); + if (NT_STATUS_IS_ERR(status)) { goto done; } - werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info, - r->in.level, - r->out.entries_read, - r->out.buffer); + werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info, + r->in.level, + r->out.entries_read, + r->out.buffer); + if (!W_ERROR_IS_OK(werr_tmp)) { + werr = werr_tmp; + } done: /* if last query */ if (NT_STATUS_IS_OK(status) || -- cgit From fe340eb92fd2e5dfef977dc391d2a43ce970e0ea Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Mar 2009 23:23:06 +0100 Subject: s3:rpc_parse: remove unused init_unistr(). Guenther --- source3/include/proto.h | 1 - source3/rpc_parse/parse_misc.c | 19 ------------------- source3/utils/net_rpc_printer.c | 9 ++++----- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d619c3ba00..77be0aba09 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5695,7 +5695,6 @@ bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); bool smb_io_uuid(const char *desc, struct GUID *uuid, prs_struct *ps, int depth); -void init_unistr(UNISTR *str, const char *buf); void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags); /* The following definitions come from rpc_parse/parse_prs.c */ diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index ffbd67befe..1ea4ecf46f 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -128,25 +128,6 @@ bool smb_io_uuid(const char *desc, struct GUID *uuid, return True; } -/******************************************************************* - Inits a UNISTR structure. -********************************************************************/ - -void init_unistr(UNISTR *str, const char *buf) -{ - size_t len; - - if (buf == NULL) { - str->buffer = NULL; - return; - } - - len = rpcstr_push_talloc(talloc_tos(), &str->buffer, buf); - if (len == (size_t)-1) { - str->buffer = NULL; - } -} - /******************************************************************* Inits a UNISTR2 structure. ********************************************************************/ diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 1d0e9a38be..9721628f02 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -2260,14 +2260,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, info_dst.info2.secdesc = NULL; #if 0 - if (asprintf(&devicename, "\\\\%s\\%s", longname, - printername) < 0) { + info_dst.info2.devmode.devicename = + talloc_asprintf(mem_ctx, "\\\\%s\\%s", + longname, printername); + if (!info_dst.info2.devmode.devicename) { nt_status = NT_STATUS_NO_MEMORY; goto done; } - - init_unistr(&ctr_dst.printers_2->devmode->devicename, - devicename); #endif if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) -- cgit From 56d74b62126083dd7e2a60d1b48b03e1b1798c90 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Mar 2009 10:26:59 +0100 Subject: s3-libnetapi: fix creds in libnetapi_open_ipc_connection(). Jeremy, this broke with 8dd1faaa2992851f6852ba7ea4498445af5faadd. Not sure if other users broke as well with that change. Guenther --- source3/lib/netapi/cm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index b676ae63dd..d28b2b2126 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -57,6 +57,11 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, false, false, PROTOCOL_NT1, 0, 0x20); + if (cli_ipc) { + cli_set_username(cli_ipc, ctx->username); + cli_set_password(cli_ipc, ctx->password); + cli_set_domain(cli_ipc, ctx->workgroup); + } TALLOC_FREE(auth_info); if (!cli_ipc) { -- cgit From 3f37342bc0e7c26b6a61490706fe8cec3e6d491e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 26 Mar 2009 22:10:02 +1100 Subject: fixed possibleinferiors.py so it matches windows behaviour This test code builds the possibleInferiors for every class in the schema on a target machine, and compares it to the servers possibleInferiors attribute. The MS-ADTS spec describes how to calculate possibleInferiors for a object, but it seems to have some bugs. The spec says that we need to use AUXCLASSES, and it does not mention the use of the SUBCLASS tree. In trying to match windows behaviour, I found that I needed to ignore the AUXCLASSES and build a SUBCLASSES tree. --- .../samdb/ldb_modules/tests/possibleinferiors.py | 166 ++++++++++++++++----- 1 file changed, 127 insertions(+), 39 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py index 0e74456dac..ec426c099b 100755 --- a/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py +++ b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py @@ -71,7 +71,7 @@ schema_base = rootDse["schemaNamingContext"][0] def possible_inferiors_search(db, oc): """return the possible inferiors via a search for the possibleInferiors attribute""" res = db.search(base=schema_base, - expression=("ldapdisplayname=%s" % oc), + expression=("ldapDisplayName=%s" % oc), attrs=["possibleInferiors"]) poss=[] @@ -86,47 +86,137 @@ def possible_inferiors_search(db, oc): # see [MS-ADTS] section 3.1.1.4.5.21 -# for this algorithm +# and section 3.1.1.4.2 for this algorithm # !systemOnly=TRUE # !objectClassCategory=2 # !objectClassCategory=3 -def POSSINFERIORS(db, oc): - """returns a list of possible inferiors to a class. Returned list has the ldapdisplayname, systemOnly and objectClassCategory for each element""" - expanded = [oc] - res = db.search(base=schema_base, - expression=("subclassof=%s" % str(oc["ldapdisplayname"][0])), - attrs=["ldapdisplayname", "systemOnly", "objectClassCategory"]) +def SUPCLASSES(classinfo, oc): + list = [] + if oc == "top": + return list + if classinfo[oc].get("SUPCLASSES") is not None: + return classinfo[oc]["SUPCLASSES"] + res = classinfo[oc]["subClassOf"]; for r in res: - expanded.extend(POSSINFERIORS(db,r)) - return expanded + list.append(r) + list.extend(SUPCLASSES(classinfo,r)) + classinfo[oc]["SUPCLASSES"] = list + return list -def possible_inferiors_constructed(db, oc): - """return the possbible inferiors via a recursive search and match""" - res = db.search(base=schema_base, - expression=("(&(objectclass=classSchema)(|(posssuperiors=%s)(systemposssuperiors=%s)))" % (oc,oc)), - attrs=["ldapdisplayname", "systemOnly", "objectClassCategory"]) +def AUXCLASSES(classinfo, oclist): + list = [] + if oclist == []: + return list + for oc in oclist: + if classinfo[oc].get("AUXCLASSES") is not None: + list.extend(classinfo[oc]["AUXCLASSES"]) + else: + list2 = [] + list2.extend(classinfo[oc]["systemAuxiliaryClass"]) + list2.extend(AUXCLASSES(classinfo, classinfo[oc]["systemAuxiliaryClass"])) + list2.extend(classinfo[oc]["auxiliaryClass"]) + list2.extend(AUXCLASSES(classinfo, classinfo[oc]["auxiliaryClass"])) + list2.extend(AUXCLASSES(classinfo, SUPCLASSES(classinfo, oc))) + classinfo[oc]["AUXCLASSES"] = list2 + list.extend(list2) + return list - poss = [] +def SUBCLASSES(classinfo, oclist): + list = [] + for oc in oclist: + list.extend(classinfo[oc]["SUBCLASSES"]) + return list + +def POSSSUPERIORS(classinfo, oclist): + list = [] + for oc in oclist: + if classinfo[oc].get("POSSSUPERIORS") is not None: + list.extend(classinfo[oc]["POSSSUPERIORS"]) + else: + list2 = [] + list2.extend(classinfo[oc]["systemPossSuperiors"]) + list2.extend(classinfo[oc]["possSuperiors"]) + list2.extend(POSSSUPERIORS(classinfo, SUPCLASSES(classinfo, oc))) + # the WSPP docs suggest we should do this: + # list2.extend(POSSSUPERIORS(classinfo, AUXCLASSES(classinfo, [oc]))) + # but testing against w2k3 and w2k8 shows that we need to do this instead + list2.extend(SUBCLASSES(classinfo, list2)) + classinfo[oc]["POSSSUPERIORS"] = list2 + list.extend(list2) + return list + +def pull_classinfo(db): + """At startup we build a classinfo[] dictionary that holds all the information needed to construct the possible inferiors""" + classinfo = {} + res = db.search(base=schema_base, + expression="objectclass=classSchema", + attrs=["ldapDisplayName", "systemOnly", "objectClassCategory", + "possSuperiors", "systemPossSuperiors", + "auxiliaryClass", "systemAuxiliaryClass", "subClassOf"]) for r in res: - poss.extend(POSSINFERIORS(db,r)) - - poss2 = [] - for p in poss: - if (not (p["systemOnly"][0] == "TRUE" or - int(p["objectClassCategory"][0]) == 2 or - int(p["objectClassCategory"][0]) == 3)): - poss2.append(p["ldapdisplayname"][0]) - - poss2 = uniq_list(poss2) - poss2.sort() - return poss2 - -def test_class(db, oc): + name = str(r["ldapDisplayName"][0]) + classinfo[name] = {} + if str(r["systemOnly"]) == "TRUE": + classinfo[name]["systemOnly"] = True + else: + classinfo[name]["systemOnly"] = False + if r.get("objectClassCategory"): + classinfo[name]["objectClassCategory"] = int(r["objectClassCategory"][0]) + else: + classinfo[name]["objectClassCategory"] = 0 + for a in [ "possSuperiors", "systemPossSuperiors", + "auxiliaryClass", "systemAuxiliaryClass", + "subClassOf" ]: + classinfo[name][a] = [] + if r.get(a): + for i in r[a]: + classinfo[name][a].append(str(i)) + + # build a list of subclasses for each class + def subclasses_recurse(subclasses, oc): + list = subclasses[oc] + for c in list: + list.extend(subclasses_recurse(subclasses, c)) + return list + + subclasses = {} + for oc in classinfo: + subclasses[oc] = [] + for oc in classinfo: + for c in classinfo[oc]["subClassOf"]: + if not c == oc: + subclasses[c].append(oc) + for oc in classinfo: + classinfo[oc]["SUBCLASSES"] = uniq_list(subclasses_recurse(subclasses, oc)) + + return classinfo + +def is_in_list(list, c): + for a in list: + if c == a: + return True + return False + +def possible_inferiors_constructed(db, classinfo, c): + list = [] + for oc in classinfo: + superiors = POSSSUPERIORS(classinfo, [oc]) + if (is_in_list(superiors, c) and + classinfo[oc]["systemOnly"] == False and + classinfo[oc]["objectClassCategory"] != 2 and + classinfo[oc]["objectClassCategory"] != 3): + list.append(oc) + list = uniq_list(list) + list.sort() + return list + +def test_class(db, classinfo, oc): """test to see if one objectclass returns the correct possibleInferiors""" + print "testing objectClass %s" % oc poss1 = possible_inferiors_search(db, oc) - poss2 = possible_inferiors_constructed(db, oc) + poss2 = possible_inferiors_constructed(db, classinfo, oc) if poss1 != poss2: print "Returned incorrect list for objectclass %s" % oc print poss1 @@ -137,19 +227,17 @@ def test_class(db, oc): def get_object_classes(db): """return a list of all object classes""" - res = db.search(base=schema_base, - expression="objectClass=classSchema", - attrs=["ldapdisplayname"]) list=[] - for item in res: - list.append(item["ldapdisplayname"][0]) + for item in classinfo: + list.append(item) return list +classinfo = pull_classinfo(db) + if objectclass is None: for oc in get_object_classes(db): - print "testing objectClass %s" % oc - test_class(db,oc) + test_class(db,classinfo,oc) else: - test_class(db,objectclass) + test_class(db,classinfo,objectclass) print "Lists match OK" -- cgit From c164c0c20ac0420878a9f7aba6503d3deb8e53d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Mar 2009 12:24:50 +0100 Subject: Fix a scary "fill_share_mode_lock failed" message To me "fill_share_mode_lock failed" is a "can't happen" alert. There is however a perfectly valid case in get_file_infos() when the file is not open. Change the corresponding debug message to level 10 and explain more. --- source3/locking/locking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bafb89522a..70841225a7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -887,7 +887,8 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, } if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) { - DEBUG(3, ("fill_share_mode_lock failed\n")); + DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record " + "around (file not open)\n")); TALLOC_FREE(lck); return NULL; } -- cgit From 5603c0f2ba9d5b90e5f8b71e779ec037053f04f8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Mar 2009 14:51:04 +0100 Subject: error-codes: add WERR_DS_DRA_SOURCE_DISABLED. Guenther --- libcli/util/doserr.c | 1 + libcli/util/werror.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c index 5104c3ee02..1a7422e3f6 100644 --- a/libcli/util/doserr.c +++ b/libcli/util/doserr.c @@ -124,6 +124,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, { "WERR_DS_DRA_ACCESS_DENIED", WERR_DS_DRA_ACCESS_DENIED }, + { "WERR_DS_DRA_SOURCE_DISABLED", WERR_DS_DRA_SOURCE_DISABLED }, { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE }, { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, { "WERR_DS_NO_MSDS_INTID", WERR_DS_NO_MSDS_INTID }, diff --git a/libcli/util/werror.h b/libcli/util/werror.h index d92232706a..a69587f361 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -248,6 +248,7 @@ typedef uint32_t WERROR; #define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) #define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) #define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105) +#define WERR_DS_DRA_SOURCE_DISABLED W_ERROR(0x00002108) #define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) #define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) #define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194) -- cgit From 2d087a0c156dc95086a39e297b24ef6889e1a50d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Mar 2009 14:54:18 +0100 Subject: Fix a talloc/malloc screwup in file_lines_pload Another bug due to careless merge to /lib :-((( Volker --- source3/lib/util_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index c5a9b7c29a..50ff844762 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -39,7 +39,7 @@ static char *file_pload(const char *syscmd, size_t *size) total = 0; while ((n = read(fd, buf, sizeof(buf))) > 0) { - p = (char *)SMB_REALLOC(p, total + n + 1); + p = talloc_realloc(NULL, p, char, total + n + 1); if (!p) { DEBUG(0,("file_pload: failed to expand buffer!\n")); close(fd); -- cgit From 8a264753a1f80defe5335c334f8242ad46d2af9f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Mar 2009 11:17:17 +0100 Subject: s4:auth/credentials: include gssapi/gssapi_krb5.h metze --- source4/auth/credentials/credentials_krb5.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/auth/credentials/credentials_krb5.h b/source4/auth/credentials/credentials_krb5.h index 0d0e9f330f..5e56752eb4 100644 --- a/source4/auth/credentials/credentials_krb5.h +++ b/source4/auth/credentials/credentials_krb5.h @@ -24,6 +24,7 @@ #define __CREDENTIALS_KRB5_H__ #include +#include #include struct gssapi_creds_container { -- cgit From 4d9641793124954e5994e64e9ce810f8f76e0449 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Mar 2009 12:21:36 +0100 Subject: s4:auth/credentials: use krb5_data_free() metze --- source4/auth/kerberos/clikrb5.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/source4/auth/kerberos/clikrb5.c b/source4/auth/kerberos/clikrb5.c index cf87d13cf2..68e7eb90cc 100644 --- a/source4/auth/kerberos/clikrb5.c +++ b/source4/auth/kerberos/clikrb5.c @@ -74,13 +74,9 @@ void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) { -#if defined(HAVE_KRB5_FREE_DATA_CONTENTS) if (pdata->data) { - krb5_free_data_contents(context, pdata); + krb5_data_free(pdata); } -#else - SAFE_FREE(pdata->data); -#endif } krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) -- cgit From 9521801dc89a425a2d1e58d0cf7ca24e83b02a04 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Mar 2009 12:21:59 +0100 Subject: s4:kdc: use krb5_data_free() metze --- source4/kdc/kdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index 1cfe9852f0..3d11441062 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -345,7 +345,7 @@ static bool kdc_process(struct kdc_server *kdc, } if (k5_reply.length) { *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length); - krb5_free_data_contents(kdc->smb_krb5_context->krb5_context, &k5_reply); + krb5_data_free(&k5_reply); } else { *reply = data_blob(NULL, 0); } -- cgit From 510e37155eab8b4bf29adcf10f242334bfedca46 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Mar 2009 11:20:50 +0100 Subject: s4:heimdal_build: define HAVE_STRLCPY, HAVE_STRLCAT, HAVE_STRCASECMP and HAVE_MKSTEMP metze --- source4/heimdal_build/roken.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h index 3edeb2fb2e..9bffbcdc53 100644 --- a/source4/heimdal_build/roken.h +++ b/source4/heimdal_build/roken.h @@ -41,6 +41,22 @@ #define HAVE_STRNDUP #endif +#ifndef HAVE_STRLCPY +#define HAVE_STRLCPY +#endif + +#ifndef HAVE_STRLCAT +#define HAVE_STRLCAT +#endif + +#ifndef HAVE_STRCASECMP +#define HAVE_STRCASECMP +#endif + +#ifndef HAVE_MKSTEMP +#define HAVE_MKSTEMP +#endif + #ifndef HAVE_SETENV #define HAVE_SETENV #endif -- cgit From 853f9283fb8fbcd2078e3cf8e99d6c8e24d77346 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Mar 2009 11:22:01 +0100 Subject: s4:heimdal_build: provide heimdal_version and heimdal_long_version symbols metze --- source4/heimdal_build/replace.c | 4 ++++ source4/heimdal_build/roken.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c index 41309fea6e..ba43dd9495 100644 --- a/source4/heimdal_build/replace.c +++ b/source4/heimdal_build/replace.c @@ -84,3 +84,7 @@ return -1; } #endif + +const char *heimdal_version = "samba-internal-heimdal"; +const char *heimdal_long_version = "samba-interal-heimdal"; + diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h index 9bffbcdc53..e3edd53872 100644 --- a/source4/heimdal_build/roken.h +++ b/source4/heimdal_build/roken.h @@ -100,4 +100,7 @@ #undef SOCKET_WRAPPER_REPLACE #include "heimdal/lib/roken/roken.h.in" +extern const char *heimdal_version; +extern const char *heimdal_long_version; + #endif -- cgit From 494e471d747c1e858481fad16cb33574d3e7f985 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 26 Mar 2009 16:28:45 +0100 Subject: configure: Use m4 defines for minimum library versions rather than shell variables, so the values rather than the variable names show up in configure output. --- source3/samba4.m4 | 8 ++++---- source4/configure.ac | 6 +++--- source4/min_versions.m4 | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source3/samba4.m4 b/source3/samba4.m4 index b5c7c74689..568283cd87 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -69,14 +69,14 @@ AC_CONFIG_FILES(../source4/librpc/dcerpc_atsvc.pc) m4_include(../source4/min_versions.m4) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= TALLOC_MIN_VERSION, [], [ SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= TDB_MIN_VERSION, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -86,13 +86,13 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, SMB_INCLUDE_MK(../lib/tdb/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = $TEVENT_REQUIRED_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = TEVENT_REQUIRED_VERSION, [],[m4_include(../lib/tevent/samba.m4)] ) SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) diff --git a/source4/configure.ac b/source4/configure.ac index 065a3300ca..3c23f27d68 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -44,14 +44,14 @@ AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc) m4_include(min_versions.m4) -SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, [], +SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= TALLOC_MIN_VERSION, [], [ m4_include(../lib/talloc/libtalloc.m4) SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, +SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= TDB_MIN_VERSION, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -67,7 +67,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = TEVENT_REQUIRED_VERSION, SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION, +SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) diff --git a/source4/min_versions.m4 b/source4/min_versions.m4 index eaefbd5148..1dd3501b99 100644 --- a/source4/min_versions.m4 +++ b/source4/min_versions.m4 @@ -1,6 +1,6 @@ # Minimum and exact required versions for various libraries # if we use the ones installed in the system. -TDB_MIN_VERSION=1.1.3 -TALLOC_MIN_VERSION=1.3.0 -LDB_REQUIRED_VERSION=0.9.3 -TEVENT_REQUIRED_VERSION=0.9.5 +define(TDB_MIN_VERSION,1.1.3) +define(TALLOC_MIN_VERSION,1.3.0) +define(LDB_REQUIRED_VERSION,0.9.3) +define(TEVENT_REQUIRED_VERSION,0.9.5) -- cgit From 94ba56b2bdad4782deefc5581e6b6ac5c4eeb258 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Mar 2009 12:21:55 -0700 Subject: Fix bug #6224 - nmbd waits 5 minutes at startup before checking if it needs to run elections Fix logic bug that causes nmbd to wait 5 minutes before looking for a master browser. This one is *old* :-). Thanks for Simo for bugging me on this. Jeremy. --- source3/nmbd/nmbd_elections.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index b50d215b91..1ed64f4059 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -130,9 +130,6 @@ void check_master_browser_exists(time_t t) struct subnet_record *subrec; const char *workgroup_name = lp_workgroup(); - if (!lastrun) - lastrun = t; - if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60))) return; -- cgit From 757d403dfff023fdb122a155f6a05d33daa76410 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Mar 2009 14:34:25 -0700 Subject: This should fix the build farm RAW-STREAMS failure. streams_depot.so depends on xattrs, and xattr_tdb was pushed *first* in the stack... Jeremy. --- source3/script/tests/selftest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index a430d01a0e..af77c79491 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -238,7 +238,7 @@ cat >$SERVERCONFFILE<