The branch, master has been updated
       via  0837d0b python: Provide Python bindings for messaging.idl
       via  a3c9ad5 messaging: Declare well known server name auth_events as 
AUTH_EVENT_NAME in IDL
       via  6e87aa3 messaging.idl: Register a message type for authentication 
log messages
       via  16e9448 pymessaging: add single element tupple form of the server_id
       via  8c75d9f pymessaging: Add a hook to run the event loop, make 
callbacks practical
       via  e92a207 server_id_db: Protect against non-0-terminated data records
       via  0c25c40 selftest: Test server_id database add and removal
       via  e77c180 pymessaging: Add irpc_remove_name
       via  3bd9e5f pymessaging: Add support for irpc_add_name
       via  a47a8e4 samba-tool: Ensure that samba-tool processes 
--name=not-existing does not error
       via  f21c17c selftest: Add more tests for "samba-tool processes"
      from  782172a s3: Test for CVE-2017-2619 regression with "follow symlinks 
= no".

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0837d0b9dca5efe8f9cade28fc2ed8b695d6f4c2
Author: Andrew Bartlett <[email protected]>
Date:   Tue Mar 14 13:09:02 2017 +1300

    python: Provide Python bindings for messaging.idl
    
    This will allow AUTH_EVENT_NAME and MSG_AUTH_LOG to be accessed from python
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    
    Autobuild-User(master): Andrew Bartlett <[email protected]>
    Autobuild-Date(master): Tue Mar 28 13:19:03 CEST 2017 on sn-devel-144

commit a3c9ad53a2543525092e78697af9816b94281960
Author: Andrew Bartlett <[email protected]>
Date:   Tue Mar 14 12:37:15 2017 +1300

    messaging: Declare well known server name auth_events as AUTH_EVENT_NAME in 
IDL
    
    This makes it easy to ensure we use the same name in the python and the C
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit 6e87aa38c4daf40f089915fd5e40e97076d35aa2
Author: Andrew Bartlett <[email protected]>
Date:   Tue Mar 7 15:09:38 2017 +1300

    messaging.idl: Register a message type for authentication log messages
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    Pair-Programmed-by: Gary Lockyer <[email protected]>
    Signed-off-by: Gary Lockyer <[email protected]>

commit 16e9448174a7cb7ece90a7a68b7f0fd8ffa4de91
Author: Gary Lockyer <[email protected]>
Date:   Thu Mar 16 16:26:01 2017 +1300

    pymessaging: add single element tupple form of the server_id
    
    This avoids the python code needing to call getpid() internally,
    while declaring a stable task_id.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit 8c75d9fc73614fad29a998d08c4b11034ab2aebb
Author: Andrew Bartlett <[email protected]>
Date:   Tue Mar 14 12:39:13 2017 +1300

    pymessaging: Add a hook to run the event loop, make callbacks practical
    
    These change allow us to write a messaging server in python.
    
    The previous ping_speed test did not actually test anything, so
    we use .loop_once() to make it actually work.  To enable practial use
    a context is supplied in the tuple with the callback, and the server_id
    for the reply is not placed inside an additional tuple.
    
    In order to get at the internal event context on which to loop, we
    expose imessaging_context in messaging_internal.h and allow the python
    bindings to use that header.
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>

commit e92a20781ca45b8696397cdef424fe8b92bee66b
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 23 15:48:25 2017 +0100

    server_id_db: Protect against non-0-terminated data records
    
    Remove the failing test from knownfail.
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12705

commit 0c25c40315a8255362780486d2f2e27ea0dbbff4
Author: Andrew Bartlett <[email protected]>
Date:   Tue Mar 14 16:07:46 2017 +1300

    selftest: Test server_id database add and removal
    
    This tests indirectly server_id_db_lookup() and
    server_id_db_prune_name(), as well as the imessaging
    and the imessaging python bindings.
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12705

commit e77c18019aef9c98caa0b66cb2e9da5a6f58e600
Author: Andrew Bartlett <[email protected]>
Date:   Tue Mar 14 13:39:00 2017 +1300

    pymessaging: Add irpc_remove_name
    
    This allows tests to be indirectly added for server_id_db_lookup()
    and server_id_db_prune_name()
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12705

