[SSSD] [PATCH] First batch of infrastructure patches for review

Lukas Slebodnik lslebodn at redhat.com
Fri Feb 14 12:03:27 UTC 2014


On (12/02/14 23:09), Jakub Hrozek wrote:
>On Wed, Jan 15, 2014 at 09:00:56AM +0100, Stef Walter wrote:
>> On 14.01.2014 21:19, Simo Sorce wrote:
>> > On Tue, 2014-01-14 at 21:08 +0100, Stef Walter wrote:
>> >> However, if you want we can use the C99 struct initialization by name
>> >> feature here. Are we fine with using that?
>> >>
>> > Yes we are fine with C99, and I strongly prefer initialization by name
>> > where it makes sense. For autogenerated code it makes a lot of sense.
>> 
>> Indeed.
>> 
>> Here's the updated patchset with the C99 struct initialization change.
>> 
>> Cheers,
>> 
>> Stef
>
>As discussed with Stef on Monday in Brno, the SSSD team will rebase the
>patches atop the DEBUG macro changes
done.

>and will make sure parallel build works fine with the generated code.

I do not have any probelm with parallel build.
What did you mean exactly?

Patches attached.

LS
-------------- next part --------------
>From 5e32686ad9d003c5a4f37f98edd8282f3ccb525d Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Thu, 9 Jan 2014 23:04:45 +0100
Subject: [PATCH 1/6] sbus: Add meta data structures and code generator

These metadata structures hold the information about all the
details of a DBus interface. They are typically generated from
the canonical XML form of the DBus interface, although they
may also be hand crafted.

Add some handy functions for looking up methods, props, signals,
in the metadata of an interface. Currently lookups are just done
by looking through an array. If performance becomes an issue (ie:
very large interfaces) it would be really easy to sort things
and use bsearch().

Later commits will include some definitions using this metadata
and related functions.

DBus interfaces are defined here:

http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format

The introspection data format has become the standard way to represent a
DBus interface. For many examples see /usr/share/dbus-1/interfaces/ on a
typical linux machine.

A word about annotations. These are extra flags or values that can be
assigned to anything. So far, the codegen supports this annotation:

org.freedesktop.DBus.GLib.CSymbol
 - An annotation specified in the specification that tells us what C symbol
   to generate for a given interface or method. By default the codegen will
   build up a symbol name from the DBus name.

It is possible to confuse the code generator into producing invalid
C code (with strange method names, for example), but the C compiler
catches such silliness right away.

Add tests testing basic features of the codegen and poking through
the metadata it creates. Also test the metadata lookup functions.

Generated code is checked in for easy discovery.

An example of the XML interface definitions can be found at:

  src/tests/sbus_codegen_tests.xml

And an example of the generated header can be found here:

  src/tests/sbus_codegen_tests_generated.h
---
 Makefile.am                              |  47 ++-
 src/sbus/sbus_codegen                    | 506 +++++++++++++++++++++++++++++++
 src/sbus/sssd_dbus_meta.c                |  64 ++++
 src/sbus/sssd_dbus_meta.h                |  82 +++++
 src/tests/sbus_codegen_tests.c           | 169 +++++++++++
 src/tests/sbus_codegen_tests.xml         |  45 +++
 src/tests/sbus_codegen_tests_generated.c |  79 +++++
 src/tests/sbus_codegen_tests_generated.h |  25 ++
 8 files changed, 1016 insertions(+), 1 deletion(-)
 create mode 100755 src/sbus/sbus_codegen
 create mode 100644 src/sbus/sssd_dbus_meta.c
 create mode 100644 src/sbus/sssd_dbus_meta.h
 create mode 100644 src/tests/sbus_codegen_tests.c
 create mode 100755 src/tests/sbus_codegen_tests.xml
 create mode 100644 src/tests/sbus_codegen_tests_generated.c
 create mode 100644 src/tests/sbus_codegen_tests_generated.h

diff --git a/Makefile.am b/Makefile.am
index efb314d474765d8d8fbce595dbac8c6a5afab5e2..8f1e6f24615a57f27b63ac391dd4aa5e6564212d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -137,7 +137,8 @@ if HAVE_CHECK
         ipa_hbac-tests \
         sss_idmap-tests \
         responder_socket_access-tests \
-        safe-format-tests
+        safe-format-tests \
+        sbus_codegen_tests
 
 if BUILD_SSH
     non_interactive_check_based_tests += sysdb_ssh-tests
@@ -443,6 +444,7 @@ dist_noinst_HEADERS = \
     src/responder/ssh/sshsrv_private.h \
     src/sbus/sbus_client.h \
     src/sbus/sssd_dbus.h \
+    src/sbus/sssd_dbus_meta.h \
     src/sbus/sssd_dbus_private.h \
     src/db/sysdb.h \
     src/db/sysdb_sudo.h \
@@ -572,6 +574,7 @@ libsss_util_la_SOURCES = \
     src/sbus/sbus_client.c \
     src/sbus/sssd_dbus_common.c \
     src/sbus/sssd_dbus_connection.c \
+    src/sbus/sssd_dbus_meta.c \
     src/sbus/sssd_dbus_server.c \
     src/util/util.c \
     src/util/memory.c \
@@ -650,6 +653,37 @@ include_HEADERS = \
     src/sss_client/idmap/sss_nss_idmap.h
 
 ####################
+# Sbus Codegen     #
+####################
+
+# Yes, the goal here is that the generated files end up in $(srcdir)
+# not $(builddir). Always use $(srcdir) here.
+CODEGEN_XML = \
+    $(srcdir)/src/tests/sbus_codegen_tests.xml
+
+SBUS_CODEGEN = src/sbus/sbus_codegen
+
+EXTRA_DIST += \
+    $(SBUS_CODEGEN) \
+    $(CODEGEN_XML)
+
+SUFFIXES = .xml _generated.h _generated.c
+
+.xml_generated.h:
+	$(srcdir)/$(SBUS_CODEGEN) --mode=header --output=$@ $<
+.xml_generated.c:
+	$(srcdir)/$(SBUS_CODEGEN) --mode=source --output=$@ $<
+
+# Regenerate when codegen changes
+CODEGEN_CODE = \
+    $(CODEGEN_XML:.xml=_generated.c) \
+    $(CODEGEN_XML:.xml=_generated.h)
+
+$(CODEGEN_CODE): $(SBUS_CODEGEN)
+
+BUILT_SOURCES = $(CODEGEN_CODE)
+
+####################
 # Program Binaries #
 ####################
 sssd_SOURCES = \
@@ -1288,6 +1322,17 @@ krb5_child_test_LDADD = \
     $(SSSD_INTERNAL_LTLIBS) \
     libsss_test_common.la
 
