Beispiel #1
0
    def run(self, sambaopts, versionopts, section_name=None,
            name=None, pid=None):

        lp = sambaopts.get_loadparm()
        logger = self.get_logger("processes")

        msg_ctx = Messaging()

        if name is not None:
            ids = msg_ctx.irpc_servers_byname(name)
            for server_id in ids:
                print "%d\n" % server_id.pid
        elif pid is not None:
            names = msg_ctx.irpc_all_servers()
            for name in names:
                for server_id in name.ids:
                    if server_id.pid == int(pid):
                        print "%s\n" % name.name
        else:
            names = msg_ctx.irpc_all_servers()
            for name in names:
                print "%s: " % name.name
                for server_id in name.ids:
                    print "%d " % server_id.pid
                print "\n"
    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1, ), lp_ctx=lp_ctx)
        global msg_ctxs
        msg_ctxs.append(self.msg_ctx)
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            context["messages"].append(jsonMsg)

        self.context = {"messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None
Beispiel #3
0
    def run(self, sambaopts, versionopts, section_name=None,
            name=None, pid=None):

        lp = sambaopts.get_loadparm()
        logger = self.get_logger("processes")

        msg_ctx = Messaging()

        if name is not None:
            ids = msg_ctx.irpc_servers_byname(name)
            for server_id in ids:
                self.outf.write("%d\n" % server_id.pid)
        elif pid is not None:
            names = msg_ctx.irpc_all_servers()
            for name in names:
                for server_id in name.ids:
                    if server_id.pid == int(pid):
                        self.outf.write("%s\n" % name.name)
        else:
            names = msg_ctx.irpc_all_servers()
            self.outf.write(" Service:                PID \n")
            self.outf.write("-----------------------------\n")
            for name in names:
                for server_id in name.ids:
                    self.outf.write("%-16s      %6d\n" % (name.name, server_id.pid))
Beispiel #4
0
    def run(self,
            sambaopts,
            versionopts,
            section_name=None,
            name=None,
            pid=None):

        lp = sambaopts.get_loadparm()
        logger = self.get_logger("processes")

        msg_ctx = Messaging()

        if name is not None:
            try:
                ids = msg_ctx.irpc_servers_byname(name)
            except KeyError:
                ids = []

            for server_id in ids:
                self.outf.write("%d\n" % server_id.pid)
        elif pid is not None:
            names = msg_ctx.irpc_all_servers()
            for name in names:
                for server_id in name.ids:
                    if server_id.pid == int(pid):
                        self.outf.write("%s\n" % name.name)
        else:
            names = msg_ctx.irpc_all_servers()
            self.outf.write(" Service:                PID \n")
            self.outf.write("-----------------------------\n")
            for name in names:
                for server_id in name.ids:
                    self.outf.write("%-16s      %6d\n" %
                                    (name.name, server_id.pid))
Beispiel #5
0
    def run(self,
            sambaopts,
            versionopts,
            section_name=None,
            name=None,
            pid=None):

        lp = sambaopts.get_loadparm()
        logger = self.get_logger("processes")

        msg_ctx = Messaging()

        if name is not None:
            try:
                ids = msg_ctx.irpc_servers_byname(name)
            except KeyError:
                ids = []

            for server_id in ids:
                self.outf.write("%d\n" % server_id.pid)
        elif pid is not None:
            names = msg_ctx.irpc_all_servers()
            for name in names:
                for server_id in name.ids:
                    if server_id.pid == int(pid):
                        self.outf.write("%s\n" % name.name)
        else:
            seen = {}  # Service entries already printed, service names can
            #               be registered multiple times against a process
            #               but we should only display them once.
            prefork = {}  # Services running in the prefork process model
            #               want to ensure that the master process and workers
            #               are grouped to together.
            (services, masters, workers) = self.get_service_data(msg_ctx)
            self.outf.write(" Service:                          PID\n")
            self.outf.write("--------------------------------------\n")

            for service in sorted(services, key=lambda x: x.name):
                if service.name in masters:
                    # If this service is running in a pre-forked process we
                    # want to print the master process followed by all the
                    # worker processes
                    pid = masters[service.name]
                    if pid not in prefork:
                        prefork[pid] = True
                        self.outf.write("%-26s      %6d\n" %
                                        (service.name, pid))
                        if service.name in workers:
                            ws = workers[service.name]
                            for w in ws:
                                (instance, pid) = ws[w]
                                sn = "{0}(worker {1})".format(
                                    service.name, instance)
                                self.outf.write("%-26s      %6d\n" % (sn, pid))
                else:
                    for server_id in service.ids:
                        if (service.name, server_id.pid) not in seen:
                            self.outf.write("%-26s      %6d\n" %
                                            (service.name, server_id.pid))
                            seen[(service.name, server_id.pid)] = True
Beispiel #6
0
class SmbcontrolBlockboxTests(BlackboxTestCase):

    def setUp(self):
        super(SmbcontrolBlockboxTests, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging(lp_ctx=lp_ctx)

    def test_expected_processes(self):
        """
        Test that the expected samba processes are running, currently we only
        check that at least one process is running
        """
        processes = self.msg_ctx.irpc_all_servers()
        if not processes:
            self.fail("No samba processes returned")

    def test_ping(self):
        """Test that all the samba processes can be pinged"""

        processes = self.msg_ctx.irpc_all_servers()

        for p in processes:
            for id in p.ids:
                if p.name != "samba":
                    try:
                        self.check_run("%s %d %s" % (COMMAND, id.pid, PING),
                                       msg="trying to ping %s" % p.name)
                    except BlackboxProcessError as e:
                        # This process could not be pinged, which is
                        # expected (occasionally) if the ldap_server
                        # is using the "standard process model" and
                        # forking a short-lived child for each
                        # connection. We don't care about this, so we
                        # list the processes again and assume that
                        # only those that remain are relevant to the
                        # ping test. Additionally we ensure that at
                        # least one process of each name remains -- in
                        # the ldap_server case, we expect at least the
                        # parent to be there.
                        name_exists = False
                        surviving_processes = self.msg_ctx.irpc_all_servers()
                        for q in surviving_processes:
                            if q.name == p.name:
                                name_exists = True
                                if id.pid in [x.pid for x in q.ids]:
                                    # the unpingable server is still
                                    # listed, meaning it is broken
                                    raise

                        if not name_exists:
                            # it looks like the service genuinely died
                            # just at this moment
                            raise

                        print("Ignoring error %s:" % e)
                        print("the process probably died before our ping")
                        continue
Beispiel #7
0
class SmbcontrolBlackboxTests(BlackboxTestCase):
    def setUp(self):
        super(SmbcontrolBlackboxTests, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging(lp_ctx=lp_ctx)

    def test_expected_processes(self):
        """
        Test that the expected samba processes are running, currently we only
        check that at least one process is running
        """
        processes = self.msg_ctx.irpc_all_servers()
        if not processes:
            self.fail("No samba processes returned")

    def test_ping(self):
        """Test that all the samba processes can be pinged"""

        processes = self.msg_ctx.irpc_all_servers()

        for p in processes:
            for id in p.ids:
                if p.name != "samba":
                    try:
                        self.check_run("%s %d %s" % (COMMAND, id.pid, PING),
                                       msg="trying to ping %s" % p.name)
                    except BlackboxProcessError as e:
                        # This process could not be pinged, which is
                        # expected (occasionally) if the ldap_server
                        # is using the "standard process model" and
                        # forking a short-lived child for each
                        # connection. We don't care about this, so we
                        # list the processes again and assume that
                        # only those that remain are relevant to the
                        # ping test. Additionally we ensure that at
                        # least one process of each name remains -- in
                        # the ldap_server case, we expect at least the
                        # parent to be there.
                        name_exists = False
                        surviving_processes = self.msg_ctx.irpc_all_servers()
                        for q in surviving_processes:
                            if q.name == p.name:
                                name_exists = True
                                if id.pid in [x.pid for x in q.ids]:
                                    # the unpingable server is still
                                    # listed, meaning it is broken
                                    raise

                        if not name_exists:
                            # it looks like the service genuinely died
                            # just at this moment
                            raise

                        print("Ignoring error %s:" % e)
                        print("the process probably died before our ping")
                        continue
Beispiel #8
0
    def setUpClass(self):
        # connect to the server's messaging bus (we need to explicitly load a
        # different smb.conf here, because in all other respects this test
        # wants to act as a separate remote client)
        server_conf = os.getenv('SERVERCONFFILE')
        if server_conf:
            lp_ctx = LoadParm(filename_for_non_global_lp=server_conf)
        else:
            samba.tests.env_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        # Now switch back to using the client-side smb.conf. The tests will
        # use the first interface in the client.conf (we need to strip off
        # the subnet mask portion)
        lp_ctx = samba.tests.env_loadparm()
        client_ip_and_mask = lp_ctx.get('interfaces')[0]
        client_ip = client_ip_and_mask.split('/')[0]

        # the messaging ctx is the server's view of the world, so our own
        # client IP will be the remoteAddress when connections are logged
        self.remoteAddress = client_ip

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            context["messages"].append(jsonMsg)

        self.context = {"messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None
Beispiel #9
0
class SmbcontrolBlockboxTests(BlackboxTestCase):
    def setUp(self):
        super(SmbcontrolBlockboxTests, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging(lp_ctx=lp_ctx)

    def test_expected_processes(self):
        """
        Test that the expected samba processes are running, currently we only
        check that at least one process is running
        """
        processes = self.msg_ctx.irpc_all_servers()
        if not processes:
            self.fail("No samba processes returned")

    def test_ping(self):
        """Test that all the samba processes can be pinged"""

        processes = self.msg_ctx.irpc_all_servers()
        for p in processes:
            for id in p.ids:
                if p.name != "samba":
                    self.check_run("%s %d %s" % (COMMAND, id.pid, PING))
Beispiel #10
0
    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            context["messages"].append(jsonMsg)

        self.context = {"messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None
Beispiel #11
0
 def setUp(self):
     super(PreforkProcessRestartTests, self).setUp()
     lp_ctx = self.get_loadparm()
     self.msg_ctx = Messaging(lp_ctx=lp_ctx)
Beispiel #12
0
class PreforkProcessRestartTests(TestCase):
    def setUp(self):
        super(PreforkProcessRestartTests, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging(lp_ctx=lp_ctx)

    def tearDown(self):
        super(PreforkProcessRestartTests, self).tearDown()

    def get_process_data(self):
        services = self.msg_ctx.irpc_all_servers()

        processes = []
        for service in services:
            for id in service.ids:
                processes.append((service.name, id.pid))
        return processes

    def get_process(self, name):
        processes = self.get_process_data()
        for pname, pid in processes:
            if name == pname:
                return pid
        return None

    def get_worker_pids(self, name, workers):
        pids = []
        for x in range(workers):
            process_name = "prefork-worker-{0}-{1}".format(name, x)
            pids.append(self.get_process(process_name))
            self.assertIsNotNone(pids[x])
        return pids

    def wait_for_workers(self, name, workers):
        num_workers = len(workers)
        for x in range(num_workers):
            process_name = "prefork-worker-{0}-{1}".format(name, x)
            self.wait_for_process(process_name, workers[x], 0, 1, 30)

    def wait_for_process(self, name, pid, initial_delay, wait, timeout):
        time.sleep(initial_delay)
        delay = initial_delay
        while delay < timeout:
            p = self.get_process(name)
            if p is not None and p != pid:
                # process has restarted
                return
            time.sleep(wait)
            delay += wait
        self.fail(
            "Times out after {0} seconds waiting for {1} to restart".format(
                delay, name))

    def check_for_duplicate_processes(self):
        processes = self.get_process_data()
        process_map = {}
        for name, p in processes:
            if (name.startswith("prefork-") or name.endswith("_server")
                    or name.endswith("srv")):

                if name in process_map:
                    if p != process_map[name]:
                        self.fail(
                            "Duplicate process for {0}, pids {1} and {2}".
                            format(name, p, process_map[name]))

    def simple_bind(self):
        creds = self.insta_creds(template=self.get_credentials())
        creds.set_bind_dn("%s\\%s" %
                          (creds.get_domain(), creds.get_username()))

        self.samdb = SamDB(url="ldaps://%s" % os.environ["SERVER"],
                           lp=self.get_loadparm(),
                           credentials=creds)

    def rpc_echo(self):
        conn = echo.rpcecho("ncalrpc:", self.get_loadparm())
        self.assertEqual([1, 2, 3], conn.EchoData([1, 2, 3]))

    def netlogon(self):
        server = os.environ["SERVER"]
        host = os.environ["SERVER_IP"]
        lp = self.get_loadparm()

        credentials = self.get_credentials()

        session = system_session()
        ldb = SamDB(url="ldap://%s" % host,
                    session_info=session,
                    credentials=credentials,
                    lp=lp)
        machine_pass = samba.generate_random_password(32, 32)
        machine_name = MACHINE_NAME
        machine_dn = "cn=%s,%s" % (machine_name, ldb.domain_dn())

        delete_force(ldb, machine_dn)

        utf16pw = ('"%s"' % get_string(machine_pass)).encode('utf-16-le')
        ldb.add({
            "dn":
            machine_dn,
            "objectclass":
            "computer",
            "sAMAccountName":
            "%s$" % machine_name,
            "userAccountControl":
            str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
            "unicodePwd":
            utf16pw
        })

        machine_creds = Credentials()
        machine_creds.guess(lp)
        machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
        machine_creds.set_kerberos_state(DONT_USE_KERBEROS)
        machine_creds.set_password(machine_pass)
        machine_creds.set_username(machine_name + "$")
        machine_creds.set_workstation(machine_name)

        netlogon.netlogon("ncacn_ip_tcp:%s[schannel,seal]" % server, lp,
                          machine_creds)

        delete_force(ldb, machine_dn)

    def test_ldap_master_restart(self):
        # check ldap connection, do a simple bind
        self.simple_bind()

        # get ldap master process
        pid = self.get_process("prefork-master-ldap")
        self.assertIsNotNone(pid)

        # Get the worker processes
        workers = self.get_worker_pids("ldap", NUM_WORKERS)

        # kill it
        os.kill(pid, signal.SIGTERM)

        # wait for the process to restart
        self.wait_for_process("prefork-master-ldap", pid, 1, 1, 30)

        # restarting the master restarts the workers as well, so make sure
        # they have finished restarting
        self.wait_for_workers("ldap", workers)

        # get ldap master process
        new_pid = self.get_process("prefork-master-ldap")
        self.assertIsNotNone(new_pid)

        # check that the pid has changed
        self.assertNotEquals(pid, new_pid)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("ldap", NUM_WORKERS)
        for x in range(NUM_WORKERS):
            self.assertNotEquals(workers[x], new_workers[x])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

        # check ldap connection, another simple bind
        self.simple_bind()

    def test_ldap_worker_restart(self):
        # check ldap connection, do a simple bind
        self.simple_bind()

        # get ldap master process
        pid = self.get_process("prefork-master-ldap")
        self.assertIsNotNone(pid)

        # Get the worker processes
        workers = self.get_worker_pids("ldap", NUM_WORKERS)

        # kill worker 0
        os.kill(workers[0], signal.SIGTERM)

        # wait for the process to restart
        self.wait_for_process("prefork-worker-ldap-0", pid, 1, 1, 30)

        # get ldap master process
        new_pid = self.get_process("prefork-master-ldap")
        self.assertIsNotNone(new_pid)

        # check that the pid has not changed
        self.assertEqual(pid, new_pid)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("ldap", NUM_WORKERS)
        # process 0 should have a new pid the others should be unchanged
        self.assertNotEquals(workers[0], new_workers[0])
        self.assertEqual(workers[1], new_workers[1])
        self.assertEqual(workers[2], new_workers[2])
        self.assertEqual(workers[3], new_workers[3])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

        # check ldap connection, another simple bind
        self.simple_bind()

    #
    # Kill all the ldap worker processes and ensure that they are restarted
    # correctly
    #
    def test_ldap_all_workers_restart(self):
        # check ldap connection, do a simple bind
        self.simple_bind()

        # get ldap master process
        pid = self.get_process("prefork-master-ldap")
        self.assertIsNotNone(pid)

        # Get the worker processes
        workers = self.get_worker_pids("ldap", NUM_WORKERS)

        # kill all the worker processes
        for x in workers:
            os.kill(x, signal.SIGTERM)

        # wait for the worker processes to restart
        self.wait_for_workers("ldap", workers)

        # get ldap master process
        new_pid = self.get_process("prefork-master-ldap")
        self.assertIsNotNone(new_pid)

        # check that the pid has not changed
        self.assertEqual(pid, new_pid)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("ldap", NUM_WORKERS)
        for x in range(NUM_WORKERS):
            self.assertNotEquals(workers[x], new_workers[x])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

        # check ldap connection, another simple bind
        self.simple_bind()

    def test_rpc_master_restart(self):
        # check rpc connection, make a rpc echo request
        self.rpc_echo()

        # get rpc master process
        pid = self.get_process("prefork-master-rpc")
        self.assertIsNotNone(pid)

        # Get the worker processes
        workers = self.get_worker_pids("rpc", NUM_WORKERS)

        # kill it
        os.kill(pid, signal.SIGTERM)

        # wait for the process to restart
        self.wait_for_process("prefork-master-rpc", pid, 1, 1, 30)

        # wait for workers to restart as well
        self.wait_for_workers("rpc", workers)

        # get ldap master process
        new_pid = self.get_process("prefork-master-rpc")
        self.assertIsNotNone(new_pid)

        # check that the pid has changed
        self.assertNotEquals(pid, new_pid)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("rpc", NUM_WORKERS)
        for x in range(NUM_WORKERS):
            self.assertNotEquals(workers[x], new_workers[x])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

        # check rpc connection, another rpc echo request
        self.rpc_echo()

    def test_rpc_worker_zero_restart(self):
        # check rpc connection, make a rpc echo request and a netlogon request
        self.rpc_echo()
        self.netlogon()

        # get rpc master process
        pid = self.get_process("prefork-master-rpc")
        self.assertIsNotNone(pid)

        # Get the worker processes
        workers = self.get_worker_pids("rpc", NUM_WORKERS)

        # kill worker 0
        os.kill(workers[0], signal.SIGTERM)

        # wait for the process to restart
        self.wait_for_process("prefork-worker-rpc-0", workers[0], 1, 1, 30)

        # get rpc master process
        new_pid = self.get_process("prefork-master-rpc")
        self.assertIsNotNone(new_pid)

        # check that the pid has not changed
        self.assertEqual(pid, new_pid)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("rpc", NUM_WORKERS)
        # process 0 should have a new pid the others should be unchanged
        self.assertNotEquals(workers[0], new_workers[0])
        self.assertEqual(workers[1], new_workers[1])
        self.assertEqual(workers[2], new_workers[2])
        self.assertEqual(workers[3], new_workers[3])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

        # check rpc connection, another rpc echo request, and netlogon request
        self.rpc_echo()
        self.netlogon()

    def test_rpc_all_workers_restart(self):
        # check rpc connection, make a rpc echo request, and a netlogon request
        self.rpc_echo()
        self.netlogon()

        # get rpc master process
        pid = self.get_process("prefork-master-rpc")
        self.assertIsNotNone(pid)

        # Get the worker processes
        workers = self.get_worker_pids("rpc", NUM_WORKERS)

        # kill all the worker processes
        for x in workers:
            os.kill(x, signal.SIGTERM)

        # wait for the worker processes to restart
        for x in range(NUM_WORKERS):
            self.wait_for_process("prefork-worker-rpc-{0}".format(x),
                                  workers[x], 0, 1, 30)

        # get rpc master process
        new_pid = self.get_process("prefork-master-rpc")
        self.assertIsNotNone(new_pid)

        # check that the pid has not changed
        self.assertEqual(pid, new_pid)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("rpc", NUM_WORKERS)
        for x in range(NUM_WORKERS):
            self.assertNotEquals(workers[x], new_workers[x])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

        # check rpc connection, another rpc echo request and netlogon
        self.rpc_echo()
        self.netlogon()

    def test_master_restart_backoff(self):

        # get kdc master process
        pid = self.get_process("prefork-master-echo")
        self.assertIsNotNone(pid)

        #
        # Check that the processes get backed off as expected
        #
        # have prefork backoff increment = 5
        #      prefork maximum backoff   = 10
        backoff_increment = 5
        for expected in [0, 5, 10, 10]:
            # Get the worker processes
            workers = self.get_worker_pids("kdc", NUM_WORKERS)

            process = self.get_process("prefork-master-echo")
            os.kill(process, signal.SIGTERM)
            # wait for the process to restart
            start = time.time()
            self.wait_for_process("prefork-master-echo", process, 0, 1, 30)
            # wait for the workers to restart as well
            self.wait_for_workers("echo", workers)
            end = time.time()
            duration = end - start

            # process restart will take some time. Check that the elapsed
            # duration falls somewhere in the expected range, i.e. we haven't
            # taken longer than the backoff increment
            self.assertLess(duration, expected + backoff_increment)
            self.assertGreaterEqual(duration, expected)

        # check that the worker processes have restarted
        new_workers = self.get_worker_pids("echo", NUM_WORKERS)
        for x in range(NUM_WORKERS):
            self.assertNotEquals(workers[x], new_workers[x])

        # check that the previous server entries have been removed.
        self.check_for_duplicate_processes()

    def test_worker_restart_backoff(self):
        #
        # Check that the processes get backed off as expected
        #
        # have prefork backoff increment = 5
        #      prefork maximum backoff   = 10
        backoff_increment = 5
        for expected in [0, 5, 10, 10]:
            process = self.get_process("prefork-worker-echo-2")
            self.assertIsNotNone(process)
            os.kill(process, signal.SIGTERM)
            # wait for the process to restart
            start = time.time()
            self.wait_for_process("prefork-worker-echo-2", process, 0, 1, 30)
            end = time.time()
            duration = end - start

            # process restart will take some time. Check that the elapsed
            # duration falls somewhere in the expected range, i.e. we haven't
            # taken longer than the backoff increment
            self.assertLess(duration, expected + backoff_increment)
            self.assertGreaterEqual(duration, expected)

        self.check_for_duplicate_processes()
Beispiel #13
0
 def get_context(self, *args, **kwargs):
     kwargs["messaging_path"] = "."
     return Messaging(*args, **kwargs)
Beispiel #14
0
class AuthLogTestBase(samba.tests.TestCase):

    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx);
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def messageHandler( context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print message
            jsonMsg = json.loads(message)
            context["messages"].append( jsonMsg)

        self.context = { "messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None

    def tearDown(self):
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)


    def waitForMessages(self, isLastExpectedMessage, connection=None):
        """Wait for all the expected messages to arrive
        The connection is passed through to keep the connection alive
        until all the logging messages have been received.
        """

        def completed( messages):
            for message in messages:
                if isRemote( message) and isLastExpectedMessage( message):
                    return True
            return False

        def isRemote( message):
            remote = None
            if message["type"] == "Authorization":
                remote = message["Authorization"]["remoteAddress"]
            elif message["type"] == "Authentication":
                remote = message["Authentication"]["remoteAddress"]
            else:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        self.connection = connection

        start_time = time.time()
        while not completed( self.context["messages"]):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                return []

        self.connection = None
        return filter( isRemote, self.context["messages"])

    # Discard any previously queued messages.
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while len( self.context["messages"]):
            self.msg_ctx.loop_once(0.001)
        self.context["messages"] = []

    # Remove any NETLOGON authentication messages
    # NETLOGON is only performed once per session, so to avoid ordering
    # dependencies within the tests it's best to strip out NETLOGON messages.
    #
    def remove_netlogon_messages(self, messages):
        def is_not_netlogon(msg):
            if "Authentication" not in msg:
                return True
            sd = msg["Authentication"]["serviceDescription"]
            return sd != "NETLOGON"

        return list(filter(is_not_netlogon, messages))
Beispiel #15
0
 def setUp(self):
     super(SmbcontrolBlockboxTests, self).setUp()
     lp_ctx = self.get_loadparm()
     self.msg_ctx = Messaging(lp_ctx=lp_ctx)
Beispiel #16
0
    def dc_watcher(self):

        (r1, w1) = os.pipe()
        pid = os.fork()
        if pid != 0:
            # Parent process return the result socket to the caller.
            return r1

        # Load the lp context for the Domain Controller, rather than the
        # member server.
        config_file = os.environ["DC_SERVERCONFFILE"]
        lp_ctx = LoadParm()
        lp_ctx.load(config_file)

        #
        # Is the message a SamLogon authentication?
        def is_sam_logon(m):
            if m is None:
                return False
            msg = json.loads(m)
            return (msg["type"] == "Authentication" and
                    msg["Authentication"]["serviceDescription"] == "SamLogon")

        #
        # Handler function for received authentication messages.
        def message_handler(context, msgType, src, message):
            # Print the message to help debugging the tests.
            # as it's a JSON message it does not look like a sub-unit message.
            print(message)
            self.dc_msgs.append(message)

        # Set up a messaging context to listen for authentication events on
        # the domain controller.
        msg_ctx = Messaging((1, ), lp_ctx=lp_ctx)
        msg_ctx.irpc_add_name(AUTH_EVENT_NAME)
        msg_handler_and_context = (message_handler, None)
        msg_ctx.register(msg_handler_and_context, msg_type=MSG_AUTH_LOG)

        # Wait for the SamLogon message.
        # As there could be other SamLogon's in progress we need to collect
        # all the SamLogons and let the caller match them to the session.
        self.dc_msgs = []
        start_time = time.time()
        while (time.time() - start_time < 1):
            msg_ctx.loop_once(0.1)

        # Only interested in SamLogon messages, filter out the rest
        msgs = list(filter(is_sam_logon, self.dc_msgs))
        if msgs:
            for m in msgs:
                m += "\n"
                os.write(w1, get_bytes(m))
        else:
            os.write(w1, get_bytes("None\n"))
        os.close(w1)

        msg_ctx.deregister(msg_handler_and_context, msg_type=MSG_AUTH_LOG)
        msg_ctx.irpc_remove_name(AUTH_EVENT_NAME)

        os._exit(0)
Beispiel #17
0
class AuthLogTestBase(samba.tests.TestCase):

    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx);
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def messageHandler( context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print message
            jsonMsg = json.loads(message)
            context["messages"].append( jsonMsg)

        self.context = { "messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None

    def tearDown(self):
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)


    def waitForMessages(self, isLastExpectedMessage, connection=None):

        def completed( messages):
            for message in messages:
                if isRemote( message) and isLastExpectedMessage( message):
                    return True
            return False

        def isRemote( message):
            remote = None
            if message["type"] == "Authorization":
                remote = message["Authorization"]["remoteAddress"]
            elif message["type"] == "Authentication":
                remote = message["Authentication"]["remoteAddress"]
            else:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        self.connection = connection

        start_time = time.time()
        while not completed( self.context["messages"]):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                return []

        self.connection = None
        return filter( isRemote, self.context["messages"])

    # Discard any previously queued messages.
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while len( self.context["messages"]):
            self.msg_ctx.loop_once(0.001)
        self.context["messages"] = []
Beispiel #18
0
    def setUp(self):
        super(AuditLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1, ), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(self.event_type)

        #
        # Check the remote address of a message against the one beimg used
        # for the tests.
        #
        def isRemote(message):
            audit = getAudit(message)
            if audit is None:
                return False

            remote = audit["remoteAddress"]
            if remote is None:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            if ((jsonMsg["type"] == "passwordChange" or jsonMsg["type"]
                 == "dsdbChange" or jsonMsg["type"] == "groupChange")
                    and isRemote(jsonMsg)):
                context["messages"].append(jsonMsg)
            elif jsonMsg["type"] == "dsdbTransaction":
                context["txnMessage"] = jsonMsg

        self.context = {"messages": [], "txnMessage": None}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=self.message_type)

        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def authHandler(context, msgType, src, message):
            jsonMsg = json.loads(message)
            if jsonMsg["type"] == "Authorization" and isRemote(jsonMsg):
                # This does not look like sub unit output and it
                # makes these tests much easier to debug.
                print(message)
                context["sessionId"] = jsonMsg["Authorization"]["sessionId"]
                context["serviceDescription"] =\
                    jsonMsg["Authorization"]["serviceDescription"]

        self.auth_context = {"sessionId": "", "serviceDescription": ""}
        self.auth_handler_and_context = (authHandler, self.auth_context)
        self.msg_ctx.register(self.auth_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.server = os.environ["SERVER"]
        self.connection = None
Beispiel #19
0
class AuditLogTestBase(samba.tests.TestCase):
    def setUp(self):
        super(AuditLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1, ), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(self.event_type)

        #
        # Check the remote address of a message against the one beimg used
        # for the tests.
        #
        def isRemote(message):
            audit = getAudit(message)
            if audit is None:
                return False

            remote = audit["remoteAddress"]
            if remote is None:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            if ((jsonMsg["type"] == "passwordChange" or jsonMsg["type"]
                 == "dsdbChange" or jsonMsg["type"] == "groupChange")
                    and isRemote(jsonMsg)):
                context["messages"].append(jsonMsg)
            elif jsonMsg["type"] == "dsdbTransaction":
                context["txnMessage"] = jsonMsg

        self.context = {"messages": [], "txnMessage": None}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=self.message_type)

        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def authHandler(context, msgType, src, message):
            jsonMsg = json.loads(message)
            if jsonMsg["type"] == "Authorization" and isRemote(jsonMsg):
                # This does not look like sub unit output and it
                # makes these tests much easier to debug.
                print(message)
                context["sessionId"] = jsonMsg["Authorization"]["sessionId"]
                context["serviceDescription"] =\
                    jsonMsg["Authorization"]["serviceDescription"]

        self.auth_context = {"sessionId": "", "serviceDescription": ""}
        self.auth_handler_and_context = (authHandler, self.auth_context)
        self.msg_ctx.register(self.auth_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.server = os.environ["SERVER"]
        self.connection = None

    def tearDown(self):
        self.discardMessages()
        self.msg_ctx.irpc_remove_name(self.event_type)
        self.msg_ctx.irpc_remove_name(AUTH_EVENT_NAME)
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=self.message_type)
        if self.auth_handler_and_context:
            self.msg_ctx.deregister(self.auth_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)

    def haveExpected(self, expected, dn):
        if dn is None:
            return len(self.context["messages"]) >= expected
        else:
            received = 0
            for msg in self.context["messages"]:
                audit = getAudit(msg)
                if audit["dn"].lower() == dn.lower():
                    received += 1
                    if received >= expected:
                        return True
            return False

    def waitForMessages(self, number, connection=None, dn=None):
        """Wait for all the expected messages to arrive
        The connection is passed through to keep the connection alive
        until all the logging messages have been received.
        """

        self.connection = connection

        start_time = time.time()
        while not self.haveExpected(number, dn):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                print("Timed out")
                return []

        self.connection = None
        if dn is None:
            return self.context["messages"]

        messages = []
        for msg in self.context["messages"]:
            audit = getAudit(msg)
            if audit["dn"].lower() == dn.lower():
                messages.append(msg)
        return messages

    # Discard any previously queued messages.
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while (len(self.context["messages"])
               or self.context["txnMessage"] is not None):

            self.context["messages"] = []
            self.context["txnMessage"] = None
            self.msg_ctx.loop_once(0.001)

    GUID_RE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"

    #
    # Is the supplied GUID string correctly formatted
    #
    def is_guid(self, guid):
        return re.match(self.GUID_RE, guid)

    def get_session(self):
        return self.auth_context["sessionId"]

    def get_service_description(self):
        return self.auth_context["serviceDescription"]
Beispiel #20
0
    def setUp(self):
        super(AuditLogTestBase, self).setUp()

        # connect to the server's messaging bus (we need to explicitly load a
        # different smb.conf here, because in all other respects this test
        # wants to act as a separate remote client)
        server_conf = os.getenv('SERVERCONFFILE')
        if server_conf:
            lp_ctx = LoadParm(filename_for_non_global_lp=server_conf)
        else:
            lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(self.event_type)

        # Now switch back to using the client-side smb.conf. The tests will
        # use the first interface in the client.conf (we need to strip off
        # the subnet mask portion)
        lp_ctx = self.get_loadparm()
        client_ip_and_mask = lp_ctx.get('interfaces')[0]
        client_ip = client_ip_and_mask.split('/')[0]

        # the messaging ctx is the server's view of the world, so our own
        # client IP will be the remoteAddress when connections are logged
        self.remoteAddress = client_ip

        #
        # Check the remote address of a message against the one being used
        # for the tests.
        #
        def isRemote(message):
            audit = getAudit(message)
            if audit is None:
                return False

            remote = audit["remoteAddress"]
            if remote is None:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            if ((jsonMsg["type"] == "passwordChange" or
                jsonMsg["type"] == "dsdbChange" or
                jsonMsg["type"] == "groupChange") and
                    isRemote(jsonMsg)):
                context["messages"].append(jsonMsg)
            elif jsonMsg["type"] == "dsdbTransaction":
                context["txnMessage"] = jsonMsg

        self.context = {"messages": [], "txnMessage": None}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=self.message_type)

        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def authHandler(context, msgType, src, message):
            jsonMsg = json.loads(message)
            if jsonMsg["type"] == "Authorization" and isRemote(jsonMsg):
                # This does not look like sub unit output and it
                # makes these tests much easier to debug.
                print(message)
                context["sessionId"] = jsonMsg["Authorization"]["sessionId"]
                context["serviceDescription"] =\
                    jsonMsg["Authorization"]["serviceDescription"]

        self.auth_context = {"sessionId": "", "serviceDescription": ""}
        self.auth_handler_and_context = (authHandler, self.auth_context)
        self.msg_ctx.register(self.auth_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.server = os.environ["SERVER"]
        self.connection = None
Beispiel #21
0
class AuditLogTestBase(samba.tests.TestCase):

    def setUp(self):
        super(AuditLogTestBase, self).setUp()

        # connect to the server's messaging bus (we need to explicitly load a
        # different smb.conf here, because in all other respects this test
        # wants to act as a separate remote client)
        server_conf = os.getenv('SERVERCONFFILE')
        if server_conf:
            lp_ctx = LoadParm(filename_for_non_global_lp=server_conf)
        else:
            lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(self.event_type)

        # Now switch back to using the client-side smb.conf. The tests will
        # use the first interface in the client.conf (we need to strip off
        # the subnet mask portion)
        lp_ctx = self.get_loadparm()
        client_ip_and_mask = lp_ctx.get('interfaces')[0]
        client_ip = client_ip_and_mask.split('/')[0]

        # the messaging ctx is the server's view of the world, so our own
        # client IP will be the remoteAddress when connections are logged
        self.remoteAddress = client_ip

        #
        # Check the remote address of a message against the one being used
        # for the tests.
        #
        def isRemote(message):
            audit = getAudit(message)
            if audit is None:
                return False

            remote = audit["remoteAddress"]
            if remote is None:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            if ((jsonMsg["type"] == "passwordChange" or
                jsonMsg["type"] == "dsdbChange" or
                jsonMsg["type"] == "groupChange") and
                    isRemote(jsonMsg)):
                context["messages"].append(jsonMsg)
            elif jsonMsg["type"] == "dsdbTransaction":
                context["txnMessage"] = jsonMsg

        self.context = {"messages": [], "txnMessage": None}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=self.message_type)

        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def authHandler(context, msgType, src, message):
            jsonMsg = json.loads(message)
            if jsonMsg["type"] == "Authorization" and isRemote(jsonMsg):
                # This does not look like sub unit output and it
                # makes these tests much easier to debug.
                print(message)
                context["sessionId"] = jsonMsg["Authorization"]["sessionId"]
                context["serviceDescription"] =\
                    jsonMsg["Authorization"]["serviceDescription"]

        self.auth_context = {"sessionId": "", "serviceDescription": ""}
        self.auth_handler_and_context = (authHandler, self.auth_context)
        self.msg_ctx.register(self.auth_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.server = os.environ["SERVER"]
        self.connection = None

    def tearDown(self):
        self.discardMessages()
        self.msg_ctx.irpc_remove_name(self.event_type)
        self.msg_ctx.irpc_remove_name(AUTH_EVENT_NAME)
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=self.message_type)
        if self.auth_handler_and_context:
            self.msg_ctx.deregister(self.auth_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)

    def haveExpected(self, expected, dn):
        if dn is None:
            return len(self.context["messages"]) >= expected
        else:
            received = 0
            for msg in self.context["messages"]:
                audit = getAudit(msg)
                if audit["dn"].lower() == dn.lower():
                    received += 1
                    if received >= expected:
                        return True
            return False

    def waitForMessages(self, number, connection=None, dn=None):
        """Wait for all the expected messages to arrive
        The connection is passed through to keep the connection alive
        until all the logging messages have been received.
        """

        self.connection = connection

        start_time = time.time()
        while not self.haveExpected(number, dn):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                print("Timed out")
                return []

        self.connection = None
        if dn is None:
            return self.context["messages"]

        messages = []
        for msg in self.context["messages"]:
            audit = getAudit(msg)
            if audit["dn"].lower() == dn.lower():
                messages.append(msg)
        return messages

    # Discard any previously queued messages.
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while (len(self.context["messages"]) or
               self.context["txnMessage"] is not None):

            self.context["messages"] = []
            self.context["txnMessage"] = None
            self.msg_ctx.loop_once(0.001)

    GUID_RE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"

    #
    # Is the supplied GUID string correctly formatted
    #
    def is_guid(self, guid):
        return re.match(self.GUID_RE, guid)

    def get_session(self):
        return self.auth_context["sessionId"]

    def get_service_description(self):
        return self.auth_context["serviceDescription"]
Beispiel #22
0
 def get_context(self, *args, **kwargs):
     kwargs['lp_ctx'] = samba.tests.env_loadparm()
     return Messaging(*args, **kwargs)
Beispiel #23
0
class AuthLogTestBase(samba.tests.TestCase):

    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            context["messages"].append(jsonMsg)

        self.context = {"messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None

    def tearDown(self):
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)
            self.msg_ctx.irpc_remove_name(AUTH_EVENT_NAME)

    def waitForMessages(self, isLastExpectedMessage, connection=None):
        """Wait for all the expected messages to arrive
        The connection is passed through to keep the connection alive
        until all the logging messages have been received.
        """

        def completed(messages):
            for message in messages:
                if isRemote(message) and isLastExpectedMessage(message):
                    return True
            return False

        def isRemote(message):
            remote = None
            if message["type"] == "Authorization":
                remote = message["Authorization"]["remoteAddress"]
            elif message["type"] == "Authentication":
                remote = message["Authentication"]["remoteAddress"]
            else:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        self.connection = connection

        start_time = time.time()
        while not completed(self.context["messages"]):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                return []

        self.connection = None
        return filter(isRemote, self.context["messages"])

    # Discard any previously queued messages.
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while len(self.context["messages"]):
            self.msg_ctx.loop_once(0.001)
        self.context["messages"] = []

    # Remove any NETLOGON authentication messages
    # NETLOGON is only performed once per session, so to avoid ordering
    # dependencies within the tests it's best to strip out NETLOGON messages.
    #
    def remove_netlogon_messages(self, messages):
        def is_not_netlogon(msg):
            if "Authentication" not in msg:
                return True
            sd = msg["Authentication"]["serviceDescription"]
            return sd != "NETLOGON"

        return list(filter(is_not_netlogon, messages))

    GUID_RE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"

    #
    # Is the supplied GUID string correctly formatted
    #
    def is_guid(self, guid):
        return re.match(self.GUID_RE, guid)
Beispiel #24
0
class AuthLogTestBase(samba.tests.TestCase):

    @classmethod
    def setUpClass(self):
        # connect to the server's messaging bus (we need to explicitly load a
        # different smb.conf here, because in all other respects this test
        # wants to act as a separate remote client)
        server_conf = os.getenv('SERVERCONFFILE')
        if server_conf:
            lp_ctx = LoadParm(filename_for_non_global_lp=server_conf)
        else:
            samba.tests.env_loadparm()
        self.msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        # Now switch back to using the client-side smb.conf. The tests will
        # use the first interface in the client.conf (we need to strip off
        # the subnet mask portion)
        lp_ctx = samba.tests.env_loadparm()
        client_ip_and_mask = lp_ctx.get('interfaces')[0]
        client_ip = client_ip_and_mask.split('/')[0]

        # the messaging ctx is the server's view of the world, so our own
        # client IP will be the remoteAddress when connections are logged
        self.remoteAddress = client_ip

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print(message)
            jsonMsg = json.loads(message)
            context["messages"].append(jsonMsg)

        self.context = {"messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None

    @classmethod
    def tearDownClass(self):
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)
            self.msg_ctx.irpc_remove_name(AUTH_EVENT_NAME)

    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        self.discardMessages()

    def waitForMessages(self, isLastExpectedMessage, connection=None):
        """Wait for all the expected messages to arrive
        The connection is passed through to keep the connection alive
        until all the logging messages have been received.
        """

        def completed(messages):
            for message in messages:
                if isRemote(message) and isLastExpectedMessage(message):
                    return True
            return False

        def isRemote(message):
            if self.remoteAddress is None:
                return True

            remote = None
            if message["type"] == "Authorization":
                remote = message["Authorization"]["remoteAddress"]
            elif message["type"] == "Authentication":
                remote = message["Authentication"]["remoteAddress"]
            else:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        self.connection = connection

        start_time = time.time()
        while not completed(self.context["messages"]):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                return []

        self.connection = None
        return list(filter(isRemote, self.context["messages"]))

    # Discard any previously queued messages.
    @classmethod
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while len(self.context["messages"]):
            self.context["messages"] = []
            self.msg_ctx.loop_once(0.001)

    # Remove any NETLOGON authentication messages
    # NETLOGON is only performed once per session, so to avoid ordering
    # dependencies within the tests it's best to strip out NETLOGON messages.
    #
    def remove_netlogon_messages(self, messages):
        def is_not_netlogon(msg):
            if "Authentication" not in msg:
                return True
            sd = msg["Authentication"]["serviceDescription"]
            return sd != "NETLOGON"

        return list(filter(is_not_netlogon, messages))

    GUID_RE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"

    #
    # Is the supplied GUID string correctly formatted
    #
    def is_guid(self, guid):
        return re.match(self.GUID_RE, guid)
Beispiel #25
0
class AuthLogTestBase(samba.tests.TestCase):
    def setUp(self):
        super(AuthLogTestBase, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging((1, ), lp_ctx=lp_ctx)
        self.msg_ctx.irpc_add_name(AUTH_EVENT_NAME)

        def messageHandler(context, msgType, src, message):
            # This does not look like sub unit output and it
            # makes these tests much easier to debug.
            print message
            jsonMsg = json.loads(message)
            context["messages"].append(jsonMsg)

        self.context = {"messages": []}
        self.msg_handler_and_context = (messageHandler, self.context)
        self.msg_ctx.register(self.msg_handler_and_context,
                              msg_type=MSG_AUTH_LOG)

        self.discardMessages()

        self.remoteAddress = None
        self.server = os.environ["SERVER"]
        self.connection = None

    def tearDown(self):
        if self.msg_handler_and_context:
            self.msg_ctx.deregister(self.msg_handler_and_context,
                                    msg_type=MSG_AUTH_LOG)

    def waitForMessages(self, isLastExpectedMessage, connection=None):
        def completed(messages):
            for message in messages:
                if isRemote(message) and isLastExpectedMessage(message):
                    return True
            return False

        def isRemote(message):
            remote = None
            if message["type"] == "Authorization":
                remote = message["Authorization"]["remoteAddress"]
            elif message["type"] == "Authentication":
                remote = message["Authentication"]["remoteAddress"]
            else:
                return False

            try:
                addr = remote.split(":")
                return addr[1] == self.remoteAddress
            except IndexError:
                return False

        self.connection = connection

        start_time = time.time()
        while not completed(self.context["messages"]):
            self.msg_ctx.loop_once(0.1)
            if time.time() - start_time > 1:
                self.connection = None
                return []

        self.connection = None
        return filter(isRemote, self.context["messages"])

    # Discard any previously queued messages.
    def discardMessages(self):
        self.msg_ctx.loop_once(0.001)
        while len(self.context["messages"]):
            self.msg_ctx.loop_once(0.001)
        self.context["messages"] = []
Beispiel #26
0
class SmbcontrolProcessBlockboxTests(BlackboxTestCase):
    def setUp(self):
        super(SmbcontrolProcessBlockboxTests, self).setUp()
        lp_ctx = self.get_loadparm()
        self.msg_ctx = Messaging(lp_ctx=lp_ctx)

    def get_process_data(self):
        services = self.msg_ctx.irpc_all_servers()

        processes = []
        for service in services:
            for id in service.ids:
                processes.append((service.name, id.pid))
        return processes

    def get_process(self, name):
        processes = self.get_process_data()
        for pname, pid in processes:
            if name == pname:
                return pid
        return None

    def test_inject_fault(self):
        INJECT = "inject"
        FAULT = "segv"
        #
        # Note that this process name needs to be different to the one used
        # in the sleep test to avoid a race condition
        #
        pid = self.get_process("rpc_server")

        #
        # Ensure we can ping the process before injecting a fault.
        #
        try:
            self.check_run("%s %s %s" % (COMMAND, pid, PING),
                           msg="trying to ping rpc_server")
        except BlackboxProcessError as e:
            self.fail("Unable to ping rpc_server process")

        #
        # Now inject a fault.
        #
        try:
            self.check_run("%s %s %s %s" % (COMMAND, pid, INJECT, FAULT),
                           msg="injecting fault into rpc_server")
        except BlackboxProcessError as e:
            print(e)
            self.fail("Unable to inject a fault into the rpc_server process")

        #
        # The process should have died, so we should not be able to ping it
        #
        try:
            self.check_run("%s %s %s" % (COMMAND, pid, PING),
                           msg="trying to ping rpc_server")
            self.fail("Could ping rpc_server process")
        except BlackboxProcessError as e:
            pass

    def test_sleep(self):
        SLEEP = "sleep"  # smbcontrol sleep command
        DURATION = 5  # duration to sleep server for
        DELTA = 1  # permitted error for the sleep duration

        #
        # Note that this process name needs to be different to the one used
        # in the inject fault test to avoid a race condition
        #
        pid = self.get_process("ldap_server")
        #
        # Ensure we can ping the process before getting it to sleep
        #
        try:
            self.check_run("%s %s %s" % (COMMAND, pid, PING),
                           msg="trying to ping rpc_server")
        except BlackboxProcessError as e:
            self.fail("Unable to ping rpc_server process")

        #
        # Now ask it to sleep
        #
        start = time.time()
        try:
            self.check_run("%s %s %s %s" % (COMMAND, pid, SLEEP, DURATION),
                           msg="putting rpc_server to sleep for %d" % DURATION)
        except BlackboxProcessError as e:
            print(e)
            self.fail("Failed to get rpc_server to sleep for %d" % DURATION)

        #
        # The process should be sleeping and not respond until it wakes
        #
        try:
            self.check_run("%s %s %s" % (COMMAND, pid, PING),
                           msg="trying to ping rpc_server")
            end = time.time()
            duration = end - start
            self.assertGreater(duration + DELTA, DURATION)
        except BlackboxProcessError as e:
            self.fail("Unable to ping rpc_server process")
Beispiel #27
0
 def setUp(self):
     super(SmbcontrolBlockboxTests, self).setUp()
     lp_ctx = self.get_loadparm()
     self.msg_ctx = Messaging(lp_ctx=lp_ctx)
Beispiel #28
0
 def get_context(self, *args, **kwargs):
     return Messaging(*args, **kwargs)