commit 3bd9e5f4ed2362f5006144433295cde2276272c5
Author: Andrew Bartlett <[email protected]>
Date:   Wed Mar 8 14:53:26 2017 +1300

    pymessaging: Add support for irpc_add_name
    
    This allows tests to be indirectly added for server_id_db_lookup()
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    Pair-Programmed-by: Gary Lockyer <[email protected]>
    Signed-off-by: Gary Lockyer <[email protected]>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12705

commit a47a8e41bd3acc20d40ba78449d89775bcdd73ed
Author: Andrew Bartlett <[email protected]>
Date:   Fri Mar 24 13:07:06 2017 +1300

    samba-tool: Ensure that samba-tool processes --name=not-existing does not 
error
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12705

commit f21c17c6d0bfa304c54d80aaceb91aad1a3a6bb1
Author: Andrew Bartlett <[email protected]>
Date:   Fri Mar 24 13:07:23 2017 +1300

    selftest: Add more tests for "samba-tool processes"
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12705

-----------------------------------------------------------------------

Summary of changes:
 lib/util/server_id_db.c                            |  22 +++-
 librpc/idl/messaging.idl                           |   6 +
 librpc/idl/wscript_build                           |   7 +-
 python/samba/netcmd/processes.py                   |   6 +-
 python/samba/tests/messaging.py                    | 113 ++++++++++++++--
 python/samba/tests/samba_tool/processes.py         |   6 +
 source4/lib/messaging/messaging.c                  |  17 +--
 .../lib/messaging/messaging_internal.h             |  21 ++-
 source4/lib/messaging/pymessaging.c                | 143 +++++++++++++++++++--
 source4/librpc/wscript_build                       |   6 +
 10 files changed, 292 insertions(+), 55 deletions(-)
 copy libcli/auth/schannel.h => source4/lib/messaging/messaging_internal.h (62%)


Changeset truncated at 500 lines:

diff --git a/lib/util/server_id_db.c b/lib/util/server_id_db.c
index e0b8476..e190f45 100644
--- a/lib/util/server_id_db.c
+++ b/lib/util/server_id_db.c
@@ -138,6 +138,7 @@ int server_id_db_prune_name(struct server_id_db *db, const 
char *name,
        char idbuf[idbuf_len];
        TDB_DATA key;
        uint8_t *data;
+       size_t datalen;
        char *ids, *id;
        int ret;
 
@@ -156,6 +157,13 @@ int server_id_db_prune_name(struct server_id_db *db, const 
char *name,
                return ret;
        }
 
+       datalen = talloc_get_size(data);
+       if ((datalen == 0) || (data[datalen-1] != '\0')) {
+               tdb_chainunlock(tdb, key);
+               TALLOC_FREE(data);
+               return EINVAL;
+       }
+
        ids = (char *)data;
 
        id = strv_find(ids, idbuf);
@@ -166,7 +174,12 @@ int server_id_db_prune_name(struct server_id_db *db, const 
char *name,
        }
 
        strv_delete(&ids, id);
-       ret = tdb_store(tdb, key, talloc_tdb_data(ids), TDB_MODIFY);
+
+       if (talloc_get_size(ids) == 0) {
+               ret = tdb_delete(tdb, key);
+       } else {
+               ret = tdb_store(tdb, key, talloc_tdb_data(ids), TDB_MODIFY);
+       }
        TALLOC_FREE(data);
 
        tdb_chainunlock(tdb, key);
@@ -200,6 +213,7 @@ int server_id_db_lookup(struct server_id_db *db, const char 
*name,
        struct tdb_context *tdb = db->tdb->tdb;
        TDB_DATA key;
        uint8_t *data;
+       size_t datalen;
        char *ids, *id;
        unsigned num_servers;
        struct server_id *servers;
@@ -212,6 +226,12 @@ int server_id_db_lookup(struct server_id_db *db, const 
char *name,
                return ret;
        }
 
+       datalen = talloc_get_size(data);
+       if ((datalen == 0) || (data[datalen-1] != '\0')) {
+               TALLOC_FREE(data);
+               return EINVAL;
+       }
+
        ids = (char *)data;
        num_servers = strv_count(ids);
 
diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index 032f95e..b962ab1 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -139,6 +139,9 @@ interface messaging
                MSG_NTVFS_OPLOCK_BREAK          = 0x0703,
                MSG_DREPL_ALLOCATE_RID          = 0x0704,
 
+               /* Called during authentication and authorization to allow 
out-of- */
+               MSG_AUTH_LOG                    = 0x0800,
+
                /* dbwrap messages 4001-4999 (0x0FA0 - 0x1387) */
                /* MSG_DBWRAP_TDB2_CHANGES              = 4001, */
                /* MSG_DBWRAP_G_LOCK_RETRY              = 4002, */
@@ -170,4 +173,7 @@ interface messaging
                uint32 num_recs;
                messaging_rec *recs[num_recs];
        } messaging_reclog;
+
+        /* This allows this well known service name to be referenced in python 
and C */
+        const string AUTH_EVENT_NAME = "auth_event";
 }
diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build
index 1f09ae0..899708c 100644
--- a/librpc/idl/wscript_build
+++ b/librpc/idl/wscript_build
@@ -24,16 +24,11 @@ bld.SAMBA_PIDL_LIST('PIDL',
                     output_dir='../gen_ndr')
 
 bld.SAMBA_PIDL_LIST('PIDL',
-                    'idmap.idl',
+                    'idmap.idl messaging.idl',
                     options='--header --ndr-parser --client --python',
                     output_dir='../gen_ndr')
 
 bld.SAMBA_PIDL_LIST('PIDL',
-                    'messaging.idl',
-                    options='--header --ndr-parser',
-                    output_dir='../gen_ndr')
-
-bld.SAMBA_PIDL_LIST('PIDL',
                     '''
                     rap.idl
                     ntprinting.idl
diff --git a/python/samba/netcmd/processes.py b/python/samba/netcmd/processes.py
index b25a2e4..c8000b7 100644
--- a/python/samba/netcmd/processes.py
+++ b/python/samba/netcmd/processes.py
@@ -60,7 +60,11 @@ class cmd_processes(Command):
         msg_ctx = Messaging()
 
         if name is not None:
-            ids = msg_ctx.irpc_servers_byname(name)
+            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:
diff --git a/python/samba/tests/messaging.py b/python/samba/tests/messaging.py
index 5d32d60..41834c1 100644
--- a/python/samba/tests/messaging.py
+++ b/python/samba/tests/messaging.py
@@ -21,7 +21,11 @@
 import samba
 from samba.messaging import Messaging
 from samba.tests import TestCase
-from samba.dcerpc.server_id import server_id
+import time
+from samba.ndr import ndr_print
+from samba.dcerpc import server_id
+import random
+import os
 
 class MessagingTests(TestCase):
 
@@ -33,7 +37,8 @@ class MessagingTests(TestCase):
         x = self.get_context()
         def callback():
             pass
-        msg_type = x.register(callback)
+        msg_type = x.register((callback, None))
+        self.assertTrue(isinstance(msg_type, long))
         x.deregister(callback, msg_type)
 
     def test_all_servers(self):
@@ -45,24 +50,104 @@ class MessagingTests(TestCase):
         for name in x.irpc_all_servers():
             self.assertTrue(isinstance(x.irpc_servers_byname(name.name), list))
 
+    def test_unknown_name(self):
+        x = self.get_context()
+        self.assertRaises(KeyError,
+                          x.irpc_servers_byname, "samba.messaging test 
NONEXISTING")
+
     def test_assign_server_id(self):
         x = self.get_context()
-        self.assertTrue(isinstance(x.server_id, server_id))
+        self.assertTrue(isinstance(x.server_id, server_id.server_id))
+
+    def test_add_remove_name(self):
+        x = self.get_context()
+        name = "samba.messaging test-%d" % random.randint(1, 1000000)
+        x.irpc_add_name(name)
+        name_list = x.irpc_servers_byname(name)
+        self.assertEqual(len(name_list), 1)
+        self.assertEqual(ndr_print(x.server_id),
+                         ndr_print(name_list[0]))
+        x.irpc_remove_name(name)
+        self.assertRaises(KeyError,
+                          x.irpc_servers_byname, name)
 
     def test_ping_speed(self):
+        got_ping = {"count": 0}
+        got_pong = {"count": 0}
+        timeout = False
+
+        msg_pong = 0
+        msg_ping = 0
+
         server_ctx = self.get_context((0, 1))
-        def ping_callback(src, data):
-                server_ctx.send(src, data)
-        def exit_callback():
-                print "received exit"
-        msg_ping = server_ctx.register(ping_callback)
-        msg_exit = server_ctx.register(exit_callback)
-
-        def pong_callback():
-                print "received pong"
+        def ping_callback(got_ping, msg_type, src, data):
+            got_ping["count"] += 1
+            server_ctx.send(src, msg_pong, data)
+
+        msg_ping = server_ctx.register((ping_callback, got_ping))
+
+        def pong_callback(got_pong, msg_type, src, data):
+            got_pong["count"] += 1
+
         client_ctx = self.get_context((0, 2))
-        msg_pong = client_ctx.register(pong_callback)
+        msg_pong = client_ctx.register((pong_callback, got_pong))
 
+        # Try both server_id forms (structure and tuple)
         client_ctx.send((0, 1), msg_ping, "testing")
-        client_ctx.send((0, 1), msg_ping, "")
 
+        client_ctx.send((0, 1), msg_ping, "testing2")
+
+        start_time = time.time()
+
+        # NOTE WELL: If debugging this with GDB, then the timeout will
+        # fire while you are trying to understand it.
+
+        while (got_ping["count"] < 2 or got_pong["count"] < 2) and not timeout:
+            client_ctx.loop_once(0.1)
+            server_ctx.loop_once(0.1)
+            if time.time() - start_time > 1:
+                timeout = True
+
+        self.assertEqual(got_ping["count"], 2)
+        self.assertEqual(got_pong["count"], 2)
+
+    def test_pid_defaulting(self):
+        got_ping = {"count": 0}
+        got_pong = {"count": 0}
+        timeout = False
+
+        msg_pong = 0
+        msg_ping = 0
+
+        pid = os.getpid()
+        server_ctx = self.get_context((pid, 1))
+        def ping_callback(got_ping, msg_type, src, data):
+            got_ping["count"] += 1
+            server_ctx.send(src, msg_pong, data)
+
+        msg_ping = server_ctx.register((ping_callback, got_ping))
+
+        def pong_callback(got_pong, msg_type, src, data):
+            got_pong["count"] += 1
+
+        client_ctx = self.get_context((2,))
+        msg_pong = client_ctx.register((pong_callback, got_pong))
+
+        # Try one and two element tuple forms
+        client_ctx.send((pid, 1), msg_ping, "testing")
+
+        client_ctx.send((1,), msg_ping, "testing2")
+
+        start_time = time.time()
+
+        # NOTE WELL: If debugging this with GDB, then the timeout will
+        # fire while you are trying to understand it.
+
+        while (got_ping["count"] < 2 or got_pong["count"] < 2) and not timeout:
+            client_ctx.loop_once(0.1)
+            server_ctx.loop_once(0.1)
+            if time.time() - start_time > 1:
+                timeout = True
+
+        self.assertEqual(got_ping["count"], 2)
+        self.assertEqual(got_pong["count"], 2)
diff --git a/python/samba/tests/samba_tool/processes.py 
b/python/samba/tests/samba_tool/processes.py
index 5b8f502..cff9cad 100644
--- a/python/samba/tests/samba_tool/processes.py
+++ b/python/samba/tests/samba_tool/processes.py
@@ -29,6 +29,12 @@ class ProcessCmdTestCase(SambaToolCmdTest):
         (result, out, err) = self.runcmd("processes", "--name", "samba")
         self.assertCmdSuccess(result, out, err, "Ensuring processes ran 
successfully")
 
+    def test_unknown_name(self):
+        """Run processes command with an not-existing --name"""
+        (result, out, err) = self.runcmd("processes", "--name", 
"not-existing-samba")
+        self.assertCmdSuccess(result, out, err, "Ensuring processes ran 
successfully")
+        self.assertEqual(out, "")
+
     def test_all(self):
         """Run processes command"""
         (result, out, err) = self.runcmd("processes")
diff --git a/source4/lib/messaging/messaging.c 
b/source4/lib/messaging/messaging.c
index 84df934..4d75f09 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -24,6 +24,7 @@
 #include "lib/util/server_id.h"
 #include "system/filesys.h"
 #include "messaging/messaging.h"
+#include "messaging/messaging_internal.h"
 #include "../lib/util/dlinklist.h"
 #include "lib/socket/socket.h"
 #include "librpc/gen_ndr/ndr_irpc.h"
@@ -55,22 +56,6 @@ struct irpc_request {
        } incoming;
 };
 
-struct imessaging_context {
-       struct imessaging_context *prev, *next;
-       struct tevent_context *ev;
-       struct server_id server_id;
-       const char *sock_dir;
-       const char *lock_dir;
-       struct dispatch_fn **dispatch;
-       uint32_t num_types;
-       struct idr_context *dispatch_tree;
-       struct irpc_list *irpc;
-       struct idr_context *idr;
-       struct server_id_db *names;
-       struct timeval start_time;
-       void *msg_dgm_ref;
-};
-
 /* we have a linked list of dispatch handlers for each msg_type that
    this messaging server can deal with */
 struct dispatch_fn {
diff --git a/libcli/auth/schannel.h b/source4/lib/messaging/messaging_internal.h
similarity index 62%
copy from libcli/auth/schannel.h
copy to source4/lib/messaging/messaging_internal.h
index c53d68e..93c5c4b 100644
--- a/libcli/auth/schannel.h
+++ b/source4/lib/messaging/messaging_internal.h
@@ -1,10 +1,9 @@
 /*
    Unix SMB/CIFS implementation.
 
-   dcerpc schannel operations
+   Samba internal messaging functions
 
    Copyright (C) Andrew Tridgell 2004
-   Copyright (C) Andrew Bartlett <[email protected]> 2004-2005
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,6 +19,18 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "libcli/auth/libcli_auth.h"
-#include "libcli/auth/schannel_state.h"
-#include "libcli/auth/schannel_proto.h"
+struct imessaging_context {
+       struct imessaging_context *prev, *next;
+       struct tevent_context *ev;
+       struct server_id server_id;
+       const char *sock_dir;
+       const char *lock_dir;
+       struct dispatch_fn **dispatch;
+       uint32_t num_types;
+       struct idr_context *dispatch_tree;
+       struct irpc_list *irpc;
+       struct idr_context *idr;
+       struct server_id_db *names;
+       struct timeval start_time;
+       void *msg_dgm_ref;
+};
diff --git a/source4/lib/messaging/pymessaging.c 
b/source4/lib/messaging/pymessaging.c
index f62354b..d83f5e6 100644
--- a/source4/lib/messaging/pymessaging.c
+++ b/source4/lib/messaging/pymessaging.c
@@ -34,6 +34,7 @@
 #include "librpc/rpc/dcerpc.h"
 #include "librpc/gen_ndr/server_id.h"
 #include <pytalloc.h>
+#include "messaging_internal.h"
 
 void initmessaging(void);
 
@@ -61,13 +62,20 @@ static bool server_id_from_py(PyObject *object, struct 
server_id *server_id)
                server_id->task_id = task_id;
                server_id->vnn = vnn;
                return true;
-       } else {
+       } else if (PyTuple_Size(object) == 2) {
                unsigned long long pid;
                int task_id;
                if (!PyArg_ParseTuple(object, "KI", &pid, &task_id))
                        return false;
                *server_id = cluster_id(pid, task_id);
                return true;
+       } else {
+               unsigned long long pid = getpid();
+               int task_id;
+               if (!PyArg_ParseTuple(object, "I", &task_id))
+                       return false;
+               *server_id = cluster_id(pid, task_id);
+               return true;
        }
 }
 
@@ -173,7 +181,8 @@ static void py_msg_callback_wrapper(struct 
imessaging_context *msg, void *privat
                               uint32_t msg_type, 
                               struct server_id server_id, DATA_BLOB *data)
 {
-       PyObject *py_server_id, *callback = (PyObject *)private_data;
+       PyObject *py_server_id, *callback_and_tuple = (PyObject *)private_data;
+       PyObject *callback, *py_private;
 
        struct server_id *p_server_id = talloc(NULL, struct server_id);
        if (!p_server_id) {
@@ -182,10 +191,18 @@ static void py_msg_callback_wrapper(struct 
imessaging_context *msg, void *privat
        }
        *p_server_id = server_id;
 
+       if (!PyArg_ParseTuple(callback_and_tuple, "OO",
+                             &callback,
+                             &py_private)) {
+               return;
+       }
+
        py_server_id = py_return_ndr_struct("samba.dcerpc.server_id", 
"server_id", p_server_id, p_server_id);
        talloc_unlink(NULL, p_server_id);
 
-       PyObject_CallFunction(callback, discard_const_p(char, "i(O)s#"), 
msg_type,
+       PyObject_CallFunction(callback, discard_const_p(char, "OiOs#"),
+                             py_private,
+                             msg_type,
                              py_server_id,
                              data->data, data->length);
 }
@@ -194,24 +211,30 @@ static PyObject *py_imessaging_register(PyObject *self, 
PyObject *args, PyObject
 {
        imessaging_Object *iface = (imessaging_Object *)self;
        int msg_type = -1;
-       PyObject *callback;
+       PyObject *callback_and_context;
        NTSTATUS status;
-       const char *kwnames[] = { "callback", "msg_type", NULL };
+       const char *kwnames[] = { "callback_and_context", "msg_type", NULL };
        
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:register", 
-               discard_const_p(char *, kwnames), &callback, &msg_type)) {
+               discard_const_p(char *, kwnames),
+                                        &callback_and_context, &msg_type)) {
+               return NULL;
+       }
+       if (!PyTuple_Check(callback_and_context)
+           || PyTuple_Size(callback_and_context) != 2) {
+               PyErr_SetString(PyExc_ValueError, "Expected of size 2 for 
callback_and_context");
                return NULL;
        }
 
-       Py_INCREF(callback);
+       Py_INCREF(callback_and_context);
 
        if (msg_type == -1) {
                uint32_t msg_type32 = msg_type;
-               status = imessaging_register_tmp(iface->msg_ctx, callback,
+               status = imessaging_register_tmp(iface->msg_ctx, 
callback_and_context,
                                                py_msg_callback_wrapper, 
&msg_type32);
                msg_type = msg_type32;
        } else {
-               status = imessaging_register(iface->msg_ctx, callback,
+               status = imessaging_register(iface->msg_ctx, 
callback_and_context,
                                    msg_type, py_msg_callback_wrapper);
        }
        if (NT_STATUS_IS_ERR(status)) {
@@ -241,6 +264,85 @@ static PyObject *py_imessaging_deregister(PyObject *self, 
PyObject *args, PyObje
        Py_RETURN_NONE;
 }
 
+static void simple_timer_handler(struct tevent_context *ev,
+                                struct tevent_timer *te,
+                                struct timeval current_time,
+                                void *private_data)
+{
+       return;
+}
+
+static PyObject *py_imessaging_loop_once(PyObject *self, PyObject *args, 
PyObject *kwargs)
+{
+       imessaging_Object *iface = (imessaging_Object *)self;
+       double offset;
+       int seconds;
+       struct timeval next_event;
+       struct tevent_timer *timer = NULL;
+       const char *kwnames[] = { "timeout", NULL };
+
+       TALLOC_CTX *frame = talloc_stackframe();
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d",
+                                        discard_const_p(char *, kwnames), 
&offset)) {
+               TALLOC_FREE(frame);
+               return NULL;
+       }
+
+       if (offset != 0.0) {
+               seconds = offset;
+               offset -= seconds;
+               next_event = tevent_timeval_current_ofs(seconds, 
(int)(offset*1000000));
+
+               timer = tevent_add_timer(iface->msg_ctx->ev, frame, next_event, 
simple_timer_handler,
+                                        NULL);
+               if (timer == NULL) {
+                       PyErr_NoMemory();
+                       TALLOC_FREE(frame);
+                       return NULL;


-- 
Samba Shared Repository

Reply via email to