+sbus_codegen_tests_SOURCES = \
+   src/tests/sbus_codegen_tests.c \
+   src/tests/sbus_codegen_tests_generated.c \
+   src/tests/sbus_codegen_tests_generated.h
+sbus_codegen_tests_CFLAGS = \
+    $(CHECK_CFLAGS)
+sbus_codegen_tests_LDADD = \
+    $(SSSD_INTERNAL_LTLIBS) \
+    $(SSSD_LIBS) \
+    $(CHECK_LIBS)
+
 if HAVE_CMOCKA
 
 TEST_MOCK_RESP_OBJ = \
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
new file mode 100755
index 0000000000000000000000000000000000000000..9c0147e2b95141f5434445b1cac8827962580a35
--- /dev/null
+++ b/src/sbus/sbus_codegen
@@ -0,0 +1,506 @@
+#!/bin/python
+
+#
+# Authors:
+#     Stef Walter <stefw at redhat.com>
+#
+# Copyright (C) 2014 Red Hat
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+#
+# Some parser code from GLib
+#
+# Copyright (C) 2008-2011 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General
+# Public License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Portions by: David Zeuthen <davidz at redhat.com>
+#
+
+#
+# DBus interfaces are defined here:
+#
+# http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
+#
+# The introspection data format has become the standard way to represent a
+# DBus interface. For many examples see /usr/share/dbus-1/interfaces/ on a
+# typical linux machine.
+#
+# A word about annotations. These are extra flags or values that can be
+# assigned to anything. So far, the codegen supports this annotation:
+#
+# org.freedesktop.DBus.GLib.CSymbol
+#  - An annotation specified in the specification that tells us what C symbol
+#    to generate for a given interface or method. By default the codegen will
+#    build up a symbol name from the DBus name.
+#
+
+import optparse
+import os
+import re
+import StringIO
+import sys
+import xml.parsers.expat
+
+# ----------------------------------------------------------------------------
+# Objects
+
+class DBusXmlException(Exception):
+    line = 0
+    file = None
+
+    # Lets us print problems like a compiler would
+    def __str__(self):
+        message = Exception.__str__(self)
+        if self.file and self.line:
+            return "%s:%d: %s" % (self.file, self.line, message)
+        elif self.file:
+            return "%s: %s" % (self.file, message)
+        else:
+            return message
+
+class Base:
+    def __init__(self, name):
+        if not name:
+            raise DBusXmlException('No name on element')
+        self.name = name
+        self.annotations = { }
+    def c_name(self):
+        return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol", self.name)
+
+class Arg(Base):
+    def __init__(self, method, name, signature):
+        Base.__init__(self, name)
+        self.method = method
+        self.signature = signature
+
+class Method(Base):
+    def __init__(self, iface, name):
+        Base.__init__(self, name)
+        self.iface = iface
+        self.in_args = []
+        self.out_args = []
+    def fq_c_name(self):
+        return "%s_%s" % (self.iface.c_name(), self.c_name())
+
+class Signal(Base):
+    def __init__(self, iface, name):
+        Base.__init__(self, name)
+        self.iface = iface
+        self.args = []
+    def fq_c_name(self):
+        return "%s_%s" % (self.iface.c_name(), self.c_name())
+
+class Property(Base):
+    def __init__(self, iface, name, signature, access):
+        Base.__init__(self, name)
+        self.iface = iface
+        self.signature = signature
+        self.readable = False
+        self.writable = False
+        if access == 'readwrite':
+            self.readable = True
+            self.writable = True
+        elif access == 'read':
+            self.readable = True
+        elif access == 'write':
+            self.writable = True
+        else:
+            raise DBusXmlException('Invalid access type %s'%self.access)
+    def fq_c_name(self):
+        return "%s_%s" % (self.iface.c_name(), self.c_name())
+
+class Interface(Base):
+    def __init__(self, name):
+        Base.__init__(self, name)
+        self.methods = []
+        self.signals = []
+        self.properties = []
+    def c_name(self):
+        return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol",
+                                    self.name.replace(".", "_"))
+
+# ----------------------------------------------------------------------------
+# Code Generation
+
+class CodegenException(Exception):
+    pass
+
+def source_args(parent, args, suffix):
+    print "/* arguments for %s.%s */" % (parent.iface.name, parent.name)
+    print "const struct sbus_arg_meta %s%s[] = {" % (parent.fq_c_name(), suffix)
+    for arg in args:
+        print "    { \"%s\", \"%s\" }," % (arg.name, arg.signature)
+    print "    { NULL, }"
+    print "};"
+    print
+
+def source_methods(iface, methods):
+    for meth in methods:
+        if meth.in_args:
+            source_args(meth, meth.in_args, "__in")
+        if meth.out_args:
+            source_args(meth, meth.out_args, "__out")
+
+    print "/* methods for %s */" % iface.name
+    print "const struct sbus_method_meta %s__methods[] = {" % iface.c_name()
+    for meth in methods:
+        print "    {"
+        print "        \"%s\", /* name */" % meth.name
+        if meth.in_args:
+            print "        %s__in," % meth.fq_c_name()
+        else:
+            print "        NULL, /* no in_args */"
+        if meth.out_args:
+            print "        %s__out," % meth.fq_c_name()
+        else:
+            print "        NULL, /* no out_args */"
+        print "    },"
+    print "    { NULL, }"
+    print "};"
+    print
+
+def source_signals(iface, signals):
+    for sig in iface.signals:
+        if sig.args:
+            source_args(sig, sig.args, "__args")
+
+    print "/* signals for %s */" % iface.name
+    print "const struct sbus_signal_meta %s__signals[] = {" % iface.c_name()
+    for sig in signals:
+        print "    {"
+        print "        \"%s\", /* name */" % sig.name
+        if sig.args:
+            print "        %s__args" % sig.fq_c_name()
+        else:
+            print "        NULL, /* no args */"
+        print "    },"
+    print "    { NULL, }"
+    print "};"
+    print
+
+def source_properties(iface, properties):
+    print "/* property info for %s */" % iface.name
+    print "const struct sbus_property_meta %s__properties[] = {" % iface.c_name()
+    for prop in properties:
+        print "    {"
+        print "        \"%s\", /* name */" % prop.name
+        print "        \"%s\", /* signature */" % prop.signature
+        if prop.readable and prop.writable:
+            print "        SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE,"
+        elif prop.readable:
+            print "        SBUS_PROPERTY_READABLE,"
+        elif prop.writable:
+            print "        SBUS_PROPERTY_WRITABLE,"
+        else:
+            assert False, "should not be reached"
+        print "    },"
+    print "    { NULL, }"
+    print "};"
+    print
+
+def header_interface(iface):
+    print "/* interface info for %s */" % iface.name
+    print "extern const struct sbus_interface_meta %s_meta;" % iface.c_name();
+    print
+
+def source_interface(iface):
+    print "/* interface info for %s */" % iface.name
+    print "const struct sbus_interface_meta %s_meta = {" % iface.c_name();
+    print "    \"%s\", /* name */" % iface.name
+    if iface.methods:
+        print "    %s__methods," % iface.c_name()
+    else:
+        print "    NULL, /* no methods */"
+    if iface.signals:
+        print "    %s__signals," % iface.c_name()
+    else:
+        print "    NULL, /* no signals */"
+    if iface.properties:
+        print "    %s__properties" % iface.c_name()
+    else:
+        print "    NULL, /* no propetries */"
+    print "};"
+    print
+
+def generate_source(ifaces, filename):
+    basename = os.path.basename(filename)
+
+    print "/* The following definitions are auto-generated from %s */" % basename
+    print
+
+    print "#include \"util/util.h\""
+    print "#include \"sbus/sssd_dbus.h\""
+    print "#include \"sbus/sssd_dbus_meta.h\""
+    print
+
+    for iface in ifaces:
+
+        # The methods
+        if iface.methods:
+            source_methods(iface, iface.methods)
+
+        # The signals array
+        if iface.signals:
+            source_signals(iface, iface.signals)
+
+        # The properties array
+        if iface.properties:
+            source_properties(iface, iface.properties)
+
+        # The sbus_interface structure
+        source_interface(iface)
+
+def generate_header(ifaces, filename):
+    basename = os.path.basename(filename)
+    guard = "__%s__" % re.sub(r'([^_A-Z0-9])', "_", basename.upper())
+
+    print "/* The following declarations are auto-generated from %s */" % basename
+    print
+    print "#ifndef %s" % guard
+    print "#define %s" % guard
+    print
+    print "#include \"sbus/sssd_dbus.h\""
+    print
+
+    print "/* ------------------------------------------------------------------------"
+    print " * DBus Interface Metadata"
+    print " *"
+    print " * These structure definitions are filled in with the information about"
+    print " * the interfaces, methods, properties and so on."
+    print " *"
+    print " * The actual definitions are found in the accompanying C file next"
+    print " * to this header."
+    print " */"
+    print
+
+    for iface in ifaces:
+        header_interface(iface)
+
+    print
+    print "#endif /* %s */" % guard
+
+# ----------------------------------------------------------------------------
+# XML Interface Parsing
+
+STATE_TOP = 'top'
+STATE_NODE = 'node'
+STATE_INTERFACE = 'interface'
+STATE_METHOD = 'method'
+STATE_SIGNAL = 'signal'
+STATE_PROPERTY = 'property'
+STATE_ARG = 'arg'
+STATE_ANNOTATION = 'annotation'
+STATE_IGNORED = 'ignored'
+
+def expect_attr(attrs, name):
+    if name not in attrs:
+        raise DBusXmlException("Missing attribute '%s'" % name)
+    if attrs[name] == "":
+        raise DBusXmlException("Empty attribute '%s'" % name)
+    return attrs[name]
+
+class DBusXMLParser:
+    def __init__(self, filename):
+        parser = xml.parsers.expat.ParserCreate()
+        parser.CommentHandler = self.handle_comment
+        parser.CharacterDataHandler = self.handle_char_data
+        parser.StartElementHandler = self.handle_start_element
+        parser.EndElementHandler = self.handle_end_element
+
+        self.parsed_interfaces = []
+        self.cur_object = None
+
+        self.state = STATE_TOP
+        self.state_stack = []
+        self.cur_object = None
+        self.cur_object_stack = []
+        self.arg_count = 0
+
+        try:
+            with open(filename, "r") as f:
+                parser.ParseFile(f)
+        except DBusXmlException, ex:
+            ex.line = parser.CurrentLineNumber
+            ex.file = filename
+            raise
+        except xml.parsers.expat.ExpatError, ex:
+            exc = DBusXmlException(str(ex))
+            exc.line = ex.lineno
+            exc.file = filename
+            raise exc
+
+    def handle_comment(self, data):
+        pass
+
+    def handle_char_data(self, data):
+        pass
+
+    def handle_start_element(self, name, attrs):
+        old_state = self.state
+        old_cur_object = self.cur_object
+        if self.state == STATE_IGNORED:
+            self.state = STATE_IGNORED
+        elif self.cur_object and name == STATE_ANNOTATION:
+                val = attrs.get('value', '')
+                self.cur_object.annotations[expect_attr(attrs, 'name')] = val
+                self.state = STATE_IGNORED
+        elif self.state == STATE_TOP:
+            if name == STATE_NODE:
+                self.state = STATE_NODE
+            else:
+                self.state = STATE_IGNORED
+        elif self.state == STATE_NODE:
+            if name == STATE_INTERFACE:
+                self.state = STATE_INTERFACE
+                iface = Interface(expect_attr(attrs, 'name'))
+                self.cur_object = iface
+                self.parsed_interfaces.append(iface)
+            else:
+                self.state = STATE_IGNORED
+
+        elif self.state == STATE_INTERFACE:
+            if name == STATE_METHOD:
+                self.state = STATE_METHOD
+                method = Method(self.cur_object, expect_attr(attrs, 'name'))
+                self.cur_object.methods.append(method)
+                self.cur_object = method
+                self.arg_count = 0
+            elif name == STATE_SIGNAL:
+                self.state = STATE_SIGNAL
+                signal = Signal(self.cur_object, expect_attr(attrs, 'name'))
+                self.cur_object.signals.append(signal)
+                self.cur_object = signal
+                self.arg_count = 0
+            elif name == STATE_PROPERTY:
+                self.state = STATE_PROPERTY
+                prop = Property(self.cur_object,
+                                expect_attr(attrs, 'name'),
+                                expect_attr(attrs, 'type'),
+                                expect_attr(attrs, 'access'))
+                self.cur_object.properties.append(prop)
+                self.cur_object = prop
+            else:
+                self.state = STATE_IGNORED
+
+        elif self.state == STATE_METHOD:
+            if name == STATE_ARG:
+                self.state = STATE_ARG
+                arg = Arg(self.cur_object,
+                          expect_attr(attrs, 'name'),
+                          expect_attr(attrs, 'type'))
+                direction = attrs.get('direction', 'in')
+                if direction == 'in':
+                    self.cur_object.in_args.append(arg)
+                elif direction == 'out':
+                    self.cur_object.out_args.append(arg)
+                else:
+                    raise DBusXmlException('Invalid direction "%s"' % direction)
+                self.cur_object = arg
+            else:
+                self.state = STATE_IGNORED
+
+        elif self.state == STATE_SIGNAL:
+            if name == STATE_ARG:
+                self.state = STATE_ARG
+                arg = Arg(self.cur_object,
+                          expect_attr(attrs, 'name'),
+                          expect_attr(attrs, 'type'))
+                self.cur_object.args.append(arg)
+                self.cur_object = arg
+            else:
+                self.state = STATE_IGNORED
+
+        elif self.state == STATE_PROPERTY:
+            self.state = STATE_IGNORED
+
+        elif self.state == STATE_ARG:
+            self.state = STATE_IGNORED
+
+        else:
+            assert False, 'Unhandled state "%s" while entering element with name "%s"' % (self.state, name)
+
+        self.state_stack.append(old_state)
+        self.cur_object_stack.append(old_cur_object)
+
+    def handle_end_element(self, name):
+        self.state = self.state_stack.pop()
+        self.cur_object = self.cur_object_stack.pop()
+
+def parse_options():
+    parser = optparse.OptionParser("usage: %prog [options] introspect.xml ...")
+    parser.set_description("sbus_codegen generates sbus interface structures \
+                            from standard XML Introspect data.")
+    parser.add_option("--mode",
+                      dest="mode", default="header",
+                      help="'header' or 'source' (default: header)",
+                      metavar="MODE")
+    parser.add_option("--output",
+                      dest="output", default=None,
+                      help="Set output file name (default: stdout)",
+                      metavar="FILE")
+    (options, args) = parser.parse_args()
+
+    if not args:
+        print >> sys.stderr, "sbus_codegen: no input file specified"
+        sys.exit(2)
+
+    if options.mode not in ["header", "source"]:
+        print >> sys.stderr, "sbus_codegen: specify --mode=header or --mode=source"
+
+    return options, args
+
+def main():
+    options, args = parse_options()
+
+    if options.output:
+        sys.stdout = buf = StringIO.StringIO()
+
+    for filename in args:
+        parser = DBusXMLParser(filename)
+
+        if options.mode == "header":
+            generate_header(parser.parsed_interfaces, filename)
+        elif options.mode == "source":
+            generate_source(parser.parsed_interfaces, filename)
+        else:
+            assert False, "should not be reached"
+
+    # Write output at end to be nice to 'make'
+    if options.output:
+        output = open(options.output, "w")
+        output.write(buf.getvalue())
+        output.close()
+
+if __name__ == "__main__":
+    try:
+        main()
+    except DBusXmlException, ex:
+        print >> sys.stderr, str(ex)
+        sys.exit(1)
diff --git a/src/sbus/sssd_dbus_meta.c b/src/sbus/sssd_dbus_meta.c
new file mode 100644
index 0000000000000000000000000000000000000000..57123b7431b18b02be408015556986c65cd50bf4
--- /dev/null
+++ b/src/sbus/sssd_dbus_meta.c
@@ -0,0 +1,64 @@
+/*
+    Authors:
+        Stef Walter <stefw at redhat.com>
+
+    Copyright (C) 2014 Red Hat
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include "sbus/sssd_dbus_meta.h"
+
+const struct sbus_method_meta *
+sbus_meta_find_method(const struct sbus_interface_meta *interface,
+                      const char *method_name)
+{
+    const struct sbus_method_meta *method;
+
+    for (method = interface->methods; method && method->name; method++) {
+        if (strcmp(method_name, method->name) == 0)
+            return method;
+    }
+
+    return NULL;
+}
+
+const struct sbus_signal_meta *
+sbus_meta_find_signal(const struct sbus_interface_meta *interface,
+                      const char *signal_name)
+{
+    const struct sbus_signal_meta *signal;
+
+    for (signal = interface->signals; signal && signal->name; signal++) {
+        if (strcmp(signal_name, signal->name) == 0)
+            return signal;
+    }
+
+    return NULL;
+}
+
+const struct sbus_property_meta *
+sbus_meta_find_property(const struct sbus_interface_meta *interface,
+                        const char *property_name)
+{
+    const struct sbus_property_meta *property;
+
+    for (property = interface->properties; property && property->name; property++) {
+        if (strcmp(property_name, property->name) == 0)
+            return property;
+    }
+
+    return NULL;
+}
diff --git a/src/sbus/sssd_dbus_meta.h b/src/sbus/sssd_dbus_meta.h
new file mode 100644
index 0000000000000000000000000000000000000000..17ea7a5076ba8ed960b954035ab584ebd1bd4f88
--- /dev/null
+++ b/src/sbus/sssd_dbus_meta.h
@@ -0,0 +1,82 @@
+/*
+    Authors:
+        Stef Walter <stefw at redhat.com>
+
+    Copyright (C) 2014 Red Hat
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SSSD_DBUS_META_H_
+#define _SSSD_DBUS_META_H_
+
+/*
+ * Interface metadata
+ *
+ * For arrays, the last item in each array will have a
+ * NULL .name field
+ *
+ * Typically these structs will be generated by sbus_codegen
+ * from canonical XML interface data:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
+ */
+
+struct sbus_arg_meta {
+    const char *name;
+    const char *type;
+};
+
+struct sbus_method_meta {
+    const char *name;
+    const struct sbus_arg_meta *in_args;
+    const struct sbus_arg_meta *out_args;
+};
+
+enum {
+    SBUS_PROPERTY_READABLE = 1 << 0,
+    SBUS_PROPERTY_WRITABLE = 1 << 1
+};
+
+struct sbus_property_meta {
+    const char *name;
+    const char *type;
+    int flags;
+};
+
+struct sbus_signal_meta {
+    const char *name;
+    const struct sbus_arg_meta *args;
+};
+
+struct sbus_interface_meta {
+    const char *name;
+    const struct sbus_method_meta *methods;
+    const struct sbus_signal_meta *signals;
+    const struct sbus_property_meta *properties;
+};
+
+const struct sbus_method_meta *
+sbus_meta_find_method (const struct sbus_interface_meta *interface,
+                       const char *method_name);
+
+const struct sbus_signal_meta *
+sbus_meta_find_signal (const struct sbus_interface_meta *interface,
+                       const char *signal_name);
+
+const struct sbus_property_meta *
+sbus_meta_find_property (const struct sbus_interface_meta *interface,
+                         const char *property_name);
+
+#endif /* _SSSD_DBUS_META_H_ */
diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c
new file mode 100644
index 0000000000000000000000000000000000000000..c098799872425b03a0c8c8b616da906b02f68722
--- /dev/null
+++ b/src/tests/sbus_codegen_tests.c
@@ -0,0 +1,169 @@
+/*
+   SSSD
+
+   sbus_codegen tests.
+
+   Authors:
+        Stef Walter <stefw at redhat.com>
+
+   Copyright (C) Red Hat, Inc 2014
+
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <check.h>
+#include <talloc.h>
+#include <tevent.h>
+#include <popt.h>
+
+#include "sbus/sssd_dbus_meta.h"
+#include "tests/sbus_codegen_tests_generated.h"
+
+static const struct sbus_arg_meta *
+find_arg(const struct sbus_arg_meta *args,
+         const char *name)
+{
+    const struct sbus_arg_meta *arg;
+    for (arg = args; arg->name != NULL; arg++) {
+        if (strcmp (arg->name, name) == 0)
+            return arg;
+    }
+
+    return NULL;
+}
+
+START_TEST(test_interfaces)
+{
+    ck_assert_str_eq(com_planetexpress_Ship_meta.name,
+                     "com.planetexpress.Ship");
+    ck_assert(com_planetexpress_Ship_meta.methods != NULL);
+    ck_assert(com_planetexpress_Ship_meta.signals != NULL);
+    ck_assert(com_planetexpress_Ship_meta.properties != NULL);
+
+    /* Explicit C Symbol */
+    ck_assert_str_eq(test_pilot_meta.name, "com.planetexpress.Pilot");
+    ck_assert(test_pilot_meta.methods == NULL); /* no methods */
+    ck_assert(test_pilot_meta.signals == NULL); /* no signals */
+    ck_assert(test_pilot_meta.properties != NULL);
+
+}
+END_TEST
+
+START_TEST(test_methods)
+{
+    const struct sbus_method_meta *method;
+    const struct sbus_arg_meta *arg;
+
+    method = sbus_meta_find_method(&com_planetexpress_Ship_meta,
+                                   "MoveUniverse");
+    ck_assert(method != NULL);
+    ck_assert_str_eq(method->name, "MoveUniverse");
+    ck_assert(method->in_args != NULL);
+    ck_assert(method->out_args != NULL);
+
+    arg = find_arg(method->in_args, "smoothly");
+    ck_assert(arg != NULL);
+    ck_assert_str_eq(arg->name, "smoothly");
+    ck_assert_str_eq(arg->type, "b");
+
+    arg = find_arg(method->out_args, "where_we_crashed");
+    ck_assert(arg != NULL);
+    ck_assert_str_eq(arg->name, "where_we_crashed");
+    ck_assert_str_eq(arg->type, "s");
+}
+END_TEST
+
+START_TEST(test_properties)
+{
+    const struct sbus_property_meta *prop;
+
+    prop = sbus_meta_find_property(&com_planetexpress_Ship_meta, "Color");
+    ck_assert(prop != NULL);
+    ck_assert_str_eq(prop->name, "Color");
+    ck_assert_str_eq(prop->type, "s");
+    ck_assert_int_eq(prop->flags, SBUS_PROPERTY_READABLE);
+}
+END_TEST
+
+START_TEST(test_signals)
+{
+    const struct sbus_signal_meta *signal;
+    const struct sbus_arg_meta *arg;
+
+    signal = sbus_meta_find_signal(&com_planetexpress_Ship_meta,
+                                   "BecameSentient");
+    ck_assert(signal != NULL);
+    ck_assert_str_eq(signal->name, "BecameSentient");
+    ck_assert(signal->args != NULL);
+
+    arg = find_arg(signal->args, "gender");
+    ck_assert(arg != NULL);
+    ck_assert_str_eq(arg->name, "gender");
+    ck_assert_str_eq(arg->type, "s");
+}
+END_TEST
+
+Suite *create_suite(void)
+{
+    Suite *s = suite_create("sbus_codegen");
+
+    TCase *tc = tcase_create("defs");
+
+    /* Do some testing */
+    tcase_add_test(tc, test_interfaces);
+    tcase_add_test(tc, test_methods);
+    tcase_add_test(tc, test_properties);
+    tcase_add_test(tc, test_signals);
+
+    /* Add all test cases to the test suite */
+    suite_add_tcase(s, tc);
+
+    return s;
+}
+
+int main(int argc, const char *argv[])
+{
+    int opt;
+    poptContext pc;
+    int failure_count;
+    Suite *suite;
+    SRunner *sr;
+
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        POPT_TABLEEND
+    };
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+        switch (opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                    poptBadOption(pc, 0), poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 1;
+        }
+    }
+    poptFreeContext(pc);
+
+    suite = create_suite();
+    sr = srunner_create(suite);
+    srunner_set_fork_status(sr, CK_FORK);
+    /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
+    srunner_run_all(sr, CK_ENV);
+    failure_count = srunner_ntests_failed(sr);
+    srunner_free(sr);
+    return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/src/tests/sbus_codegen_tests.xml b/src/tests/sbus_codegen_tests.xml
new file mode 100755
index 0000000000000000000000000000000000000000..0def3585a973ef1d7fdef198d8ed8bf5e84c209c
--- /dev/null
+++ b/src/tests/sbus_codegen_tests.xml
@@ -0,0 +1,45 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+    <!--
+      This file should exercise as many aspects of the sbus_codegen as
+      possible. See sbus_codegen_test.c for verification.
+    -->
+
+    <!--
+      This is an interface, it will get a sbus_interface_meta struct.
+      Its name will be com_planetexpress_Ship__meta, since no c symbol
+      is specified.
+    -->
+    <interface name="com.planetexpress.Ship">
+        <!-- A property -->
+        <property name="Color" type="s" access="read"/>
+
+        <!-- A method with two in and one out argument -->
+        <method name="MoveUniverse">
+            <!-- This is a boolean arg -->
+            <arg name="smoothly" type="b" direction="in"/>
+            <!-- This is an uint32 arg -->
+            <arg name="speed_factor" type="u" direction="in"/>
+            <!-- This is a string arg -->
+            <arg name="where_we_crashed" type="s" direction="out"/>
+        </method>
+
+        <!-- A signal with one argument -->
+        <signal name="BecameSentient">
+            <arg name="gender" type="s"/>
+        </signal>
+    </interface>
+
+    <!--
+      Another interface. It's C name will be test_pilot, since we've overridden
+      the c symbol name.
+    -->
+    <interface name="com.planetexpress.Pilot">
+        <annotation value="test_pilot" name="org.freedesktop.DBus.GLib.CSymbol"/>
+
+        <!-- A property -->
+        <property name="FullName" type="s" access="readwrite"/>
+    </interface>
+
+</node>
diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c
new file mode 100644
index 0000000000000000000000000000000000000000..556eea12c8f16103e3a14bdbd955e62dbc346351
--- /dev/null
+++ b/src/tests/sbus_codegen_tests_generated.c
@@ -0,0 +1,79 @@
+/* The following definitions are auto-generated from sbus_codegen_tests.xml */
+
+#include "util/util.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus/sssd_dbus_meta.h"
+
+/* arguments for com.planetexpress.Ship.MoveUniverse */
+const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__in[] = {
+    { "smoothly", "b" },
+    { "speed_factor", "u" },
+    { NULL, }
+};
+
+/* arguments for com.planetexpress.Ship.MoveUniverse */
+const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__out[] = {
+    { "where_we_crashed", "s" },
+    { NULL, }
+};
+
+/* methods for com.planetexpress.Ship */
+const struct sbus_method_meta com_planetexpress_Ship__methods[] = {
+    {
+        "MoveUniverse", /* name */
+        com_planetexpress_Ship_MoveUniverse__in,
+        com_planetexpress_Ship_MoveUniverse__out,
+    },
+    { NULL, }
+};
+
+/* arguments for com.planetexpress.Ship.BecameSentient */
+const struct sbus_arg_meta com_planetexpress_Ship_BecameSentient__args[] = {
+    { "gender", "s" },
+    { NULL, }
+};
+
+/* signals for com.planetexpress.Ship */
+const struct sbus_signal_meta com_planetexpress_Ship__signals[] = {
+    {
+        "BecameSentient", /* name */
+        com_planetexpress_Ship_BecameSentient__args
+    },
+    { NULL, }
+};
+
+/* property info for com.planetexpress.Ship */
+const struct sbus_property_meta com_planetexpress_Ship__properties[] = {
+    {
+        "Color", /* name */
+        "s", /* signature */
+        SBUS_PROPERTY_READABLE,
+    },
+    { NULL, }
+};
+
+/* interface info for com.planetexpress.Ship */
+const struct sbus_interface_meta com_planetexpress_Ship_meta = {
+    "com.planetexpress.Ship", /* name */
+    com_planetexpress_Ship__methods,
+    com_planetexpress_Ship__signals,
+    com_planetexpress_Ship__properties
+};
+
+/* property info for com.planetexpress.Pilot */
+const struct sbus_property_meta test_pilot__properties[] = {
+    {
+        "FullName", /* name */
+        "s", /* signature */
+        SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE,
+    },
+    { NULL, }
+};
+
+/* interface info for com.planetexpress.Pilot */
+const struct sbus_interface_meta test_pilot_meta = {
+    "com.planetexpress.Pilot", /* name */
+    NULL, /* no methods */
+    NULL, /* no signals */
+    test_pilot__properties
+};
diff --git a/src/tests/sbus_codegen_tests_generated.h b/src/tests/sbus_codegen_tests_generated.h
new file mode 100644
index 0000000000000000000000000000000000000000..56911ddefefcccfd7eaf90edf3677278ed8dcef4
--- /dev/null
+++ b/src/tests/sbus_codegen_tests_generated.h
@@ -0,0 +1,25 @@
+/* The following declarations are auto-generated from sbus_codegen_tests.xml */
+
+#ifndef __SBUS_CODEGEN_TESTS_XML__
+#define __SBUS_CODEGEN_TESTS_XML__
+
+#include "sbus/sssd_dbus.h"
+
+/* ------------------------------------------------------------------------
+ * DBus Interface Metadata
+ *
+ * These structure definitions are filled in with the information about
+ * the interfaces, methods, properties and so on.
+ *
+ * The actual definitions are found in the accompanying C file next
+ * to this header.
+ */
+
+/* interface info for com.planetexpress.Ship */
+extern const struct sbus_interface_meta com_planetexpress_Ship_meta;
+
+/* interface info for com.planetexpress.Pilot */
+extern const struct sbus_interface_meta test_pilot_meta;
+
+
+#endif /* __SBUS_CODEGEN_TESTS_XML__ */
-- 
1.8.5.3

