/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos-ctl

  • Committer: Teddy Hogeborn
  • Date: 2019-08-02 22:16:53 UTC
  • Revision ID: teddy@recompile.se-20190802221653-ic1iko9hbefzwsk7
Fix bug in server Debian package: Fails to start on first install

There has been a very long-standing bug where installation of the
server (the "mandos" Debian package) would fail to start the server
properly right after installation.  It would work on manual (re)start
after installation, or after reboot, and even after package purge and
reinstall, it would then work the first time.  The problem, it turns
out, is when the new "_mandos" user (and corresponding group) is
created, the D-Bus server is not reloaded, and is therefore not aware
of that user, and does not recognize the user and group name in the
/etc/dbus-1/system.d/mandos.conf file.  The Mandos server, when it
tries to start and access the D-Bus, is then not permitted to connect
to its D-Bus bus name, and disables D-Bus use as a fallback measure;
i.e. the server works, but it is not controllable via D-Bus commands
(via mandos-ctl or mandos-monitor).  The next time the D-Bus daemon is
reloaded for any reason, the new user & group would become visible to
the D-Bus daemon and after that, any restart of the Mandos server
would succeed and it would bind to its D-Bus name properly, and
thereby be visible and controllable by mandos-ctl & mandos-monitor.
This was mostly invisible when using sysvinit, but systemd makes the
problem visible since the systemd service file for the Mandos server
is configured to not consider the Mandos server "started" until the
D-Bus name has been bound; this makes the starting of the service wait
for 90 seconds and then fail with a timeout error.

Fixing this should also make the Debian CI autopkgtest tests work.

* debian/mandos.postinst (configure): After creating (or renaming)
                                      user & group, reload D-Bus
                                      daemon (if present).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python3 -bb
 
1
#!/usr/bin/python
2
2
# -*- after-save-hook: (lambda () (let ((command (if (fboundp 'file-local-name) (file-local-name (buffer-file-name)) (or (file-remote-p (buffer-file-name) 'localname) (buffer-file-name))))) (if (= (progn (if (get-buffer "*Test*") (kill-buffer "*Test*")) (process-file-shell-command (format "%s --check" (shell-quote-argument command)) nil "*Test*")) 0) (let ((w (get-buffer-window "*Test*"))) (if w (delete-window w))) (progn (with-current-buffer "*Test*" (compilation-mode)) (display-buffer "*Test*" '(display-buffer-in-side-window)))))); coding: utf-8 -*-
3
3
#
4
4
# Mandos Monitor - Control and monitor the Mandos server
46
46
import tempfile
47
47
import contextlib
48
48
 
49
 
if sys.version_info.major == 2:
50
 
    __metaclass__ = type
51
 
 
52
49
try:
53
50
    import pydbus
54
51
    import gi
56
53
except ImportError:
57
54
    import dbus as dbus_python
58
55
    pydbus = None
59
 
    class gi:
 
56
    class gi(object):
60
57
        """Dummy gi module, for the tests"""
61
 
        class repository:
62
 
            class GLib:
 
58
        class repository(object):
 
59
            class GLib(object):
63
60
                class Error(Exception):
64
61
                    pass
65
62
 
81
78
 
82
79
locale.setlocale(locale.LC_ALL, "")
83
80
 
84
 
version = "1.8.8"
 
81
version = "1.8.5"
85
82
 
86
83
 
87
84
def main():
470
467
        parser.error("--remove can only be combined with --deny")
471
468
 
472
469
 
473
 
class dbus:
 
470
class dbus(object):
474
471
 
475
 
    class SystemBus:
 
472
    class SystemBus(object):
476
473
 
477
474
        object_manager_iface = "org.freedesktop.DBus.ObjectManager"
478
475
        def get_managed_objects(self, busname, objectpath):
524
521
        pass
525
522
 
526
523
 
527
 
class dbus_python_adapter:
 
524
class dbus_python_adapter(object):
528
525
 
529
526
    class SystemBus(dbus.MandosBus):
530
527
        """Use dbus-python"""
584
581
                                     self.client_interface, key,
585
582
                                     value)
586
583
 
587
 
    class SilenceLogger:
 
584
    class SilenceLogger(object):
588
585
        "Simple context manager to silence a particular logger"
589
586
        def __init__(self, loggername):
590
587
            self.logger = logging.getLogger(loggername)
619
616
                return new_object
620
617
 
621
618
 
622
 
class pydbus_adapter:
 
619
class pydbus_adapter(object):
623
620
    class SystemBus(dbus.MandosBus):
624
621
        def __init__(self, module=pydbus):
625
622
            self.pydbus = module
715
712
    return commands
716
713
 
717
714
 
718
 
class command:
 
715
class command(object):
719
716
    """A namespace for command classes"""
720
717
 
721
 
    class Base:
 
718
    class Base(object):
722
719
        """Abstract base class for commands"""
723
720
        def run(self, clients, bus=None):