-------------- next part --------------
>From a48b47852985f04881315225a2095c6d67697b50 Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Fri, 10 Jan 2014 08:54:41 +0100
Subject: [PATCH 2/6] sbus: Add sbus_vtable and update codegen to support it

Each interface is a vtable structure derived from
sbus_vtable, in the sense that it has an sbus_vtable
struct as its first argument. This lets us upcast the
interface vtable structure to an sbus_vtable and dispatch
to it dynamically and cleanly.

The interface metadata contains information about which
vtable offset in the interface metadata should be dispatched
to for a given function. This is a common scheme, not only
among dbus implementations, but also compiled languages.

Currently all the vtable functions are of type
sbus_msg_handler_fn. These are the handlers we are familiar
with and perform raw processing of the message. Later commits
will introduce type safe handlers that levelage compile checking
and automatic argument packing/unpacking.

Although this may seem contrived now, the remainder of the
dbus infrastructure work will build on this, including
ofd.Properties, ofd.ObjectManager, ofd.Introspect, compiler
checked type safe unpacking/packing, etc.

The codegen now generates vtable structures for each interface
along-side the metadata, and fills in vtable offsets
appropriately.

It is obviously still possible to hand-craft such vtables and
metadata if needed for a special case.

Once again examples output can be found at:

  src/tests/sbus_codegen_tests_generated.h
---
 Makefile.am                              |  2 +-
 src/sbus/sbus_codegen                    | 41 ++++++++++++++++++++++++++++++--
 src/sbus/sssd_dbus.h                     | 15 ++++++++++++
 src/sbus/sssd_dbus_meta.h                |  1 +
 src/tests/sbus_codegen_tests.c           | 33 +++++++++++++++++++++++++
 src/tests/sbus_codegen_tests.xml         |  5 ++++
 src/tests/sbus_codegen_tests_generated.c |  8 +++++++
 src/tests/sbus_codegen_tests_generated.h | 19 +++++++++++++++
 8 files changed, 121 insertions(+), 3 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 8f1e6f24615a57f27b63ac391dd4aa5e6564212d..836f2067e54ab3a24f23e9a081d6e7159adc59b1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -672,7 +672,7 @@ SUFFIXES = .xml _generated.h _generated.c
 .xml_generated.h:
 	$(srcdir)/$(SBUS_CODEGEN) --mode=header --output=$@ $<
 .xml_generated.c:
-	$(srcdir)/$(SBUS_CODEGEN) --mode=source --output=$@ $<
+	$(srcdir)/$(SBUS_CODEGEN) --mode=source --include=$(@:.c=.h) --output=$@ $<
 
 # Regenerate when codegen changes
 CODEGEN_CODE = \
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index 9c0147e2b95141f5434445b1cac8827962580a35..6d26d1867750d38e4f70c25fd43ee7fe1abccb58 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -181,6 +181,7 @@ def source_methods(iface, methods):
             print "        %s__out," % meth.fq_c_name()
         else:
             print "        NULL, /* no out_args */"
+        print "        offsetof(struct %s, %s)," % (iface.c_name(), meth.c_name())
         print "    },"
     print "    { NULL, }"
     print "};"
@@ -249,7 +250,7 @@ def source_interface(iface):
     print "};"
     print
 
-def generate_source(ifaces, filename):
+def generate_source(ifaces, filename, include_header=None):
     basename = os.path.basename(filename)
 
     print "/* The following definitions are auto-generated from %s */" % basename
@@ -258,6 +259,8 @@ def generate_source(ifaces, filename):
     print "#include \"util/util.h\""
     print "#include \"sbus/sssd_dbus.h\""
     print "#include \"sbus/sssd_dbus_meta.h\""
+    if include_header:
+        print "#include \"%s\"" % include_header
     print
 
     for iface in ifaces:
@@ -277,6 +280,20 @@ def generate_source(ifaces, filename):
         # The sbus_interface structure
         source_interface(iface)
 
+def header_vtable(iface, methods):
+    print "/* vtable for %s */" % iface.name
+    print "struct %s {" % iface.c_name()
+    print "    struct sbus_vtable vtable; /* derive from sbus_vtable */"
+
+    # All methods
+    for meth in iface.methods:
+        print "    sbus_msg_handler_fn %s;" % meth.c_name()
+
+    # TODO: Property getters and setters will go here
+
+    print "};"
+    print
+
 def generate_header(ifaces, filename):
     basename = os.path.basename(filename)
     guard = "__%s__" % re.sub(r'([^_A-Z0-9])', "_", basename.upper())
@@ -290,6 +307,22 @@ def generate_header(ifaces, filename):
     print
 
     print "/* ------------------------------------------------------------------------"
+    print " * DBus Vtable handler structures"
+    print " *"
+    print " * These structures are filled in by implementors of the different"
+    print " * dbus interfaces to handle method calls."
+    print " *"
+    print " * Handler functions of type sbus_msg_handler_fn accept raw messages,"
+    print " * other handlers will be typed appropriately. If a handler that is"
+    print " * set to NULL is invoked it will result in a"
+    print " * org.freedesktop.DBus.Error.NotSupported error for the caller."
+    print " */"
+    print
+    for iface in ifaces:
+        if iface.methods:
+            header_vtable(iface, iface.methods)
+
+    print "/* ------------------------------------------------------------------------"
     print " * DBus Interface Metadata"
     print " *"
     print " * These structure definitions are filled in with the information about"
@@ -465,6 +498,10 @@ def parse_options():
                       dest="output", default=None,
                       help="Set output file name (default: stdout)",
                       metavar="FILE")
+    parser.add_option("--include",
+                      dest="include", default=None,
+                      help="name of a header to #include",
+                      metavar="HEADER")
     (options, args) = parser.parse_args()
 
     if not args:
@@ -488,7 +525,7 @@ def main():
         if options.mode == "header":
             generate_header(parser.parsed_interfaces, filename)
         elif options.mode == "source":
-            generate_source(parser.parsed_interfaces, filename)
+            generate_source(parser.parsed_interfaces, filename, options.include)
         else:
             assert False, "should not be reached"
 
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index 7604797c1f8ef74deacacec2251606650ee2402d..e9e7c98672e17c1a90bf688b1edfbc243392632e 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -55,6 +55,21 @@ enum {
     SBUS_RECONNECT_ERROR
 };
 
+/*
+ * This represents vtable of interface handlers for methods and
+ * properties and so on. The actual vtable structs derive from this struct
+ * (ie: have this struct as their first member).
+ *
+ * The offsets for matching vtable function pointers are in sbus_method_meta
+ * These are used to dynamically dispatch the method invocations.
+ */
+struct sbus_vtable {
+    const struct sbus_interface_meta *meta;
+    int flags; /* unused for now */
+
+    /* derived structs place function pointers here. */
+};
+
 /* Special interface and method for D-BUS introspection */
 #define DBUS_INTROSPECT_INTERFACE "org.freedesktop.DBus.Introspectable"
 #define DBUS_INTROSPECT_METHOD "Introspect"
diff --git a/src/sbus/sssd_dbus_meta.h b/src/sbus/sssd_dbus_meta.h
index 17ea7a5076ba8ed960b954035ab584ebd1bd4f88..abc992137811be6c6930ff86831a03f7b43fb485 100644
--- a/src/sbus/sssd_dbus_meta.h
+++ b/src/sbus/sssd_dbus_meta.h
@@ -42,6 +42,7 @@ struct sbus_method_meta {
     const char *name;
     const struct sbus_arg_meta *in_args;
     const struct sbus_arg_meta *out_args;
+    size_t vtable_offset;
 };
 
 enum {
diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c
index c098799872425b03a0c8c8b616da906b02f68722..36ce6fbaf3d8916d815d73fdfcb5844ca73c1a3c 100644
--- a/src/tests/sbus_codegen_tests.c
+++ b/src/tests/sbus_codegen_tests.c
@@ -115,6 +115,38 @@ START_TEST(test_signals)
 }
 END_TEST
 
+static int
+mock_move_universe(DBusMessage *msg, struct sbus_connection *conn)
+{
+    /* not called */
+    return 0;
+}
+
+static int
+mock_crash_now(DBusMessage *msg, struct sbus_connection *conn)
+{
+    /* not called */
+    return 0;
+}
+
+START_TEST(test_vtable)
+{
+    struct com_planetexpress_Ship vtable = {
+        { &com_planetexpress_Ship_meta, 0 },
+        mock_move_universe,
+        mock_crash_now,
+    };
+
+    /*
+     * These are not silly tests:
+     * - Will fail compilation if c-symbol name was not respected
+     * - Will fail if method order was not respected
+     */
+    ck_assert(vtable.crash_now == mock_crash_now);
+    ck_assert(vtable.MoveUniverse == mock_move_universe);
+}
+END_TEST
+
 Suite *create_suite(void)
 {
     Suite *s = suite_create("sbus_codegen");
@@ -126,6 +158,7 @@ Suite *create_suite(void)
     tcase_add_test(tc, test_methods);
     tcase_add_test(tc, test_properties);
     tcase_add_test(tc, test_signals);
+    tcase_add_test(tc, test_vtable);
 
     /* Add all test cases to the test suite */
     suite_add_tcase(s, tc);
diff --git a/src/tests/sbus_codegen_tests.xml b/src/tests/sbus_codegen_tests.xml
index 0def3585a973ef1d7fdef198d8ed8bf5e84c209c..e571dbc17b9e5c0e065d2ab87fb37458072f10b0 100755
--- a/src/tests/sbus_codegen_tests.xml
+++ b/src/tests/sbus_codegen_tests.xml
@@ -29,6 +29,11 @@
         <signal name="BecameSentient">
             <arg name="gender" type="s"/>
         </signal>
+
+        <!-- A method with a specific c name -->
+        <method name="Crash">
+            <annotation value="crash_now" name="org.freedesktop.DBus.GLib.CSymbol"/>
+        </method>
     </interface>
 
     <!--
diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c
index 556eea12c8f16103e3a14bdbd955e62dbc346351..932c89e86f71c61ef33848b411df4b00d4b8d900 100644
--- a/src/tests/sbus_codegen_tests_generated.c
+++ b/src/tests/sbus_codegen_tests_generated.c
@@ -3,6 +3,7 @@
 #include "util/util.h"
 #include "sbus/sssd_dbus.h"
 #include "sbus/sssd_dbus_meta.h"
+#include "../src/tests/sbus_codegen_tests_generated.h"
 
 /* arguments for com.planetexpress.Ship.MoveUniverse */
 const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__in[] = {
@@ -23,6 +24,13 @@ const struct sbus_method_meta com_planetexpress_Ship__methods[] = {
         "MoveUniverse", /* name */
         com_planetexpress_Ship_MoveUniverse__in,
         com_planetexpress_Ship_MoveUniverse__out,
+        offsetof(struct com_planetexpress_Ship, MoveUniverse),
+    },
+    {
+        "Crash", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct com_planetexpress_Ship, crash_now),
     },
     { NULL, }
 };
diff --git a/src/tests/sbus_codegen_tests_generated.h b/src/tests/sbus_codegen_tests_generated.h
index 56911ddefefcccfd7eaf90edf3677278ed8dcef4..c3ff78db3a03f117542b5b8f1b1952a6d944c9bb 100644
--- a/src/tests/sbus_codegen_tests_generated.h
+++ b/src/tests/sbus_codegen_tests_generated.h
@@ -6,6 +6,25 @@
 #include "sbus/sssd_dbus.h"
 
 /* ------------------------------------------------------------------------
+ * DBus Vtable handler structures
+ *
+ * These structures are filled in by implementors of the different
+ * dbus interfaces to handle method calls.
+ *
+ * Handler functions of type sbus_msg_handler_fn accept raw messages,
+ * other handlers will be typed appropriately. If a handler that is
+ * set to NULL is invoked it will result in a
+ * org.freedesktop.DBus.Error.NotSupported error for the caller.
+ */
+
+/* vtable for com.planetexpress.Ship */
+struct com_planetexpress_Ship {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    sbus_msg_handler_fn MoveUniverse;
+    sbus_msg_handler_fn crash_now;
+};
+
+/* ------------------------------------------------------------------------
  * DBus Interface Metadata
  *
  * These structure definitions are filled in with the information about
-- 
1.8.5.3

-------------- next part --------------
>From b936c8477910c1459d092e40af88095830a7f3bc Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Fri, 10 Jan 2014 11:50:43 +0100
Subject: [PATCH 3/6] nss: Stop using one DBus interface with totally different
 methods

This is an incorrect use of DBus, where we use a single interface
name with completely different sets of methods.

Easily fixed.

Once the vtable stuff is in use then this would be automatically
detected and fail to build.
---
 src/providers/data_provider.h    | 1 +
 src/providers/data_provider_be.c | 2 +-
 src/responder/nss/nsssrv.c       | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index f88637c2d3dbd9bd9df8a94493c229fe75b48f41..c33445c9ead27638845e67f428c64f92879835a4 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -60,6 +60,7 @@
 /* this is a reverse method sent from providers to
  * the nss responder to tell it to update the mmap
  * cache */
+#define DP_REV_INTERFACE "org.freedesktop.sssd.dataprovider_rev"
 #define DP_REV_METHOD_UPDATE_CACHE "updateCache"
 #define DP_REV_METHOD_INITGR_CHECK "initgrCheck"
 
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index bfb776cae15cfe280ec315b36ef32213b1d8d5e1..2e64226938f84b79cdc462379cbe4c5b621ba1db 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -857,7 +857,7 @@ static void acctinfo_initgroups_callback(struct be_req *be_req,
     /* Set up null request */
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
+                                       DP_REV_INTERFACE,
                                        DP_REV_METHOD_INITGR_CHECK);
     if (!msg) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 9d0c9969a0c6472f8dd4f3239003f59a32ece36a..d258dfc71f635d3c7a88ea525f278e48e2ba427b 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -379,7 +379,7 @@ static struct sbus_method nss_dp_methods[] = {
 };
 
 struct sbus_interface nss_dp_interface = {
-    DP_INTERFACE,
+    DP_REV_INTERFACE,
     DP_PATH,
     SBUS_DEFAULT_VTABLE,
     nss_dp_methods,
-- 
1.8.5.3

-------------- next part --------------
>From 20d07b4e9374f94e03d59e4437cd8f2aa99d283b Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Fri, 10 Jan 2014 08:58:12 +0100
Subject: [PATCH 4/6] sbus: Rework sbus to use interface metadata and vtables

Previous commits added support for interface metadata and
handler vtables. This commit ports sbus_dbus_connection to
use them.

Port the internal uses of dbus to use the new scheme in a
very minimal way. Further cleanup is possible here.

This commit provides basic definitions of the internal
dbus interfaces. The interfaces aren't fully defined, as the
handlers will continue to unpack manually, and often overload
DBus methods with different arguments (which is rather
unorthodox, but not the end of the world).
---
 Makefile.am                                   | 30 +++++++--
 src/monitor/monitor.c                         | 12 ++--
 src/monitor/monitor_iface.xml                 | 41 ++++++++++++
 src/monitor/monitor_iface_generated.c         | 92 +++++++++++++++++++++++++++
 src/monitor/monitor_iface_generated.h         | 57 +++++++++++++++++
 src/monitor/monitor_interfaces.h              |  2 +
 src/providers/data_provider.h                 |  1 +
 src/providers/data_provider_be.c              | 43 ++++++-------
 src/providers/data_provider_iface.xml         | 38 +++++++++++
 src/providers/data_provider_iface_generated.c | 86 +++++++++++++++++++++++++
 src/providers/data_provider_iface_generated.h | 56 ++++++++++++++++
 src/providers/proxy/proxy_child.c             | 16 +++--
 src/providers/proxy/proxy_init.c              | 16 +++--
 src/responder/autofs/autofssrv.c              | 35 ++++++----
 src/responder/nss/nsssrv.c                    | 33 +++++-----
 src/responder/pac/pacsrv.c                    | 34 ++++++----
 src/responder/pam/pamsrv.c                    | 34 ++++++----
 src/responder/ssh/sshsrv.c                    | 34 ++++++----
 src/responder/sudo/sudosrv.c                  | 34 ++++++----
 src/sbus/sssd_dbus.h                          | 11 +---
 src/sbus/sssd_dbus_connection.c               | 69 +++++++++++++-------
 21 files changed, 611 insertions(+), 163 deletions(-)
 create mode 100644 src/monitor/monitor_iface.xml
 create mode 100644 src/monitor/monitor_iface_generated.c
 create mode 100644 src/monitor/monitor_iface_generated.h
 create mode 100644 src/providers/data_provider_iface.xml
 create mode 100644 src/providers/data_provider_iface_generated.c
 create mode 100644 src/providers/data_provider_iface_generated.h

diff --git a/Makefile.am b/Makefile.am
index 836f2067e54ab3a24f23e9a081d6e7159adc59b1..8fbb009499f882b9a62192e01679d9c7802fa363 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -319,7 +319,11 @@ SSSD_RESPONDER_OBJ = \
     src/responder/common/responder_common.c \
     src/responder/common/responder_dp.c \
     src/responder/common/responder_packet.c \
-    src/responder/common/responder_get_domains.c
+    src/responder/common/responder_get_domains.c \
+    src/monitor/monitor_iface_generated.c \
+    src/monitor/monitor_iface_generated.h \
+    src/providers/data_provider_iface_generated.c \
+    src/providers/data_provider_iface_generated.h
 
 SSSD_TOOLS_OBJ = \
     src/tools/sss_sync_ops.c \
@@ -659,7 +663,9 @@ include_HEADERS = \
 # Yes, the goal here is that the generated files end up in $(srcdir)
 # not $(builddir). Always use $(srcdir) here.
 CODEGEN_XML = \
-    $(srcdir)/src/tests/sbus_codegen_tests.xml
+    $(srcdir)/src/tests/sbus_codegen_tests.xml \
+    $(srcdir)/src/monitor/monitor_iface.xml \
+    $(srcdir)/src/providers/data_provider_iface.xml
 
 SBUS_CODEGEN = src/sbus/sbus_codegen
 
@@ -690,7 +696,9 @@ sssd_SOURCES = \
     src/monitor/monitor.c \
     src/monitor/monitor_netlink.c \
     src/confdb/confdb_setup.c \
-    src/util/nscd.c
+    src/util/nscd.c \
+    src/monitor/monitor_iface_generated.c \
+    src/monitor/monitor_iface_generated.h
 sssd_LDADD = \
     $(SSSD_LIBS) \
     $(INOTIFY_LIBS) \
@@ -783,6 +791,10 @@ sssd_be_SOURCES = \
     src/providers/dp_dyndns.c \
     src/providers/dp_ptask.c \
     src/providers/dp_refresh.c \
+    src/monitor/monitor_iface_generated.c \
+    src/monitor/monitor_iface_generated.h \
+    src/providers/data_provider_iface_generated.c \
+    src/providers/data_provider_iface_generated.h \
     $(SSSD_FAILOVER_OBJ)
 sssd_be_LDADD = \
     $(LIBADD_DL) \
@@ -1192,6 +1204,10 @@ simple_access_tests_SOURCES = \
     src/providers/data_provider_callbacks.c \
     src/providers/dp_ptask.c \
     src/providers/dp_refresh.c \
+    src/monitor/monitor_iface_generated.c \
+    src/monitor/monitor_iface_generated.h \
+    src/providers/data_provider_iface_generated.c \
+    src/providers/data_provider_iface_generated.h \
     $(SSSD_FAILOVER_OBJ)
 simple_access_tests_CFLAGS = \
     $(AM_CFLAGS) \
@@ -1752,7 +1768,9 @@ libsss_proxy_la_SOURCES = \
     src/providers/proxy/proxy_id.c \
     src/providers/proxy/proxy_netgroup.c \
     src/providers/proxy/proxy_services.c \
-    src/providers/proxy/proxy_auth.c
+    src/providers/proxy/proxy_auth.c \
+    src/providers/data_provider_iface_generated.c \
+    src/providers/data_provider_iface_generated.h
 libsss_proxy_la_CFLAGS = \
     $(AM_CFLAGS)
 libsss_proxy_la_LIBADD = \
@@ -1946,7 +1964,9 @@ ldap_child_LDADD = \
     $(KRB5_LIBS)
 
 proxy_child_SOURCES = \
-    src/providers/proxy/proxy_child.c
+    src/providers/proxy/proxy_child.c \
+    src/providers/data_provider_iface_generated.c \
+    src/providers/data_provider_iface_generated.h
 proxy_child_CFLAGS = \
     $(AM_CFLAGS) \
     $(POPT_CFLAGS)
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 8a0844bbca5bb0e502c1988458758ecd41cccc3f..c2e5a5af627b7d543533c3da8d620a38e93aeadc 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -523,17 +523,15 @@ static int add_services_startup_timeout(struct mt_ctx *ctx)
     return EOK;
 }
 