724
721
            """Normal commands should implement run_on_one_client(),
787
784
                keywords = self.all_keywords
788
785
            print(self.TableOfClients(clients.values(), keywords))
789
786
 
790
 
        class TableOfClients:
 
787
        class TableOfClients(object):
791
788
            tableheaders = {
792
789
                "Name": "Name",
793
790
                "Enabled": "Enabled",
1024
1021
                                                     "output"))
1025
1022
 
1026
1023
 
1027
 
class Unique:
 
1024
class Unique(object):
1028
1025
    """Class for objects which exist only to be unique objects, since
1029
1026
unittest.mock.sentinel only exists in Python 3.3"""
1030
1027
 
1314
1311
class Test_dbus_python_adapter_SystemBus(TestCaseWithAssertLogs):
1315
1312
 
1316
1313
    def MockDBusPython_func(self, func):
1317
 
        class mock_dbus_python:
 
1314
        class mock_dbus_python(object):
1318
1315
            """mock dbus-python module"""
1319
 
            class exceptions:
 
1316
            class exceptions(object):
1320
1317
                """Pseudo-namespace"""
1321
1318
                class DBusException(Exception):
1322
1319
                    pass
1323
 
            class SystemBus:
 
1320
            class SystemBus(object):
1324
1321
                @staticmethod
1325
1322
                def get_object(busname, objectpath):
1326
1323
                    DBusObject = collections.namedtuple(
1340
1337
                                    dbus_interface=dbus_interface)
1341
1338
                    return DBusObject(methodname=method,
1342
1339
                                      Set=set_property)
1343
 
            class Boolean:
 
1340
            class Boolean(object):
1344
1341
                def __init__(self, value):
1345
1342
                    self.value = bool(value)
1346
1343
                def __bool__(self):
1558
1555
            self.call_method(bus, "methodname", "busname",
1559
1556
                             "objectpath", "interface")
1560
1557
 
1561
 
    class fake_dbus_python_raises_exception_on_connect:
 
1558
    class fake_dbus_python_raises_exception_on_connect(object):
1562
1559
        """fake dbus-python module"""
1563
 
        class exceptions:
 
1560
        class exceptions(object):
1564
1561
            """Pseudo-namespace"""
1565
1562
            class DBusException(Exception):
1566
1563
                pass
1574
1571
 
1575
1572
 
1576
1573
class Test_dbus_python_adapter_CachingBus(unittest.TestCase):
1577
 
    class mock_dbus_python:
 
1574
    class mock_dbus_python(object):
1578
1575
        """mock dbus-python modules"""
1579
 
        class SystemBus:
 
1576
        class SystemBus(object):
1580
1577
            @staticmethod
1581
1578
            def get_object(busname, objectpath):
1582
1579
                return Unique()
1628
1625
class Test_pydbus_adapter_SystemBus(TestCaseWithAssertLogs):
1629
1626
 
1630
1627
    def Stub_pydbus_func(self, func):
1631
 
        class stub_pydbus:
 
1628
        class stub_pydbus(object):
1632
1629
            """stub pydbus module"""
1633
 
            class SystemBus:
 
1630
            class SystemBus(object):
1634
1631
                @staticmethod
1635
1632
                def get(busname, objectpath):
1636
1633
                    DBusObject = collections.namedtuple(
1682
1679
            self.call_method(bus, "methodname", "busname",
1683
1680
                             "objectpath", "interface")
1684
1681
 
1685
 
    class fake_pydbus_raises_exception_on_connect:
 
1682
    class fake_pydbus_raises_exception_on_connect(object):
1686
1683
        """fake dbus-python module"""
1687
1684
        @classmethod
1688
1685
        def SystemBus(cls):
1692
1689
            return Bus(get=get)
1693
1690
 
1694
1691
    def test_set_property_uses_setattr(self):
1695
 
        class Object:
 
1692
        class Object(object):
1696
1693
            pass
1697
1694
        obj = Object()
1698
 
        class pydbus_spy:
1699
 
            class SystemBus:
 
1695
        class pydbus_spy(object):
 
1696
            class SystemBus(object):
1700
1697
                @staticmethod
1701
1698
                def get(busname, objectpath):
1702
1699
                    return {"interface": obj}
1709
1706
    def test_get_suppresses_xml_deprecation_warning(self):
1710
1707
        if sys.version_info.major >= 3:
1711
1708
            return
1712
 
        class stub_pydbus_get:
1713
 
            class SystemBus:
 
1709
        class stub_pydbus_get(object):
 
1710
            class SystemBus(object):
1714
1711
                @staticmethod
1715
1712
                def get(busname, objectpath):
1716
1713
                    warnings.warn_explicit(
1724
1721
 
1725
1722
 
1726
1723
class Test_pydbus_adapter_CachingBus(unittest.TestCase):
1727
 
    class stub_pydbus:
 
1724
    class stub_pydbus(object):
1728
1725
        """stub pydbus module"""
1729
 
        class SystemBus:
 
1726
        class SystemBus(object):
1730
1727
            @staticmethod
1731
1728
            def get(busname, objectpath):
1732
1729
                return Unique()