-struct sbus_method monitor_methods[] = {
-    { MON_SRV_METHOD_VERSION, get_monitor_version },
-    { MON_SRV_METHOD_REGISTER, client_registration },
-    { NULL, NULL }
+struct mon_srv_iface monitor_methods = {
+    { &mon_srv_iface_meta, 0 },
+    .getVersion = get_monitor_version,
+    .RegisterService = client_registration,
 };
 
 struct sbus_interface monitor_server_interface = {
-    MON_SRV_INTERFACE,
     MON_SRV_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_methods,
+    &monitor_methods.vtable,
     NULL
 };
 
diff --git a/src/monitor/monitor_iface.xml b/src/monitor/monitor_iface.xml
new file mode 100644
index 0000000000000000000000000000000000000000..506b749c8a12b2c137b433e168beaf38f0b2c97f
--- /dev/null
+++ b/src/monitor/monitor_iface.xml
@@ -0,0 +1,41 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+    <interface name="org.freedesktop.sssd.monitor">
+        <annotation value="mon_srv_iface" name="org.freedesktop.DBus.GLib.CSymbol"/>
+        <method name="getVersion">
+            <!-- manual argument parsing -->
+        </method>
+        <method name="RegisterService">
+            <!-- manual argument parsing -->
+        </method>
+    </interface>
+
+    <interface name="org.freedesktop.sssd.service">
+        <annotation value="mon_cli_iface" name="org.freedesktop.DBus.GLib.CSymbol"/>
+        <method name="ping">
+            <!-- no arguments -->
+        </method>
+        <method name="resInit">
+            <!-- no arguments -->
+        </method>
+        <method name="shutDown">
+            <!-- no arguments -->
+        </method>
+        <method name="goOffline">
+            <!-- no arguments -->
+        </method>
+        <method name="resetOffline">
+            <!-- no arguments -->
+        </method>
+        <method name="rotateLogs">
+            <!-- no arguments -->
+        </method>
+        <method name="clearMemcache">
+            <!-- no arguments -->
+        </method>
+        <method name="clearEnumCache">
+            <!-- no arguments -->
+        </method>
+    </interface>
+</node>
diff --git a/src/monitor/monitor_iface_generated.c b/src/monitor/monitor_iface_generated.c
new file mode 100644
index 0000000000000000000000000000000000000000..41a52c066fb8a10058da330f4f3ea4f851a5ecba
--- /dev/null
+++ b/src/monitor/monitor_iface_generated.c
@@ -0,0 +1,92 @@
+/* The following definitions are auto-generated from monitor_iface.xml */
+
+#include "util/util.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus/sssd_dbus_meta.h"
+#include "../src/monitor/monitor_iface_generated.h"
+
+/* methods for org.freedesktop.sssd.monitor */
+const struct sbus_method_meta mon_srv_iface__methods[] = {
+    {
+        "getVersion", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_srv_iface, getVersion),
+    },
+    {
+        "RegisterService", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_srv_iface, RegisterService),
+    },
+    { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.monitor */
+const struct sbus_interface_meta mon_srv_iface_meta = {
+    "org.freedesktop.sssd.monitor", /* name */
+    mon_srv_iface__methods,
+    NULL, /* no signals */
+    NULL, /* no propetries */
+};
+
+/* methods for org.freedesktop.sssd.service */
+const struct sbus_method_meta mon_cli_iface__methods[] = {
+    {
+        "ping", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, ping),
+    },
+    {
+        "resInit", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, resInit),
+    },
+    {
+        "shutDown", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, shutDown),
+    },
+    {
+        "goOffline", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, goOffline),
+    },
+    {
+        "resetOffline", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, resetOffline),
+    },
+    {
+        "rotateLogs", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, rotateLogs),
+    },
+    {
+        "clearMemcache", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, clearMemcache),
+    },
+    {
+        "clearEnumCache", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct mon_cli_iface, clearEnumCache),
+    },
+    { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.service */
+const struct sbus_interface_meta mon_cli_iface_meta = {
+    "org.freedesktop.sssd.service", /* name */
+    mon_cli_iface__methods,
+    NULL, /* no signals */
+    NULL, /* no propetries */
+};
diff --git a/src/monitor/monitor_iface_generated.h b/src/monitor/monitor_iface_generated.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a24f733e9f41612bce3e73a0c451b4916608572
--- /dev/null
+++ b/src/monitor/monitor_iface_generated.h
@@ -0,0 +1,57 @@
+/* The following declarations are auto-generated from monitor_iface.xml */
+
+#ifndef __MONITOR_IFACE_XML__
+#define __MONITOR_IFACE_XML__
+
+#include "sbus/sssd_dbus.h"
+
+/* ------------------------------------------------------------------------
+ * DBus Vtable handler structures
+ *
+ * These structures are filled in by implementors of the different
+ * dbus interfaces to handle method calls.
+ *
+ * Handler functions of type sbus_msg_handler_fn accept raw messages,
+ * other handlers will be typed appropriately. If a handler that is
+ * set to NULL is invoked it will result in a
+ * org.freedesktop.DBus.Error.NotSupported error for the caller.
+ */
+
+/* vtable for org.freedesktop.sssd.monitor */
+struct mon_srv_iface {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    sbus_msg_handler_fn getVersion;
+    sbus_msg_handler_fn RegisterService;
+};
+
+/* vtable for org.freedesktop.sssd.service */
+struct mon_cli_iface {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    sbus_msg_handler_fn ping;
+    sbus_msg_handler_fn resInit;
+    sbus_msg_handler_fn shutDown;
+    sbus_msg_handler_fn goOffline;
+    sbus_msg_handler_fn resetOffline;
+    sbus_msg_handler_fn rotateLogs;
+    sbus_msg_handler_fn clearMemcache;
+    sbus_msg_handler_fn clearEnumCache;
+};
+
+/* ------------------------------------------------------------------------
+ * DBus Interface Metadata
+ *
+ * These structure definitions are filled in with the information about
+ * the interfaces, methods, properties and so on.
+ *
+ * The actual definitions are found in the accompanying C file next
+ * to this header.
+ */
+
+/* interface info for org.freedesktop.sssd.monitor */
+extern const struct sbus_interface_meta mon_srv_iface_meta;
+
+/* interface info for org.freedesktop.sssd.service */
+extern const struct sbus_interface_meta mon_cli_iface_meta;
+
+
+#endif /* __MONITOR_IFACE_XML__ */
diff --git a/src/monitor/monitor_interfaces.h b/src/monitor/monitor_interfaces.h
index f27c7d00c9b920a463a7ea7ab3281422053ad5a6..308642f7859bb3a06856420db7a8552f4b5b76dd 100644
--- a/src/monitor/monitor_interfaces.h
+++ b/src/monitor/monitor_interfaces.h
@@ -21,6 +21,8 @@
 
 #include "sbus/sssd_dbus.h"
 
+#include "monitor/monitor_iface_generated.h"
+
 /*** Monitor ***/
 
 #define MONITOR_VERSION 0x0001
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index c33445c9ead27638845e67f428c64f92879835a4..714983032ca2fb7ad385c67210cdf722e3a2bb43 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -43,6 +43,7 @@
 #include "sbus/sbus_client.h"
 #include "sss_client/sss_cli.h"
 #include "util/authtok.h"
+#include "providers/data_provider_iface_generated.h"
 
 #define DATA_PROVIDER_VERSION 0x0001
 #define DATA_PROVIDER_PIPE "private/sbus-dp"
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 2e64226938f84b79cdc462379cbe4c5b621ba1db..67d52103203d18742c2940318bdcbcf240cbdbba 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -63,20 +63,21 @@ static int data_provider_reset_offline(DBusMessage *message,
 static int data_provider_logrotate(DBusMessage *message,
                                 struct sbus_connection *conn);
 
-struct sbus_method monitor_be_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, data_provider_res_init },
-    { MON_CLI_METHOD_OFFLINE, data_provider_go_offline },
-    { MON_CLI_METHOD_RESET_OFFLINE, data_provider_reset_offline },
-    { MON_CLI_METHOD_ROTATE, data_provider_logrotate },
-    { NULL, NULL }
+struct mon_cli_iface monitor_be_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = data_provider_res_init,
+    .shutDown = NULL,
+    .goOffline = data_provider_go_offline,
+    .resetOffline = data_provider_reset_offline,
+    .rotateLogs = data_provider_logrotate,
+    .clearMemcache = NULL,
+    .clearEnumCache = NULL,
 };
 
 struct sbus_interface monitor_be_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_be_methods,
+    &monitor_be_methods.vtable,
     NULL
 };
 
@@ -88,22 +89,20 @@ static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn)
 static int be_host_handler(DBusMessage *message, struct sbus_connection *conn);
 static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn);
 
-struct sbus_method be_methods[] = {
-    { DP_METHOD_REGISTER, client_registration },
-    { DP_METHOD_GETACCTINFO, be_get_account_info },
-    { DP_METHOD_PAMHANDLER, be_pam_handler },
-    { DP_METHOD_SUDOHANDLER, be_sudo_handler },
-    { DP_METHOD_AUTOFSHANDLER, be_autofs_handler },
-    { DP_METHOD_HOSTHANDLER, be_host_handler },
-    { DP_METHOD_GETDOMAINS, be_get_subdomains },
-    { NULL, NULL }
+struct data_provider_iface be_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = client_registration,
+    .pamHandler = be_pam_handler,
+    .sudoHandler = be_sudo_handler,
+    .autofsHandler = be_autofs_handler,
+    .hostHandler = be_host_handler,
+    .getDomains = be_get_subdomains,
+    .getAccountInfo = be_get_account_info,
 };
 
 struct sbus_interface be_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    be_methods,
+    &be_methods.vtable,
     NULL
 };
 
diff --git a/src/providers/data_provider_iface.xml b/src/providers/data_provider_iface.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1f349649316cdadfed747ff4b8bedddb27c3ec6f
--- /dev/null
+++ b/src/providers/data_provider_iface.xml
@@ -0,0 +1,38 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+    <interface name="org.freedesktop.sssd.dataprovider">
+        <annotation value="data_provider_iface" name="org.freedesktop.DBus.GLib.CSymbol"/>
+        <method name="RegisterService">
+            <!-- arguments parsed manually -->
+        </method>
+        <method name="pamHandler">
+            <!-- arguments parsed manually -->
+        </method>
+        <method name="sudoHandler">
+            <!-- arguments parsed manually -->
+        </method>
+        <method name="autofsHandler">
+            <!-- arguments parsed manually -->
+        </method>
+        <method name="hostHandler">
+            <!-- arguments parsed manually -->
+        </method>
+        <method name="getDomains">
+            <!-- arguments parsed manually -->
+        </method>
+        <method name="getAccountInfo">
+            <!-- arguments parsed manually -->
+        </method>
+    </interface>
+
+    <interface name="org.freedesktop.sssd.dataprovider_rev">
+        <annotation value="data_provider_rev_iface" name="org.freedesktop.DBus.GLib.CSymbol"/>
+        <method name="updateCache">
+            <!-- manual argument parsing -->
+        </method>
+        <method name="initgrCheck">
+            <!-- manual argument parsing -->
+        </method>
+    </interface>
+</node>
diff --git a/src/providers/data_provider_iface_generated.c b/src/providers/data_provider_iface_generated.c
new file mode 100644
index 0000000000000000000000000000000000000000..9003cd89ddd5b2f498d48158f788922aa71ca74a
--- /dev/null
+++ b/src/providers/data_provider_iface_generated.c
@@ -0,0 +1,86 @@
+/* The following definitions are auto-generated from data_provider_iface.xml */
+
+#include "util/util.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus/sssd_dbus_meta.h"
+#include "../src/providers/data_provider_iface_generated.h"
+
+/* methods for org.freedesktop.sssd.dataprovider */
+const struct sbus_method_meta data_provider_iface__methods[] = {
+    {
+        "RegisterService", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, RegisterService),
+    },
+    {
+        "pamHandler", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, pamHandler),
+    },
+    {
+        "sudoHandler", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, sudoHandler),
+    },
+    {
+        "autofsHandler", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, autofsHandler),
+    },
+    {
+        "hostHandler", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, hostHandler),
+    },
+    {
+        "getDomains", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, getDomains),
+    },
+    {
+        "getAccountInfo", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_iface, getAccountInfo),
+    },
+    { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.dataprovider */
+const struct sbus_interface_meta data_provider_iface_meta = {
+    "org.freedesktop.sssd.dataprovider", /* name */
+    data_provider_iface__methods,
+    NULL, /* no signals */
+    NULL, /* no propetries */
+};
+
+/* methods for org.freedesktop.sssd.dataprovider_rev */
+const struct sbus_method_meta data_provider_rev_iface__methods[] = {
+    {
+        "updateCache", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_rev_iface, updateCache),
+    },
+    {
+        "initgrCheck", /* name */
+        NULL, /* no in_args */
+        NULL, /* no out_args */
+        offsetof(struct data_provider_rev_iface, initgrCheck),
+    },
+    { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.dataprovider_rev */
+const struct sbus_interface_meta data_provider_rev_iface_meta = {
+    "org.freedesktop.sssd.dataprovider_rev", /* name */
+    data_provider_rev_iface__methods,
+    NULL, /* no signals */
+    NULL, /* no propetries */
+};
diff --git a/src/providers/data_provider_iface_generated.h b/src/providers/data_provider_iface_generated.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f485523a0b576ea9d4fa4cd01016ab286917ffc
--- /dev/null
+++ b/src/providers/data_provider_iface_generated.h
@@ -0,0 +1,56 @@
+/* The following declarations are auto-generated from data_provider_iface.xml */
+
+#ifndef __DATA_PROVIDER_IFACE_XML__
+#define __DATA_PROVIDER_IFACE_XML__
+
+#include "sbus/sssd_dbus.h"
+
+/* ------------------------------------------------------------------------
+ * DBus Vtable handler structures
+ *
+ * These structures are filled in by implementors of the different
+ * dbus interfaces to handle method calls.
+ *
+ * Handler functions of type sbus_msg_handler_fn accept raw messages,
+ * other handlers will be typed appropriately. If a handler that is
+ * set to NULL is invoked it will result in a
+ * org.freedesktop.DBus.Error.NotSupported error for the caller.
+ */
+
+/* vtable for org.freedesktop.sssd.dataprovider */
+struct data_provider_iface {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    sbus_msg_handler_fn RegisterService;
+    sbus_msg_handler_fn pamHandler;
+    sbus_msg_handler_fn sudoHandler;
+    sbus_msg_handler_fn autofsHandler;
+    sbus_msg_handler_fn hostHandler;
+    sbus_msg_handler_fn getDomains;
+    sbus_msg_handler_fn getAccountInfo;
+};
+
+/* vtable for org.freedesktop.sssd.dataprovider_rev */
+struct data_provider_rev_iface {
+    struct sbus_vtable vtable; /* derive from sbus_vtable */
+    sbus_msg_handler_fn updateCache;
+    sbus_msg_handler_fn initgrCheck;
+};
+
+/* ------------------------------------------------------------------------
+ * DBus Interface Metadata
+ *
+ * These structure definitions are filled in with the information about
+ * the interfaces, methods, properties and so on.
+ *
+ * The actual definitions are found in the accompanying C file next
+ * to this header.
+ */
+
+/* interface info for org.freedesktop.sssd.dataprovider */
+extern const struct sbus_interface_meta data_provider_iface_meta;
+
+/* interface info for org.freedesktop.sssd.dataprovider_rev */
+extern const struct sbus_interface_meta data_provider_rev_iface_meta;
+
+
+#endif /* __DATA_PROVIDER_IFACE_XML__ */
diff --git a/src/providers/proxy/proxy_child.c b/src/providers/proxy/proxy_child.c
index 52968651b3e5ce7ab3ad11d21f66ed7cfb7f1900..737b0cfd6f7cabb35f1911b95fadd901ce5ee64c 100644
--- a/src/providers/proxy/proxy_child.c
+++ b/src/providers/proxy/proxy_child.c
@@ -49,16 +49,20 @@
 
 static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn);
 
-struct sbus_method pc_methods[] = {
-    { DP_METHOD_PAMHANDLER, pc_pam_handler },
-    { NULL, NULL }
+struct data_provider_iface pc_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = NULL,
+    .pamHandler = pc_pam_handler,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface pc_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    pc_methods,
+    &pc_methods.vtable,
     NULL
 };
 
diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c
index ae73fe7025d9108824c2a56d32a65b8638d85bef..60ae4a950fd18648d13b7fe50ef73d9a398ad8d5 100644
--- a/src/providers/proxy/proxy_init.c
+++ b/src/providers/proxy/proxy_init.c
@@ -30,16 +30,20 @@
 static int client_registration(DBusMessage *message,
                                struct sbus_connection *conn);
 
-static struct sbus_method proxy_methods[] = {
-    { DP_METHOD_REGISTER, client_registration },
-    { NULL, NULL }
+static struct data_provider_iface proxy_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = client_registration,
+    .pamHandler = NULL,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface proxy_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    proxy_methods,
+    &proxy_methods.vtable,
     NULL
 };
 
diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c
index 12f318eee5ec2b1c0765cb4077a7c7f528918db7..5ce9ae0236d61b6b643cbc0682dc4bb53774b87f 100644
--- a/src/responder/autofs/autofssrv.c
+++ b/src/responder/autofs/autofssrv.c
@@ -32,31 +32,38 @@
 static int autofs_clean_hash_table(DBusMessage *message,
                                    struct sbus_connection *conn);
 
-struct sbus_method monitor_autofs_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
-    { MON_CLI_METHOD_ROTATE, responder_logrotate },
-    { MON_CLI_METHOD_CLEAR_ENUM_CACHE, autofs_clean_hash_table },
-    { NULL, NULL }
+struct mon_cli_iface monitor_autofs_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = monitor_common_res_init,
+    .shutDown = NULL,
+    .goOffline = NULL,
+    .resetOffline = NULL,
+    .rotateLogs = responder_logrotate,
+    .clearMemcache = NULL,
+    .clearEnumCache = autofs_clean_hash_table,
 };
 
 struct sbus_interface monitor_autofs_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_autofs_methods,
+    &monitor_autofs_methods.vtable,
     NULL
 };
 
-static struct sbus_method autofs_dp_methods[] = {
-    { NULL, NULL }
+static struct data_provider_iface autofs_dp_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = NULL,
+    .pamHandler = NULL,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface autofs_dp_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    autofs_dp_methods,
+    &autofs_dp_methods.vtable,
     NULL
 };
 
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index d258dfc71f635d3c7a88ea525f278e48e2ba427b..a385f2943e68022c0cc2fe8022000e9d8e8854d4 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -60,20 +60,21 @@ static int nss_clear_memcache(DBusMessage *message,
 static int nss_clear_netgroup_hash_table(DBusMessage *message,
                                          struct sbus_connection *conn);
 
-struct sbus_method monitor_nss_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
-    { MON_CLI_METHOD_ROTATE, responder_logrotate },
-    { MON_CLI_METHOD_CLEAR_MEMCACHE, nss_clear_memcache},
-    { MON_CLI_METHOD_CLEAR_ENUM_CACHE, nss_clear_netgroup_hash_table},
-    { NULL, NULL }
+struct mon_cli_iface monitor_nss_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = monitor_common_res_init,
+    .shutDown = NULL,
+    .goOffline = NULL,
+    .resetOffline = NULL,
+    .rotateLogs = responder_logrotate,
+    .clearMemcache = nss_clear_memcache,
+    .clearEnumCache = nss_clear_netgroup_hash_table
 };
 
 struct sbus_interface monitor_nss_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_nss_methods,
+    &monitor_nss_methods.vtable,
     NULL
 };
 
@@ -372,17 +373,15 @@ static int nss_memcache_initgr_check(DBusMessage *message,
     return EOK;
 }
 
-static struct sbus_method nss_dp_methods[] = {
-    { DP_REV_METHOD_UPDATE_CACHE, nss_update_memcache },
-    { DP_REV_METHOD_INITGR_CHECK, nss_memcache_initgr_check },
-    { NULL, NULL }
+static struct data_provider_rev_iface nss_dp_methods = {
+    { &data_provider_rev_iface_meta, 0 },
+    .updateCache = nss_update_memcache,
+    .initgrCheck = nss_memcache_initgr_check
 };
 
 struct sbus_interface nss_dp_interface = {
-    DP_REV_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    nss_dp_methods,
+    &nss_dp_methods.vtable,
     NULL
 };
 
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index 2fb94293cf611cea317384339b2ae7eb478b520d..04a6200e0d4dbb1cd3f84763bbff0783be9cfa0c 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -48,30 +48,38 @@
 #define DEFAULT_PAC_FD_LIMIT 8192
 #define DEFAULT_ALLOWED_UIDS "0"
 
-struct sbus_method monitor_pac_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
-    { MON_CLI_METHOD_ROTATE, responder_logrotate },
-    { NULL, NULL }
+struct mon_cli_iface monitor_pac_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = monitor_common_res_init,
+    .shutDown = NULL,
+    .goOffline = NULL,
+    .resetOffline = NULL,
+    .rotateLogs = responder_logrotate,
+    .clearMemcache = NULL,
+    .clearEnumCache = NULL,
 };
 
 struct sbus_interface monitor_pac_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_pac_methods,
+    &monitor_pac_methods.vtable,
     NULL
 };
 
-static struct sbus_method pac_dp_methods[] = {
-    { NULL, NULL }
+static struct data_provider_iface pac_dp_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = NULL,
+    .pamHandler = NULL,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface pac_dp_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    pac_dp_methods,
+    &pac_dp_methods.vtable,
     NULL
 };
 
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index 5f9844ebce0bfb8ee56d0aa16c17ab44e666282b..1fc9f62828cab2854eac8ea88949ee222b9ae0ce 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -47,30 +47,38 @@
 
 #define DEFAULT_PAM_FD_LIMIT 8192
 
-struct sbus_method monitor_pam_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
-    { MON_CLI_METHOD_ROTATE, responder_logrotate },
-    { NULL, NULL }
+struct mon_cli_iface monitor_pam_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = monitor_common_res_init,
+    .shutDown = NULL,
+    .goOffline = NULL,
+    .resetOffline = NULL,
+    .rotateLogs = responder_logrotate,
+    .clearMemcache = NULL,
+    .clearEnumCache = NULL,
 };
 
 struct sbus_interface monitor_pam_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_pam_methods,
+    &monitor_pam_methods.vtable,
     NULL
 };
 
-static struct sbus_method pam_dp_methods[] = {
-        { NULL, NULL }
+static struct data_provider_iface pam_dp_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = NULL,
+    .pamHandler = NULL,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface pam_dp_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    pam_dp_methods,
+    &pam_dp_methods.vtable,
     NULL
 };
 
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index ea943afda72fee18ed264a5bb4bfd2cc4bb69753..fb0738f6c8cfb62064659be210d59bfee54827cb 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -28,30 +28,38 @@
 #include "responder/ssh/sshsrv_private.h"
 #include "providers/data_provider.h"
 
-struct sbus_method monitor_ssh_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
-    { MON_CLI_METHOD_ROTATE, responder_logrotate },
-    { NULL, NULL }
+struct mon_cli_iface monitor_ssh_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = monitor_common_res_init,
+    .shutDown = NULL,
+    .goOffline = NULL,
+    .resetOffline = NULL,
+    .rotateLogs = responder_logrotate,
+    .clearMemcache = NULL,
+    .clearEnumCache = NULL,
 };
 
 struct sbus_interface monitor_ssh_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_ssh_methods,
+    &monitor_ssh_methods.vtable,
     NULL
 };
 
-static struct sbus_method ssh_dp_methods[] = {
-    { NULL, NULL }
+static struct data_provider_iface ssh_dp_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = NULL,
+    .pamHandler = NULL,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface ssh_dp_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    ssh_dp_methods,
+    &ssh_dp_methods.vtable,
     NULL
 };
 
diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c
index b821c96cd77b17438ed82eb14cfbad46e4bc7cb2..1ad260b3578373664da6aec135a9a3aaa62d4931 100644
--- a/src/responder/sudo/sudosrv.c
+++ b/src/responder/sudo/sudosrv.c
@@ -28,30 +28,38 @@
 #include "responder/sudo/sudosrv_private.h"
 #include "providers/data_provider.h"
 
-struct sbus_method monitor_sudo_methods[] = {
-    { MON_CLI_METHOD_PING, monitor_common_pong },
-    { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
-    { MON_CLI_METHOD_ROTATE, responder_logrotate },
-    { NULL, NULL }
+struct mon_cli_iface monitor_sudo_methods = {
+    { &mon_cli_iface_meta, 0 },
+    .ping = monitor_common_pong,
+    .resInit = monitor_common_res_init,
+    .shutDown = NULL,
+    .goOffline = NULL,
+    .resetOffline = NULL,
+    .rotateLogs = responder_logrotate,
+    .clearMemcache = NULL,
+    .clearEnumCache = NULL,
 };
 
 struct sbus_interface monitor_sudo_interface = {
-    MONITOR_INTERFACE,
     MONITOR_PATH,
-    SBUS_DEFAULT_VTABLE,
-    monitor_sudo_methods,
+    &monitor_sudo_methods.vtable,
     NULL
 };
 
-static struct sbus_method sudo_dp_methods[] = {
-    { NULL, NULL }
+static struct data_provider_iface sudo_dp_methods = {
+    { &data_provider_iface_meta, 0 },
+    .RegisterService = NULL,
+    .pamHandler = NULL,
+    .sudoHandler = NULL,
+    .autofsHandler = NULL,
+    .hostHandler = NULL,
+    .getDomains = NULL,
+    .getAccountInfo = NULL,
 };
 
 struct sbus_interface sudo_dp_interface = {
-    DP_INTERFACE,
     DP_PATH,
-    SBUS_DEFAULT_VTABLE,
-    sudo_dp_methods,
+    &sudo_dp_methods.vtable,
     NULL
 };
 
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index e9e7c98672e17c1a90bf688b1edfbc243392632e..7d00b94d0f805e065b46d729aa6a5ef15aa57b3d 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -74,18 +74,9 @@ struct sbus_vtable {
 #define DBUS_INTROSPECT_INTERFACE "org.freedesktop.DBus.Introspectable"
 #define DBUS_INTROSPECT_METHOD "Introspect"
 
-#define SBUS_DEFAULT_VTABLE { NULL, sbus_message_handler, NULL, NULL, NULL, NULL }
-
-struct sbus_method {
-    const char *method;
-    sbus_msg_handler_fn fn;
-};
-
 struct sbus_interface {
-    const char *interface;
     const char *path;
-    DBusObjectPathVTable vtable;
-    struct sbus_method *methods;
+    struct sbus_vtable *vtable;
     sbus_msg_handler_fn introspect_fn;
 };
 
diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c
index eb07b8d5b6792144c20a6db9956fd202e3ea4541..09a4bf47eb9c43d136c7d84c965a8a86d412a847 100644
--- a/src/sbus/sssd_dbus_connection.c
+++ b/src/sbus/sssd_dbus_connection.c
@@ -25,10 +25,14 @@
 #include "util/util.h"
 #include "sbus/sssd_dbus.h"
 #include "sbus/sssd_dbus_private.h"
+#include "sbus/sssd_dbus_meta.h"
 
 /* Types */
 struct dbus_ctx_list;
 
+static DBusObjectPathVTable dbus_object_path_vtable =
+    { NULL, sbus_message_handler, NULL, NULL, NULL, NULL };
+
 struct sbus_interface_p {
     struct sbus_interface_p *prev, *next;
     struct sbus_connection *conn;
@@ -394,6 +398,10 @@ static int sbus_reply_internal_error(DBusMessage *message,
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
+/* Looks up a vtable func, in a struct derived from struct sbus_vtable */
+#define VTABLE_FUNC(vtable, offset) \
+    (*((void **)((char *)(vtable) + (offset))))
+
 /* messsage_handler
  * Receive messages and process them
  */
@@ -402,24 +410,26 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn,
                                          void *user_data)
 {
     struct sbus_interface_p *intf_p;
-    const char *method;
+    const char *msg_method;
     const char *path;
     const char *msg_interface;
     DBusMessage *reply = NULL;
-    int i, ret;
-    int found;
+    const struct sbus_method_meta *method;
+    const struct sbus_interface_meta *interface;
+    sbus_msg_handler_fn handler_fn;
+    int ret;
 
     if (!user_data) {
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
     intf_p = talloc_get_type(user_data, struct sbus_interface_p);
 
-    method = dbus_message_get_member(message);
-    DEBUG(SSSDBG_TRACE_ALL, "Received SBUS method [%s]\n", method);
+    msg_method = dbus_message_get_member(message);
+    DEBUG(SSSDBG_TRACE_ALL, "Received SBUS method [%s]\n", msg_method);
     path = dbus_message_get_path(message);
     msg_interface = dbus_message_get_interface(message);
 
-    if (!method || !path || !msg_interface)
+    if (!msg_method || !path || !msg_interface)
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
     /* Validate the D-BUS path */
@@ -427,26 +437,35 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn,
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
     /* Validate the method interface */
-    if (strcmp(msg_interface, intf_p->intf->interface) == 0) {
-        found = 0;
-        for (i = 0; intf_p->intf->methods[i].method != NULL; i++) {
-            if (strcmp(method, intf_p->intf->methods[i].method) == 0) {
-                found = 1;
-                ret = intf_p->intf->methods[i].fn(message, intf_p->conn);
-                if (ret != EOK) {
-                    return sbus_reply_internal_error(message, intf_p->conn);
-                }
-                break;
-            }
-        }
+    interface = intf_p->intf->vtable->meta;
+    if (strcmp(msg_interface, interface->name) == 0) {
+        handler_fn = NULL;
+        method = sbus_meta_find_method(interface, msg_method);
+        if (method && method->vtable_offset)
+            handler_fn = VTABLE_FUNC(intf_p->intf->vtable,
+                                     method->vtable_offset);
 
-        if (!found) {
+        if (!method) {
             /* Reply DBUS_ERROR_UNKNOWN_METHOD */
             DEBUG(SSSDBG_CRIT_FAILURE,
-                  "No matching method found for %s.\n", method);
+                  "No matching method found for %s.\n", msg_method);
             reply = dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, NULL);
             sbus_conn_send_reply(intf_p->conn, reply);
             dbus_message_unref(reply);
+
+        } else if (!handler_fn) {
+            /* Reply DBUS_ERROR_NOT_SUPPORTED */
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "No matching handler found for %s.\n", msg_method);
+            reply = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED,
+                                           NULL);
+            sbus_conn_send_reply(intf_p->conn, reply);
+            dbus_message_unref(reply);
+
+        } else {
+            ret = handler_fn(message, intf_p->conn);
+            if (ret != EOK)
+                return sbus_reply_internal_error(message, intf_p->conn);
         }
     }
     else {
@@ -454,7 +473,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn,
          * This is usually only useful for system bus connections
          */
         if (strcmp(msg_interface, DBUS_INTROSPECT_INTERFACE) == 0 &&
-            strcmp(method, DBUS_INTROSPECT_METHOD) == 0)
+            strcmp(msg_method, DBUS_INTROSPECT_METHOD) == 0)
         {
             if (intf_p->intf->introspect_fn) {
                 /* If we have been asked for introspection data and we have
@@ -483,7 +502,7 @@ int sbus_conn_add_interface(struct sbus_connection *conn,
     dbus_bool_t dbret;
     const char *path;
 
-    if (!conn || !intf || !intf->vtable.message_function) {
+    if (!conn || !intf || !intf->vtable || !intf->vtable->meta) {
         return EINVAL;
     }
 
@@ -505,7 +524,9 @@ int sbus_conn_add_interface(struct sbus_connection *conn,
     DLIST_ADD(conn->intf_list, intf_p);
 
     dbret = dbus_connection_register_object_path(conn->dbus.conn,
-                                                 path, &intf->vtable, intf_p);
+                                                 path,
+                                                 &dbus_object_path_vtable,
+                                                 intf_p);
     if (!dbret) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               "Could not register object path to the connection.\n");
@@ -586,7 +607,7 @@ static void sbus_reconnect(struct tevent_context *ev,
         while (iter) {
             dbret = dbus_connection_register_object_path(conn->dbus.conn,
                                                          iter->intf->path,
-                                                         &iter->intf->vtable,
+                                                         &dbus_object_path_vtable,
                                                          iter);
             if (!dbret) {
                 DEBUG(SSSDBG_FATAL_FAILURE,
-- 
1.8.5.3

-------------- next part --------------
>From 63205371845f2158f3d50cfdda6b28d3a3d2aa71 Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Fri, 10 Jan 2014 11:08:16 +0100
Subject: [PATCH 5/6] sbus: Generate constants from interface definitions

This is not strictly necessary, but avoids duplicating data
in mulitple places, and makes the interface definitions
benefit dbus callers (a little).

After applying this commit you may need to 'make clean' as
the codegen has changed.
---
 src/monitor/monitor_iface_generated.h         | 22 ++++++++++++++++++++++
 src/providers/data_provider_iface_generated.h | 21 +++++++++++++++++++++
 src/sbus/sbus_codegen                         | 21 +++++++++++++++++++++
 src/tests/sbus_codegen_tests.c                | 15 +++++++++++++++
 src/tests/sbus_codegen_tests_generated.h      | 17 +++++++++++++++++
 5 files changed, 96 insertions(+)

diff --git a/src/monitor/monitor_iface_generated.h b/src/monitor/monitor_iface_generated.h
index 5a24f733e9f41612bce3e73a0c451b4916608572..567d35fe7fbfaf201c20a772cd1f876e90540208 100644
--- a/src/monitor/monitor_iface_generated.h
+++ b/src/monitor/monitor_iface_generated.h
@@ -6,6 +6,28 @@
 #include "sbus/sssd_dbus.h"
 
 /* ------------------------------------------------------------------------
+ * DBus Constants
+ *
+ * Various constants of interface and method names mostly for use by clients
+ */
+
+/* constants for org.freedesktop.sssd.monitor */
+#define MON_SRV_IFACE "org.freedesktop.sssd.monitor"
+#define MON_SRV_IFACE_GETVERSION "getVersion"
+#define MON_SRV_IFACE_REGISTERSERVICE "RegisterService"
+
+/* constants for org.freedesktop.sssd.service */
+#define MON_CLI_IFACE "org.freedesktop.sssd.service"
+#define MON_CLI_IFACE_PING "ping"
+#define MON_CLI_IFACE_RESINIT "resInit"
+#define MON_CLI_IFACE_SHUTDOWN "shutDown"
+#define MON_CLI_IFACE_GOOFFLINE "goOffline"
+#define MON_CLI_IFACE_RESETOFFLINE "resetOffline"
+#define MON_CLI_IFACE_ROTATELOGS "rotateLogs"
+#define MON_CLI_IFACE_CLEARMEMCACHE "clearMemcache"
+#define MON_CLI_IFACE_CLEARENUMCACHE "clearEnumCache"
+
+/* ------------------------------------------------------------------------
  * DBus Vtable handler structures
  *
  * These structures are filled in by implementors of the different
diff --git a/src/providers/data_provider_iface_generated.h b/src/providers/data_provider_iface_generated.h
index 4f485523a0b576ea9d4fa4cd01016ab286917ffc..01165e848356dddec61d4ab2493a33808e57eaec 100644
--- a/src/providers/data_provider_iface_generated.h
+++ b/src/providers/data_provider_iface_generated.h
@@ -6,6 +6,27 @@
 #include "sbus/sssd_dbus.h"
 
 /* ------------------------------------------------------------------------
+ * DBus Constants
+ *
+ * Various constants of interface and method names mostly for use by clients
+ */
+
+/* constants for org.freedesktop.sssd.dataprovider */
+#define DATA_PROVIDER_IFACE "org.freedesktop.sssd.dataprovider"
+#define DATA_PROVIDER_IFACE_REGISTERSERVICE "RegisterService"
+#define DATA_PROVIDER_IFACE_PAMHANDLER "pamHandler"
+#define DATA_PROVIDER_IFACE_SUDOHANDLER "sudoHandler"
+#define DATA_PROVIDER_IFACE_AUTOFSHANDLER "autofsHandler"
+#define DATA_PROVIDER_IFACE_HOSTHANDLER "hostHandler"
+#define DATA_PROVIDER_IFACE_GETDOMAINS "getDomains"
+#define DATA_PROVIDER_IFACE_GETACCOUNTINFO "getAccountInfo"
+
+/* constants for org.freedesktop.sssd.dataprovider_rev */
+#define DATA_PROVIDER_REV_IFACE "org.freedesktop.sssd.dataprovider_rev"
+#define DATA_PROVIDER_REV_IFACE_UPDATECACHE "updateCache"
+#define DATA_PROVIDER_REV_IFACE_INITGRCHECK "initgrCheck"
+
+/* ------------------------------------------------------------------------
  * DBus Vtable handler structures
  *
  * These structures are filled in by implementors of the different
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index 6d26d1867750d38e4f70c25fd43ee7fe1abccb58..17ae291421dadb95a8b308647083236495f58594 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -294,6 +294,17 @@ def header_vtable(iface, methods):
     print "};"
     print
 
+def header_constants(iface):
+    print "/* constants for %s */" % iface.name
+    print "#define %s \"%s\"" % (iface.c_name().upper(), iface.name)
+    for meth in iface.methods:
+        print "#define %s \"%s\"" % (meth.fq_c_name().upper(), meth.name)
+    for sig in iface.signals:
+        print "#define %s \"%s\"" % (sig.fq_c_name().upper(), sig.name)
+    for prop in iface.properties:
+        print "#define %s \"%s\"" % (prop.fq_c_name().upper(), prop.name)
+    print
+
 def generate_header(ifaces, filename):
     basename = os.path.basename(filename)
     guard = "__%s__" % re.sub(r'([^_A-Z0-9])', "_", basename.upper())
@@ -307,6 +318,16 @@ def generate_header(ifaces, filename):
     print
 
     print "/* ------------------------------------------------------------------------"
+    print " * DBus Constants"
+    print " *"
+    print " * Various constants of interface and method names mostly for use by clients"
+    print " */"
+    print
+
+    for iface in ifaces:
+        header_constants(iface)
+
+    print "/* ------------------------------------------------------------------------"
     print " * DBus Vtable handler structures"
     print " *"
     print " * These structures are filled in by implementors of the different"
diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c
index 36ce6fbaf3d8916d815d73fdfcb5844ca73c1a3c..d72a50fc9bdb4fe6a463466812997fc1c724fc84 100644
--- a/src/tests/sbus_codegen_tests.c
+++ b/src/tests/sbus_codegen_tests.c
@@ -147,6 +147,20 @@ START_TEST(test_vtable)
 }
 END_TEST
 
+START_TEST(test_constants)
+{
+    ck_assert_str_eq(COM_PLANETEXPRESS_SHIP, "com.planetexpress.Ship");
+    ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_MOVEUNIVERSE, "MoveUniverse");
+    ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_CRASH_NOW, "Crash");
+    ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_BECAMESENTIENT, "BecameSentient");
+    ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_COLOR, "Color");
+
+    /* constants for com.planetexpress.Pilot */
+    ck_assert_str_eq(TEST_PILOT, "com.planetexpress.Pilot");
+    ck_assert_str_eq(TEST_PILOT_FULLNAME, "FullName");
+}
+END_TEST
+
 Suite *create_suite(void)
 {
     Suite *s = suite_create("sbus_codegen");
@@ -159,6 +173,7 @@ Suite *create_suite(void)
     tcase_add_test(tc, test_properties);
     tcase_add_test(tc, test_signals);
     tcase_add_test(tc, test_vtable);
+    tcase_add_test(tc, test_constants);
 
     /* Add all test cases to the test suite */
     suite_add_tcase(s, tc);
diff --git a/src/tests/sbus_codegen_tests_generated.h b/src/tests/sbus_codegen_tests_generated.h
index c3ff78db3a03f117542b5b8f1b1952a6d944c9bb..a1a7e5ee9bf7072c3e5234cd644cb93da5a8564e 100644
--- a/src/tests/sbus_codegen_tests_generated.h
+++ b/src/tests/sbus_codegen_tests_generated.h
@@ -6,6 +6,23 @@
 #include "sbus/sssd_dbus.h"
 
 /* ------------------------------------------------------------------------
+ * DBus Constants
+ *
+ * Various constants of interface and method names mostly for use by clients
+ */
+
+/* constants for com.planetexpress.Ship */
+#define COM_PLANETEXPRESS_SHIP "com.planetexpress.Ship"
+#define COM_PLANETEXPRESS_SHIP_MOVEUNIVERSE "MoveUniverse"
+#define COM_PLANETEXPRESS_SHIP_CRASH_NOW "Crash"
+#define COM_PLANETEXPRESS_SHIP_BECAMESENTIENT "BecameSentient"
+#define COM_PLANETEXPRESS_SHIP_COLOR "Color"
+
+/* constants for com.planetexpress.Pilot */
+#define TEST_PILOT "com.planetexpress.Pilot"
+#define TEST_PILOT_FULLNAME "FullName"
+
+/* ------------------------------------------------------------------------
  * DBus Vtable handler structures
  *
  * These structures are filled in by implementors of the different
-- 
1.8.5.3

-------------- next part --------------
>From de0fa482a4a9289337b6512584c943f3a0185e6b Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Fri, 10 Jan 2014 11:23:33 +0100
Subject: [PATCH 6/6] sbus: Use constants to make dbus calls

This allows us to remove duplicated information, and have the
compiler check that when an method name is changed or removed
the callers are updated.
---
 src/monitor/monitor.c                        | 18 +++++++++---------
 src/monitor/monitor_interfaces.h             | 17 -----------------
 src/monitor/monitor_sbus.c                   |  4 ++--
 src/providers/data_provider.h                | 17 -----------------
 src/providers/data_provider_be.c             |  4 ++--
 src/providers/data_provider_iface.xml        |  6 ++++++
 src/providers/dp_auth_util.c                 |  4 ++--
 src/providers/proxy/proxy_auth.c             |  4 ++--
 src/providers/proxy/proxy_child.c            |  4 ++--
 src/responder/autofs/autofssrv_dp.c          |  4 ++--
 src/responder/common/responder_dp.c          |  4 ++--
 src/responder/common/responder_get_domains.c |  4 ++--
 src/responder/pam/pamsrv_dp.c                |  4 ++--
 src/responder/ssh/sshsrv_dp.c                |  4 ++--
 src/responder/sudo/sudosrv_dp.c              |  4 ++--
 15 files changed, 37 insertions(+), 65 deletions(-)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index c2e5a5af627b7d543533c3da8d620a38e93aeadc..ecfa95cfd1f399184dc012f125e815e46ec585b3 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -752,7 +752,7 @@ static int service_signal(struct mt_svc *svc, const char *svc_signal)
 
     msg = dbus_message_new_method_call(NULL,
                                        MONITOR_PATH,
-                                       MONITOR_INTERFACE,
+                                       MON_CLI_IFACE,
                                        svc_signal);
     if (msg == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE,
@@ -772,27 +772,27 @@ static int service_signal(struct mt_svc *svc, const char *svc_signal)
 
 static int service_signal_dns_reload(struct mt_svc *svc)
 {
-    return service_signal(svc, MON_CLI_METHOD_RES_INIT);
+    return service_signal(svc, MON_CLI_IFACE_RESINIT);
 }
 static int service_signal_offline(struct mt_svc *svc)
 {
-    return service_signal(svc, MON_CLI_METHOD_OFFLINE);
+    return service_signal(svc, MON_CLI_IFACE_GOOFFLINE);
 }
 static int service_signal_reset_offline(struct mt_svc *svc)
 {
-    return service_signal(svc, MON_CLI_METHOD_RESET_OFFLINE);
+    return service_signal(svc, MON_CLI_IFACE_RESETOFFLINE);
 }
 static int service_signal_rotate(struct mt_svc *svc)
 {
-    return service_signal(svc, MON_CLI_METHOD_ROTATE);
+    return service_signal(svc, MON_CLI_IFACE_ROTATELOGS);
 }
 static int service_signal_clear_memcache(struct mt_svc *svc)
 {
-    return service_signal(svc, MON_CLI_METHOD_CLEAR_MEMCACHE);
+    return service_signal(svc, MON_CLI_IFACE_CLEARMEMCACHE);
 }
 static int service_signal_clear_enum_cache(struct mt_svc *svc)
 {
-    return service_signal(svc, MON_CLI_METHOD_CLEAR_ENUM_CACHE);
+    return service_signal(svc, MON_CLI_IFACE_CLEARENUMCACHE);
 }
 
 static int check_domain_ranges(struct sss_domain_info *domains)
@@ -2392,8 +2392,8 @@ static int service_send_ping(struct mt_svc *svc)
      */
     msg = dbus_message_new_method_call(NULL,
                                        MONITOR_PATH,
-                                       MONITOR_INTERFACE,
-                                       MON_CLI_METHOD_PING);
+                                       MON_CLI_IFACE,
+                                       MON_CLI_IFACE_PING);
     if (!msg) {
         DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n");
         talloc_zfree(svc->conn);
diff --git a/src/monitor/monitor_interfaces.h b/src/monitor/monitor_interfaces.h
index 308642f7859bb3a06856420db7a8552f4b5b76dd..ef4254a5f59620fe1789135248358bfa6ffe7530 100644
--- a/src/monitor/monitor_interfaces.h
+++ b/src/monitor/monitor_interfaces.h
@@ -29,26 +29,9 @@
 
 /*** Monitor SRV Interface ***/
 #define MON_SRV_PATH "/org/freedesktop/sssd/monitor"
-#define MON_SRV_INTERFACE "org.freedesktop.sssd.monitor"
-
-/* Monitor SRV Methods */
-#define MON_SRV_METHOD_VERSION "getVersion"
-#define MON_SRV_METHOD_REGISTER "RegisterService"
 
 /*** Monitor CLI Interface ***/
 #define MONITOR_PATH "/org/freedesktop/sssd/service"
-#define MONITOR_INTERFACE "org.freedesktop.sssd.service"
-
-/* Monitor CLI Methods */
-#define MON_CLI_METHOD_IDENTITY "getIdentity"
-#define MON_CLI_METHOD_PING "ping"
-#define MON_CLI_METHOD_SHUTDOWN "shutDown"
-#define MON_CLI_METHOD_RES_INIT "resInit"
-#define MON_CLI_METHOD_OFFLINE "goOffline" /* Applicable only to providers */
-#define MON_CLI_METHOD_RESET_OFFLINE "resetOffline" /* Applicable only to providers */
-#define MON_CLI_METHOD_ROTATE "rotateLogs"
-#define MON_CLI_METHOD_CLEAR_MEMCACHE "clearMemcache"
-#define MON_CLI_METHOD_CLEAR_ENUM_CACHE "clearEnumCache"
 
 #define SSSD_SERVICE_PIPE "private/sbus-monitor"
 
diff --git a/src/monitor/monitor_sbus.c b/src/monitor/monitor_sbus.c
index 4b0e221e8df1debbbf715b468c23489509ccc2fe..b1550bcdd1927d62c55e85d0cca66aad0523c3ab 100644
--- a/src/monitor/monitor_sbus.c
+++ b/src/monitor/monitor_sbus.c
@@ -119,8 +119,8 @@ int monitor_common_send_id(struct sbus_connection *conn,
     /* create the message */
     msg = dbus_message_new_method_call(NULL,
                                        MON_SRV_PATH,
-                                       MON_SRV_INTERFACE,
-                                       MON_SRV_METHOD_REGISTER);
+                                       MON_SRV_IFACE,
+                                       MON_SRV_IFACE_REGISTERSERVICE);
     if (msg == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n");
         return ENOMEM;
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 714983032ca2fb7ad385c67210cdf722e3a2bb43..5622cc1fa763a29fa81304245e359ec4ef555d90 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -48,23 +48,8 @@
 #define DATA_PROVIDER_VERSION 0x0001
 #define DATA_PROVIDER_PIPE "private/sbus-dp"
 
-#define DP_INTERFACE "org.freedesktop.sssd.dataprovider"
 #define DP_PATH "/org/freedesktop/sssd/dataprovider"
 
-#define DP_METHOD_REGISTER "RegisterService"
-#define DP_METHOD_GETACCTINFO "getAccountInfo"
-#define DP_METHOD_SUDOHANDLER "sudoHandler"
-#define DP_METHOD_AUTOFSHANDLER "autofsHandler"
-#define DP_METHOD_HOSTHANDLER "hostHandler"
-#define DP_METHOD_GETDOMAINS "getDomains"
-
-/* this is a reverse method sent from providers to
- * the nss responder to tell it to update the mmap
- * cache */
-#define DP_REV_INTERFACE "org.freedesktop.sssd.dataprovider_rev"
-#define DP_REV_METHOD_UPDATE_CACHE "updateCache"
-#define DP_REV_METHOD_INITGR_CHECK "initgrCheck"
-
 /**
  * @defgroup pamHandler PAM DBUS request
  * @ingroup sss_pam
@@ -125,8 +110,6 @@
  */
 
 
-#define DP_METHOD_PAMHANDLER "pamHandler"
-
 /**
  * @}
  */ /* end of group pamHandler */
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 67d52103203d18742c2940318bdcbcf240cbdbba..5519237e895566f66158eee999e317d6bb229fb2 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -856,8 +856,8 @@ static void acctinfo_initgroups_callback(struct be_req *be_req,
     /* Set up null request */
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_REV_INTERFACE,
-                                       DP_REV_METHOD_INITGR_CHECK);
+                                       DATA_PROVIDER_REV_IFACE,
+                                       DATA_PROVIDER_REV_IFACE_INITGRCHECK);
     if (!msg) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
         ret = ENOMEM;
diff --git a/src/providers/data_provider_iface.xml b/src/providers/data_provider_iface.xml
index 1f349649316cdadfed747ff4b8bedddb27c3ec6f..90397f1b2a1dabc3b45005340cd503b0746c7bb5 100644
--- a/src/providers/data_provider_iface.xml
+++ b/src/providers/data_provider_iface.xml
@@ -26,6 +26,12 @@
         </method>
     </interface>
 
+    <!--
+      this is a reverse method sent from providers to
+      the nss responder to tell it to update the mmap
+      cache
+    -->
+
     <interface name="org.freedesktop.sssd.dataprovider_rev">
         <annotation value="data_provider_rev_iface" name="org.freedesktop.DBus.GLib.CSymbol"/>
         <method name="updateCache">
diff --git a/src/providers/dp_auth_util.c b/src/providers/dp_auth_util.c
index 196a0520ceae260f6a754b21b5d4b572489ff878..391d55c1e6b952a4c91e005258ff7ccae25bce09 100644
--- a/src/providers/dp_auth_util.c
+++ b/src/providers/dp_auth_util.c
@@ -364,8 +364,8 @@ int dp_common_send_id(struct sbus_connection *conn, uint16_t version,
     /* create the message */
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_REGISTER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_REGISTERSERVICE);
     if (msg == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n");
         return ENOMEM;
diff --git a/src/providers/proxy/proxy_auth.c b/src/providers/proxy/proxy_auth.c
index c2b792bd8741a87629f6f2fa1748011e1c48de86..a901f0f1738e45f84c101d8786d9258e88e3a135 100644
--- a/src/providers/proxy/proxy_auth.c
+++ b/src/providers/proxy/proxy_auth.c
@@ -602,8 +602,8 @@ static struct tevent_req *proxy_pam_conv_send(TALLOC_CTX *mem_ctx,
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_PAMHANDLER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_PAMHANDLER);
     if (msg == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_call failed.\n");
         talloc_zfree(req);
diff --git a/src/providers/proxy/proxy_child.c b/src/providers/proxy/proxy_child.c
index 737b0cfd6f7cabb35f1911b95fadd901ce5ee64c..b99c35317e057551ca35d7b4a7bc7a5523cd5ec5 100644
--- a/src/providers/proxy/proxy_child.c
+++ b/src/providers/proxy/proxy_child.c
@@ -432,8 +432,8 @@ int proxy_child_send_id(struct sbus_connection *conn,
     /* create the message */
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_REGISTER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_REGISTERSERVICE);
     if (msg == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n");
         return ENOMEM;
diff --git a/src/responder/autofs/autofssrv_dp.c b/src/responder/autofs/autofssrv_dp.c
index 975692aadf86c495720abfa9ce0a1c7778d95883..041f0629eafadb92fc6b8ec7190830a2662b40a0 100644
--- a/src/responder/autofs/autofssrv_dp.c
+++ b/src/responder/autofs/autofssrv_dp.c
@@ -118,8 +118,8 @@ sss_dp_get_autofs_msg(void *pvt)
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_AUTOFSHANDLER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_AUTOFSHANDLER);
     if (msg == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
         return NULL;
diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c
index a9b4ae23a3233f69723798751d2875cfa78ed66e..df7455ce3ead4d84ff124ca54f5b74273c77a6d4 100644
--- a/src/responder/common/responder_dp.c
+++ b/src/responder/common/responder_dp.c
@@ -588,8 +588,8 @@ sss_dp_get_account_msg(void *pvt)
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_GETACCTINFO);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_GETACCOUNTINFO);
     if (msg == NULL) {
         talloc_free(filter);
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
index ba9a0905fe82f46998814fefc1f91bba2382d967..23b274b52a6e704afd41686f3bb2491698aea3eb 100644
--- a/src/responder/common/responder_get_domains.c
+++ b/src/responder/common/responder_get_domains.c
@@ -94,8 +94,8 @@ sss_dp_get_domains_msg(void *pvt)
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_GETDOMAINS);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_GETDOMAINS);
     if (msg == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
         return NULL;
diff --git a/src/responder/pam/pamsrv_dp.c b/src/responder/pam/pamsrv_dp.c
index 4e79eee879cf337301ecd8f1f63d6172b98e4992..8871f198be60d853619e9f3ac6292871755c4af5 100644
--- a/src/responder/pam/pamsrv_dp.c
+++ b/src/responder/pam/pamsrv_dp.c
@@ -128,8 +128,8 @@ int pam_dp_send_req(struct pam_auth_req *preq, int timeout)
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_PAMHANDLER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_PAMHANDLER);
     if (msg == NULL) {
         DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n");
         return ENOMEM;
diff --git a/src/responder/ssh/sshsrv_dp.c b/src/responder/ssh/sshsrv_dp.c
index 7ba65b12c8a4ab4903fc9a7c559934de9bd7c017..90b0b5754e695c4757287d8694e390daee17af5d 100644
--- a/src/responder/ssh/sshsrv_dp.c
+++ b/src/responder/ssh/sshsrv_dp.c
@@ -126,8 +126,8 @@ sss_dp_get_ssh_host_msg(void *pvt)
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_HOSTHANDLER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_HOSTHANDLER);
     if (msg == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
         talloc_free(filter);
diff --git a/src/responder/sudo/sudosrv_dp.c b/src/responder/sudo/sudosrv_dp.c
index 483533cccd1915e6566513f622749f9c4249be54..18e51a92728df38af7ce960f5ef545647840cb25 100644
--- a/src/responder/sudo/sudosrv_dp.c
+++ b/src/responder/sudo/sudosrv_dp.c
@@ -141,8 +141,8 @@ sss_dp_get_sudoers_msg(void *pvt)
 
     msg = dbus_message_new_method_call(NULL,
                                        DP_PATH,
-                                       DP_INTERFACE,
-                                       DP_METHOD_SUDOHANDLER);
+                                       DATA_PROVIDER_IFACE,
+                                       DATA_PROVIDER_IFACE_SUDOHANDLER);
     if (msg == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
         return NULL;
-- 
1.8.5.3



More information about the sssd-devel mailing list