impersonation part 3 (Re: [Patches] Preparation for tevent impersonation (part1))
Stefan Metzmacher
metze at samba.org
Sun Jun 17 20:59:04 UTC 2018
Am 14.06.2018 um 22:12 schrieb Jeremy Allison via samba-technical:
> On Thu, Jun 14, 2018 at 08:13:07PM +0200, Stefan Metzmacher wrote:
>> Hi Jeremy,
>>
>> here's the almost finished patchset, that actually implements the
>> impersonation for tevent. (The pthreadpool_tevent impersonation will
>> follow later as part4).
>>
>> This is (as part2) already reviewed by Ralph, but we want to
>> add some tests in tevent for the new wrapper infrastructure
>> and add useful debug message to the
>> smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers.
>> We'll do that once everything is otherwise complete, working and reviewed.
>
> Wow, this is a dense patchset :-). I'll study carefully,
> and send feedback.
Here's the update on top of the current part2.
It also passed some autobuilds and is ready and reviewed code wise,
Just the debug messages in [PATCH 35/37] FIXUP: add debuggging to
impersonation will be improved and squashed.
metze
-------------- next part --------------
From d8ada3e398128f965f669354fde26f054b956419 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 23 Sep 2015 04:27:53 +0200
Subject: [PATCH 01/37] tevent.h: improve tevent_req documentation
Document tevent_req naming conventions.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
lib/tevent/tevent.h | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 3ccac6a3600c..0e2e806ee5c4 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -697,6 +697,22 @@ void tevent_get_trace_callback(struct tevent_context *ev,
* the tevent_req structure can be talloc_free'ed. After it has
* finished, it should talloc_free'ed by the API user.
*
+ * tevent_req variable naming conventions:
+ *
+ * The name of the variable pointing to the tevent_req structure
+ * returned by a _send() function SHOULD be named differently between
+ * implementation and caller.
+ *
+ * From the point of view of the implementation (of the _send() and
+ * _recv() functions) the variable returned by tevent_req_create() is
+ * always called @em req.
+ *
+ * While the caller of the _send() function should use @em subreq to
+ * hold the result.
+ *
+ * @see tevent_req_create()
+ * @see tevent_req_fn()
+ *
* @{
*/
@@ -748,9 +764,9 @@ struct tevent_req;
/**
* @brief A tevent request callback function.
*
- * @param[in] req The tevent async request which executed this callback.
+ * @param[in] subreq The tevent async request which executed this callback.
*/
-typedef void (*tevent_req_fn)(struct tevent_req *req);
+typedef void (*tevent_req_fn)(struct tevent_req *subreq);
/**
* @brief Set an async request callback.
@@ -799,8 +815,6 @@ void *_tevent_req_callback_data(struct tevent_req *req);
*
* @param[in] req The structure to get the callback data from.
*
- * @param[in] req The structure to get the data from.
- *
* @return The private data or NULL if not set.
*/
void *tevent_req_callback_data_void(struct tevent_req *req);
--
2.17.1
From da8a26c3ee0611cfcedf7c356081b0286fed6cd2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 23 Oct 2014 06:54:10 +0200
Subject: [PATCH 02/37] tevent/testsuite: return after torture_fail()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/testsuite.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index 63abbf2dc1a6..08aa7588acee 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -191,8 +191,9 @@ static bool test_event_context(struct torture_context *test,
while (!finished) {
errno = 0;
if (tevent_loop_once(ev_ctx) == -1) {
- talloc_free(ev_ctx);
+ TALLOC_FREE(ev_ctx);
torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno)));
+ return false;
}
}
--
2.17.1
From 3485d98d39a1d964f571a6ecada7013c09c6760f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 16:51:01 +0100
Subject: [PATCH 03/37] tevent: allow tevent_abort() to cope with ev == NULL
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index a2d2003cbf43..3d32fd7e12de 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -577,8 +577,10 @@ void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
static void tevent_abort(struct tevent_context *ev, const char *reason)
{
- tevent_debug(ev, TEVENT_DEBUG_FATAL,
- "abort: %s\n", reason);
+ if (ev != NULL) {
+ tevent_debug(ev, TEVENT_DEBUG_FATAL,
+ "abort: %s\n", reason);
+ }
if (!tevent_abort_fn) {
abort();
--
2.17.1
From f8c295f990cde74ae084cd174d84314480b912aa Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 15:10:00 +0200
Subject: [PATCH 04/37] tevent: make tevent_abort() available for backends
We'll remove the _PRIVATE_ with the next release.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent.c | 5 ++---
lib/tevent/tevent_internal.h | 2 ++
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 3d32fd7e12de..501d548a9f09 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -70,8 +70,6 @@
#include <sys/eventfd.h>
#endif
-static void tevent_abort(struct tevent_context *ev, const char *reason);
-
struct tevent_ops_list {
struct tevent_ops_list *next, *prev;
const char *name;
@@ -575,7 +573,8 @@ void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
tevent_abort_fn = abort_fn;
}
-static void tevent_abort(struct tevent_context *ev, const char *reason)
+_PRIVATE_
+void tevent_abort(struct tevent_context *ev, const char *reason)
{
if (ev != NULL) {
tevent_debug(ev, TEVENT_DEBUG_FATAL,
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index ec3955e70a49..cbe2e69548dc 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -246,6 +246,8 @@ struct tevent_debug_ops {
void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
+void tevent_abort(struct tevent_context *ev, const char *reason);
+
struct tevent_context {
/* the specific events implementation */
const struct tevent_ops *ops;
--
2.17.1
From 12c326138ad47ae56d370eee6958b619c3b086cb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 23 Oct 2014 07:15:14 +0200
Subject: [PATCH 05/37] tevent: use struct initializers for tevent_fd
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_fd.c | 19 +++++++++----------
lib/tevent/tevent_poll.c | 21 +++++++++++----------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
index 455961b67c84..f33ae841b396 100644
--- a/lib/tevent/tevent_fd.c
+++ b/lib/tevent/tevent_fd.c
@@ -60,16 +60,15 @@ struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *me
fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
if (!fde) return NULL;
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->close_fn = NULL;
- fde->private_data = private_data;
- fde->handler_name = handler_name;
- fde->location = location;
- fde->additional_flags = 0;
- fde->additional_data = NULL;
+ *fde = (struct tevent_fd) {
+ .event_ctx = ev,
+ .fd = fd,
+ .flags = flags,
+ .handler = handler,
+ .private_data = private_data,
+ .handler_name = handler_name,
+ .location = location,
+ };
DLIST_ADD(ev->fd_events, fde);
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index 09d85fa322ad..f1d52533f5de 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -307,16 +307,17 @@ static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev,
if (fde == NULL) {
return NULL;
}
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->close_fn = NULL;
- fde->private_data = private_data;
- fde->handler_name = handler_name;
- fde->location = location;
- fde->additional_flags = UINT64_MAX;
- fde->additional_data = NULL;
+
+ *fde = (struct tevent_fd) {
+ .event_ctx = ev,
+ .fd = fd,
+ .flags = flags,
+ .handler = handler,
+ .private_data = private_data,
+ .handler_name = handler_name,
+ .location = location,
+ .additional_flags = UINT64_MAX,
+ };
tevent_poll_event_add_fd_internal(ev, fde);
poll_event_wake_pollthread(poll_ev);
--
2.17.1
From bc9f5ba0993fce79d517a52275fa027c860246be Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 23 Oct 2014 07:15:14 +0200
Subject: [PATCH 06/37] tevent: use struct initializers for tevent_timer
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_timed.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c
index 92f3ed17b26e..ae1eb98d8b2a 100644
--- a/lib/tevent/tevent_timed.c
+++ b/lib/tevent/tevent_timed.c
@@ -224,13 +224,14 @@ static struct tevent_timer *tevent_common_add_timer_internal(
te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer);
if (te == NULL) return NULL;
- te->event_ctx = ev;
- te->next_event = next_event;
- te->handler = handler;
- te->private_data = private_data;
- te->handler_name = handler_name;
- te->location = location;
- te->additional_data = NULL;
+ *te = (struct tevent_timer) {
+ .event_ctx = ev,
+ .next_event = next_event,
+ .handler = handler,
+ .private_data = private_data,
+ .handler_name = handler_name,
+ .location = location,
+ };
if (ev->timer_events == NULL) {
ev->last_zero_timer = NULL;
--
2.17.1
From d2305981cba15b383c6321bbc88057d3002db18a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 23 Oct 2014 07:15:14 +0200
Subject: [PATCH 07/37] tevent: use struct initializers for tevent_signal
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_signal.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index c85e1c528c4e..1283aab48211 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -257,22 +257,23 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
se = talloc(mem_ctx?mem_ctx:ev, struct tevent_signal);
if (se == NULL) return NULL;
- se->event_ctx = ev;
- se->signum = signum;
- se->sa_flags = sa_flags;
- se->handler = handler;
- se->private_data = private_data;
- se->handler_name = handler_name;
- se->location = location;
- se->additional_data = NULL;
-
sl = talloc(se, struct tevent_common_signal_list);
if (!sl) {
talloc_free(se);
return NULL;
}
sl->se = se;
- se->additional_data = sl;
+
+ *se = (struct tevent_signal) {
+ .event_ctx = ev,
+ .signum = signum,
+ .sa_flags = sa_flags,
+ .handler = handler,
+ .private_data = private_data,
+ .handler_name = handler_name,
+ .location = location,
+ .additional_data= sl,
+ };
/* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */
if (!talloc_reference(se, sig_state)) {
--
2.17.1
From 75be13ece04eca64cdae03f724892ea4b560566d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 23 Oct 2014 07:15:14 +0200
Subject: [PATCH 08/37] tevent: use struct initializers for tevent_immediate
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_immediate.c | 30 ++++++++++++++++--------------
lib/tevent/tevent_threads.c | 16 +++++++++-------
2 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index 9ff532234306..7b4c3e843ded 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -30,6 +30,8 @@
static void tevent_common_immediate_cancel(struct tevent_immediate *im)
{
+ const char *create_location = im->create_location;
+
if (!im->event_ctx) {
return;
}
@@ -44,13 +46,10 @@ static void tevent_common_immediate_cancel(struct tevent_immediate *im)
}
DLIST_REMOVE(im->event_ctx->immediate_events, im);
- im->event_ctx = NULL;
- im->handler = NULL;
- im->private_data = NULL;
- im->handler_name = NULL;
- im->schedule_location = NULL;
- im->cancel_fn = NULL;
- im->additional_data = NULL;
+
+ *im = (struct tevent_immediate) {
+ .create_location = create_location,
+ };
talloc_set_destructor(im, NULL);
}
@@ -74,19 +73,22 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
const char *handler_name,
const char *location)
{
+ const char *create_location = im->create_location;
+
tevent_common_immediate_cancel(im);
if (!handler) {
return;
}
- im->event_ctx = ev;
- im->handler = handler;
- im->private_data = private_data;
- im->handler_name = handler_name;
- im->schedule_location = location;
- im->cancel_fn = NULL;
- im->additional_data = NULL;
+ *im = (struct tevent_immediate) {
+ .event_ctx = ev,
+ .handler = handler,
+ .private_data = private_data,
+ .handler_name = handler_name,
+ .create_location = create_location,
+ .schedule_location = location,
+ };
DLIST_ADD_END(ev->immediate_events, im);
talloc_set_destructor(im, tevent_common_immediate_destructor);
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index 2c6e66b09049..728f8416d452 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -449,6 +449,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
const char *location)
{
#ifdef HAVE_PTHREAD
+ const char *create_location = im->create_location;
struct tevent_context *ev;
int ret, wakeup_fd;
@@ -474,13 +475,14 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
abort();
}
- im->event_ctx = ev;
- im->handler = handler;
- im->private_data = private_data;
- im->handler_name = handler_name;
- im->schedule_location = location;
- im->cancel_fn = NULL;
- im->additional_data = NULL;
+ *im = (struct tevent_immediate) {
+ .event_ctx = ev,
+ .handler = handler,
+ .private_data = private_data,
+ .handler_name = handler_name,
+ .create_location = create_location,
+ .schedule_location = location,
+ };
ret = pthread_mutex_lock(&ev->scheduled_mutex);
if (ret != 0) {
--
2.17.1
From 36c94f99efb57492a10221f73bf6c8de5445163d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 23 Mar 2018 10:25:27 +0100
Subject: [PATCH 09/37] tevent: use _tevent_schedule_immediate() to move events
from a thread to the main_ev
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_immediate.c | 8 +++++---
lib/tevent/tevent_threads.c | 14 +++++++++++++-
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index 7b4c3e843ded..c640a565b082 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -36,9 +36,11 @@ static void tevent_common_immediate_cancel(struct tevent_immediate *im)
return;
}
- tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE,
- "Cancel immediate event %p \"%s\"\n",
- im, im->handler_name);
+ if (im->handler_name != NULL) {
+ tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE,
+ "Cancel immediate event %p \"%s\"\n",
+ im, im->handler_name);
+ }
/* let the backend free im->additional_data */
if (im->cancel_fn) {
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index 728f8416d452..3f91ab8bc2ab 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -532,8 +532,20 @@ void tevent_common_threaded_activate_immediate(struct tevent_context *ev)
while (ev->scheduled_immediates != NULL) {
struct tevent_immediate *im = ev->scheduled_immediates;
+ struct tevent_immediate copy = *im;
+
DLIST_REMOVE(ev->scheduled_immediates, im);
- DLIST_ADD_END(ev->immediate_events, im);
+
+ tevent_debug(ev, TEVENT_DEBUG_TRACE,
+ "Schedule immediate event \"%s\": %p from thread into main\n",
+ im->handler_name, im);
+ im->handler_name = NULL;
+ _tevent_schedule_immediate(im,
+ ev,
+ copy.handler,
+ copy.private_data,
+ copy.handler_name,
+ copy.schedule_location);
}
ret = pthread_mutex_unlock(&ev->scheduled_mutex);
--
2.17.1
From d55dbcde9cb78d00350e08bd6f6f4c5faef33950 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 23 Mar 2018 10:32:15 +0100
Subject: [PATCH 10/37] tevent: add
tevent_threaded_schedule_immediate_destructor that just aborts
This will be active while the event is part of the ev->scheduled_immediates
list.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_threads.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index 3f91ab8bc2ab..efdac9856dd1 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -441,6 +441,14 @@ struct tevent_threaded_context *tevent_threaded_context_create(
#endif
}
+static int tevent_threaded_schedule_immediate_destructor(struct tevent_immediate *im)
+{
+ if (im->event_ctx != NULL) {
+ abort();
+ }
+ return 0;
+}
+
void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
struct tevent_immediate *im,
tevent_immediate_handler_t handler,
@@ -484,6 +492,14 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
.schedule_location = location,
};
+ /*
+ * Make sure the event won't be destroyed while
+ * it's part of the ev->scheduled_immediates list.
+ * _tevent_schedule_immediate() will reset the destructor
+ * in tevent_common_threaded_activate_immediate().
+ */
+ talloc_set_destructor(im, tevent_threaded_schedule_immediate_destructor);
+
ret = pthread_mutex_lock(&ev->scheduled_mutex);
if (ret != 0) {
abort();
--
2.17.1
From 9cd581d1fb45c2416cf0daa1ab81c2e95ee567be Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 17 Apr 2018 16:33:47 +0200
Subject: [PATCH 11/37] tevent: add tevent_common_check_double_free() helper
function
This will be used to generically support TALLOC_FREE() on
event which are currently running.
It aborts on every explicit talloc_free(), but ignores implicit
cleanup when the talloc parent is about to go.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent.c | 20 ++++++++++++++++++++
lib/tevent/tevent_internal.h | 2 ++
2 files changed, 22 insertions(+)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 501d548a9f09..d12ec10720e9 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -429,6 +429,26 @@ static int tevent_common_context_constructor(struct tevent_context *ev)
return 0;
}
+_PRIVATE_
+void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason)
+{
+ void *parent_ptr = talloc_parent(ptr);
+ size_t parent_blocks = talloc_total_blocks(parent_ptr);
+
+ if (parent_ptr != NULL && parent_blocks == 0) {
+ /*
+ * This is an implicit talloc free, as we still have a parent
+ * but it's already being destroyed. Note that
+ * talloc_total_blocks(ptr) also just returns 0 if a
+ * talloc_free(ptr) is still in progress of freeing all
+ * children.
+ */
+ return;
+ }
+
+ tevent_abort(NULL, reason);
+}
+
/*
create a event_context structure for a specific implemementation.
This must be the first events call, and all subsequent calls pass
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index cbe2e69548dc..4fd49f58ffb0 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -248,6 +248,8 @@ void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
void tevent_abort(struct tevent_context *ev, const char *reason);
+void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason);
+
struct tevent_context {
/* the specific events implementation */
const struct tevent_ops *ops;
--
2.17.1
From c125b3d2fd08a34508afb91a2c2a3ee8a4e8735f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 12:02:45 +0200
Subject: [PATCH 12/37] tevent: simplify
tevent_cleanup_pending_signal_handlers()
Calling tevent_signal_destructor() does the same as se->event_ctx is already
NULL.
This also makes sure we correctly cleanup the SA_SIGINFO array.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_signal.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 1283aab48211..6bb69d77d7a5 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -194,6 +194,7 @@ static int tevent_signal_destructor(struct tevent_signal *se)
DLIST_REMOVE(ev->signal_events, se);
}
+ se->additional_data = NULL;
talloc_free(sl);
if (sig_state->sig_handlers[se->signum] == NULL) {
@@ -464,18 +465,7 @@ int tevent_common_check_signal(struct tevent_context *ev)
void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se)
{
- struct tevent_common_signal_list *sl =
- talloc_get_type_abort(se->additional_data,
- struct tevent_common_signal_list);
-
- tevent_common_signal_list_destructor(sl);
-
- if (sig_state->sig_handlers[se->signum] == NULL) {
- if (sig_state->oldact[se->signum]) {
- sigaction(se->signum, sig_state->oldact[se->signum], NULL);
- talloc_free(sig_state->oldact[se->signum]);
- sig_state->oldact[se->signum] = NULL;
- }
- }
+ tevent_signal_destructor(se);
+ talloc_set_destructor(se, NULL);
return;
}
--
2.17.1
From 8ef043b2d2f8b0abd0ff68f9c54aa0570702f565 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 27 Mar 2018 14:30:20 +0200
Subject: [PATCH 13/37] tevent: use talloc_zero() in tevent_signal.c
This might not be strictly required, but it might
avoid problems in future...
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_signal.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 6bb69d77d7a5..73b8de798f69 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -255,10 +255,10 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
}
}
- se = talloc(mem_ctx?mem_ctx:ev, struct tevent_signal);
+ se = talloc_zero(mem_ctx?mem_ctx:ev, struct tevent_signal);
if (se == NULL) return NULL;
- sl = talloc(se, struct tevent_common_signal_list);
+ sl = talloc_zero(se, struct tevent_common_signal_list);
if (!sl) {
talloc_free(se);
return NULL;
@@ -303,7 +303,7 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
}
}
#endif
- sig_state->oldact[signum] = talloc(sig_state, struct sigaction);
+ sig_state->oldact[signum] = talloc_zero(sig_state, struct sigaction);
if (sig_state->oldact[signum] == NULL) {
talloc_free(se);
return NULL;
--
2.17.1
From 248f997b370408199c4e29ecfd1de7b7d67b837c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 17 Apr 2018 16:43:54 +0200
Subject: [PATCH 14/37] tevent: simplify tevent_signal_destructor()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_signal.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 73b8de798f69..ef2302433168 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -184,31 +184,22 @@ static int tevent_common_signal_list_destructor(struct tevent_common_signal_list
*/
static int tevent_signal_destructor(struct tevent_signal *se)
{
- struct tevent_common_signal_list *sl =
- talloc_get_type_abort(se->additional_data,
- struct tevent_common_signal_list);
+ TALLOC_FREE(se->additional_data);
- if (se->event_ctx) {
- struct tevent_context *ev = se->event_ctx;
-
- DLIST_REMOVE(ev->signal_events, se);
+ if (se->event_ctx != NULL) {
+ DLIST_REMOVE(se->event_ctx->signal_events, se);
}
- se->additional_data = NULL;
- talloc_free(sl);
-
if (sig_state->sig_handlers[se->signum] == NULL) {
/* restore old handler, if any */
if (sig_state->oldact[se->signum]) {
sigaction(se->signum, sig_state->oldact[se->signum], NULL);
- talloc_free(sig_state->oldact[se->signum]);
- sig_state->oldact[se->signum] = NULL;
+ TALLOC_FREE(sig_state->oldact[se->signum]);
}
#ifdef SA_SIGINFO
if (se->sa_flags & SA_SIGINFO) {
if (sig_state->sig_info[se->signum]) {
- talloc_free(sig_state->sig_info[se->signum]);
- sig_state->sig_info[se->signum] = NULL;
+ TALLOC_FREE(sig_state->sig_info[se->signum]);
}
}
#endif
--
2.17.1
From c15eaea332b64f6ea7433ac6f900974af90632c7 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 13:01:01 +0200
Subject: [PATCH 15/37] tevent: split out tevent_common_invoke_signal_handler()
As side effect this avoids tricks with tevent_se_exists_destructor() to
figure out if the event handler removed itself.
We'll remove _PRIVATE_ with the next release.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_internal.h | 5 ++
lib/tevent/tevent_signal.c | 101 ++++++++++++++++++++++-------------
2 files changed, 68 insertions(+), 38 deletions(-)
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 4fd49f58ffb0..48212949e161 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -216,6 +216,8 @@ struct tevent_immediate {
struct tevent_signal {
struct tevent_signal *prev, *next;
struct tevent_context *event_ctx;
+ bool busy;
+ bool destroyed;
int signum;
int sa_flags;
tevent_signal_handler_t handler;
@@ -378,6 +380,9 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
const char *location);
int tevent_common_check_signal(struct tevent_context *ev);
void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se);
+int tevent_common_invoke_signal_handler(struct tevent_signal *se,
+ int signum, int count, void *siginfo,
+ bool *removed);
bool tevent_standard_init(void);
bool tevent_poll_init(void);
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index ef2302433168..3ca03334c92f 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -184,6 +184,12 @@ static int tevent_common_signal_list_destructor(struct tevent_common_signal_list
*/
static int tevent_signal_destructor(struct tevent_signal *se)
{
+ if (se->destroyed) {
+ tevent_common_check_double_free(se, "tevent_signal double free");
+ goto done;
+ }
+ se->destroyed = true;
+
TALLOC_FREE(se->additional_data);
if (se->event_ctx != NULL) {
@@ -205,6 +211,11 @@ static int tevent_signal_destructor(struct tevent_signal *se)
#endif
}
+done:
+ if (se->busy) {
+ return -1;
+ }
+
return 0;
}
@@ -322,13 +333,43 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
return se;
}
-struct tevent_se_exists {
- struct tevent_se_exists **myself;
-};
-
-static int tevent_se_exists_destructor(struct tevent_se_exists *s)
+_PRIVATE_
+int tevent_common_invoke_signal_handler(struct tevent_signal *se,
+ int signum, int count, void *siginfo,
+ bool *removed)
{
- *s->myself = NULL;
+ bool remove = false;
+
+ if (removed != NULL) {
+ *removed = false;
+ }
+
+ if (se->event_ctx == NULL) {
+ return 0;
+ }
+
+ se->busy = true;
+ se->handler(se->event_ctx, se, signum, count, siginfo, se->private_data);
+ se->busy = false;
+
+#ifdef SA_RESETHAND
+ if (se->sa_flags & SA_RESETHAND) {
+ remove = true;
+ }
+#endif
+
+ if (se->destroyed) {
+ talloc_set_destructor(se, NULL);
+ remove = true;
+ }
+
+ if (remove) {
+ TALLOC_FREE(se);
+ if (removed != NULL) {
+ *removed = true;
+ }
+ }
+
return 0;
}
@@ -348,6 +389,7 @@ int tevent_common_check_signal(struct tevent_context *ev)
struct tevent_common_signal_list *sl, *next;
struct tevent_sigcounter counter = sig_state->signal_count[i];
uint32_t count = tevent_sig_count(counter);
+ int ret;
#ifdef SA_SIGINFO
/* Ensure we null out any stored siginfo_t entries
* after processing for debugging purposes. */
@@ -359,25 +401,9 @@ int tevent_common_check_signal(struct tevent_context *ev)
}
for (sl=sig_state->sig_handlers[i];sl;sl=next) {
struct tevent_signal *se = sl->se;
- struct tevent_se_exists *exists;
next = sl->next;
- /*
- * We have to be careful to not touch "se"
- * after it was deleted in its handler. Thus
- * we allocate a child whose destructor will
- * tell by nulling out itself that its parent
- * is gone.
- */
- exists = talloc(se, struct tevent_se_exists);
- if (exists == NULL) {
- continue;
- }
- exists->myself = &exists;
- talloc_set_destructor(
- exists, tevent_se_exists_destructor);
-
#ifdef SA_SIGINFO
if (se->sa_flags & SA_SIGINFO) {
uint32_t j;
@@ -391,29 +417,28 @@ int tevent_common_check_signal(struct tevent_context *ev)
* signals in the ringbuffer. */
uint32_t ofs = (counter.seen + j)
% TEVENT_SA_INFO_QUEUE_COUNT;
- se->handler(ev, se, i, 1,
- (void*)&sig_state->sig_info[i][ofs],
- se->private_data);
- if (!exists) {
+ bool removed = false;
+
+ ret = tevent_common_invoke_signal_handler(
+ se, i, 1,
+ (void*)&sig_state->sig_info[i][ofs],
+ &removed);
+ if (ret != 0) {
+ tevent_abort(ev, "tevent_common_invoke_signal_handler() failed");
+ }
+ if (removed) {
break;
}
}
-#ifdef SA_RESETHAND
- if (exists && (se->sa_flags & SA_RESETHAND)) {
- talloc_free(se);
- }
-#endif
- talloc_free(exists);
continue;
}
#endif
- se->handler(ev, se, i, count, NULL, se->private_data);
-#ifdef SA_RESETHAND
- if (exists && (se->sa_flags & SA_RESETHAND)) {
- talloc_free(se);
+
+ ret = tevent_common_invoke_signal_handler(se, i, count,
+ NULL, NULL);
+ if (ret != 0) {
+ tevent_abort(ev, "tevent_common_invoke_signal_handler() failed");
}
-#endif
- talloc_free(exists);
}
#ifdef SA_SIGINFO
--
2.17.1
From 2bf0006dc6d03c21dc74dfc1ac5583c7db8e442c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 13:08:42 +0200
Subject: [PATCH 16/37] tevent: split out tevent_common_invoke_timer_handler()
As side effect this avoids tricks with an extra
tevent_common_timed_deny_destructor().
We'll remove the _PRIVATE_ with the next release.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_internal.h | 5 ++
lib/tevent/tevent_timed.c | 112 +++++++++++++++++++++++------------
2 files changed, 79 insertions(+), 38 deletions(-)
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 48212949e161..bd1c2a0370a3 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -187,6 +187,8 @@ struct tevent_fd {
struct tevent_timer {
struct tevent_timer *prev, *next;
struct tevent_context *event_ctx;
+ bool busy;
+ bool destroyed;
struct timeval next_event;
tevent_timer_handler_t handler;
/* this is private for the specific handler */
@@ -355,6 +357,9 @@ struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev,
const char *handler_name,
const char *location);
struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
+int tevent_common_invoke_timer_handler(struct tevent_timer *te,
+ struct timeval current_time,
+ bool *removed);
void tevent_common_schedule_immediate(struct tevent_immediate *im,
struct tevent_context *ev,
diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c
index ae1eb98d8b2a..d460e7001dca 100644
--- a/lib/tevent/tevent_timed.c
+++ b/lib/tevent/tevent_timed.c
@@ -133,6 +133,12 @@ struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs)
*/
static int tevent_common_timed_destructor(struct tevent_timer *te)
{
+ if (te->destroyed) {
+ tevent_common_check_double_free(te, "tevent_timer double free");
+ goto done;
+ }
+ te->destroyed = true;
+
if (te->event_ctx == NULL) {
return 0;
}
@@ -146,12 +152,14 @@ static int tevent_common_timed_destructor(struct tevent_timer *te)
}
DLIST_REMOVE(te->event_ctx->timer_events, te);
- return 0;
-}
+ te->event_ctx = NULL;
-static int tevent_common_timed_deny_destructor(struct tevent_timer *te)
-{
- return -1;
+done:
+ if (te->busy) {
+ return -1;
+ }
+
+ return 0;
}
static void tevent_common_insert_timer(struct tevent_context *ev,
@@ -160,6 +168,11 @@ static void tevent_common_insert_timer(struct tevent_context *ev,
{
struct tevent_timer *prev_te = NULL;
+ if (te->destroyed) {
+ tevent_abort(ev, "tevent_timer use after free");
+ return;
+ }
+
/* keep the list ordered */
if (optimize_zero && tevent_timeval_is_zero(&te->next_event)) {
/*
@@ -303,6 +316,58 @@ void tevent_update_timer(struct tevent_timer *te, struct timeval next_event)
tevent_common_insert_timer(ev, te, false);
}
+_PRIVATE_
+int tevent_common_invoke_timer_handler(struct tevent_timer *te,
+ struct timeval current_time,
+ bool *removed)
+{
+ if (removed != NULL) {
+ *removed = false;
+ }
+
+ if (te->event_ctx == NULL) {
+ return 0;
+ }
+
+ /*
+ * We need to remove the timer from the list before calling the
+ * handler because in a semi-async inner event loop called from the
+ * handler we don't want to come across this event again -- vl
+ */
+ if (te->event_ctx->last_zero_timer == te) {
+ te->event_ctx->last_zero_timer = DLIST_PREV(te);
+ }
+ DLIST_REMOVE(te->event_ctx->timer_events, te);
+
+ tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE,
+ "Running timer event %p \"%s\"\n",
+ te, te->handler_name);
+
+ /*
+ * If the timed event was registered for a zero current_time,
+ * then we pass a zero timeval here too! To avoid the
+ * overhead of gettimeofday() calls.
+ *
+ * otherwise we pass the current time
+ */
+ te->busy = true;
+ te->handler(te->event_ctx, te, current_time, te->private_data);
+ te->busy = false;
+
+ tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE,
+ "Ending timer event %p \"%s\"\n",
+ te, te->handler_name);
+
+ te->event_ctx = NULL;
+ talloc_set_destructor(te, NULL);
+ TALLOC_FREE(te);
+
+ if (removed != NULL) {
+ *removed = true;
+ }
+
+ return 0;
+}
/*
do a single event loop using the events defined in ev
@@ -313,6 +378,7 @@ struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev)
{
struct timeval current_time = tevent_timeval_zero();
struct tevent_timer *te = ev->timer_events;
+ int ret;
if (!te) {
/* have a default tick time of 30 seconds. This guarantees
@@ -344,40 +410,10 @@ struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev)
/*
* ok, we have a timed event that we'll process ...
*/
-
- /* deny the handler to free the event */
- talloc_set_destructor(te, tevent_common_timed_deny_destructor);
-
- /* We need to remove the timer from the list before calling the
- * handler because in a semi-async inner event loop called from the
- * handler we don't want to come across this event again -- vl */
- if (ev->last_zero_timer == te) {
- ev->last_zero_timer = DLIST_PREV(te);
+ ret = tevent_common_invoke_timer_handler(te, current_time, NULL);
+ if (ret != 0) {
+ tevent_abort(ev, "tevent_common_invoke_timer_handler() failed");
}
- DLIST_REMOVE(ev->timer_events, te);
-
- tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE,
- "Running timer event %p \"%s\"\n",
- te, te->handler_name);
-
- /*
- * If the timed event was registered for a zero current_time,
- * then we pass a zero timeval here too! To avoid the
- * overhead of gettimeofday() calls.
- *
- * otherwise we pass the current time
- */
- te->handler(ev, te, current_time, te->private_data);
-
- /* The destructor isn't necessary anymore, we've already removed the
- * event from the list. */
- talloc_set_destructor(te, NULL);
-
- tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE,
- "Ending timer event %p \"%s\"\n",
- te, te->handler_name);
-
- talloc_free(te);
return tevent_timeval_zero();
}
--
2.17.1
From 154521178eecafefa8a20d2161752891923461eb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 13:08:42 +0200
Subject: [PATCH 17/37] tevent: split out
tevent_common_invoke_immediate_handler()
We'll remove _PRIVATE_ with the next release.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_immediate.c | 88 ++++++++++++++++++++++++++---------
lib/tevent/tevent_internal.h | 4 ++
lib/tevent/tevent_threads.c | 6 +++
3 files changed, 75 insertions(+), 23 deletions(-)
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index c640a565b082..abcaca41fb80 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -31,6 +31,12 @@
static void tevent_common_immediate_cancel(struct tevent_immediate *im)
{
const char *create_location = im->create_location;
+ bool busy = im->busy;
+
+ if (im->destroyed) {
+ tevent_abort(im->event_ctx, "tevent_immediate use after free");
+ return;
+ }
if (!im->event_ctx) {
return;
@@ -51,9 +57,12 @@ static void tevent_common_immediate_cancel(struct tevent_immediate *im)
*im = (struct tevent_immediate) {
.create_location = create_location,
+ .busy = busy,
};
- talloc_set_destructor(im, NULL);
+ if (!busy) {
+ talloc_set_destructor(im, NULL);
+ }
}
/*
@@ -61,7 +70,21 @@ static void tevent_common_immediate_cancel(struct tevent_immediate *im)
*/
static int tevent_common_immediate_destructor(struct tevent_immediate *im)
{
+ if (im->destroyed) {
+ tevent_common_check_double_free(im,
+ "tevent_immediate double free");
+ goto done;
+ }
+
tevent_common_immediate_cancel(im);
+
+ im->destroyed = true;
+
+done:
+ if (im->busy) {
+ return -1;
+ }
+
return 0;
}
@@ -76,6 +99,7 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
const char *location)
{
const char *create_location = im->create_location;
+ bool busy = im->busy;
tevent_common_immediate_cancel(im);
@@ -90,6 +114,7 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
.handler_name = handler_name,
.create_location = create_location,
.schedule_location = location,
+ .busy = busy,
};
DLIST_ADD_END(ev->immediate_events, im);
@@ -100,18 +125,15 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
handler_name, im);
}
-/*
- trigger the first immediate event and return true
- if no event was triggered return false
-*/
-bool tevent_common_loop_immediate(struct tevent_context *ev)
+_PRIVATE_
+int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
+ bool *removed)
{
- struct tevent_immediate *im = ev->immediate_events;
- tevent_immediate_handler_t handler;
- void *private_data;
+ struct tevent_context *ev = im->event_ctx;
+ struct tevent_immediate cur = *im;
- if (!im) {
- return false;
+ if (removed != NULL) {
+ *removed = false;
}
tevent_debug(ev, TEVENT_DEBUG_TRACE,
@@ -122,21 +144,41 @@ bool tevent_common_loop_immediate(struct tevent_context *ev)
* remember the handler and then clear the event
* the handler might reschedule the event
*/
- handler = im->handler;
- private_data = im->private_data;
- DLIST_REMOVE(im->event_ctx->immediate_events, im);
- im->event_ctx = NULL;
- im->handler = NULL;
- im->private_data = NULL;
- im->handler_name = NULL;
- im->schedule_location = NULL;
- im->cancel_fn = NULL;
- im->additional_data = NULL;
+ im->busy = true;
+ im->handler_name = NULL;
+ tevent_common_immediate_cancel(im);
+ cur.handler(ev, im, cur.private_data);
+ im->busy = false;
+
+ if (im->destroyed) {
+ talloc_set_destructor(im, NULL);
+ TALLOC_FREE(im);
+ if (removed != NULL) {
+ *removed = true;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ trigger the first immediate event and return true
+ if no event was triggered return false
+*/
+bool tevent_common_loop_immediate(struct tevent_context *ev)
+{
+ struct tevent_immediate *im = ev->immediate_events;
+ int ret;
- talloc_set_destructor(im, NULL);
+ if (!im) {
+ return false;
+ }
- handler(ev, im, private_data);
+ ret = tevent_common_invoke_immediate_handler(im, NULL);
+ if (ret != 0) {
+ tevent_abort(ev, "tevent_common_invoke_immediate_handler() failed");
+ }
return true;
}
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index bd1c2a0370a3..a590a5bb3b75 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -203,6 +203,8 @@ struct tevent_timer {
struct tevent_immediate {
struct tevent_immediate *prev, *next;
struct tevent_context *event_ctx;
+ bool busy;
+ bool destroyed;
tevent_immediate_handler_t handler;
/* this is private for the specific handler */
void *private_data;
@@ -367,6 +369,8 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
void *private_data,
const char *handler_name,
const char *location);
+int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
+ bool *removed);
bool tevent_common_loop_immediate(struct tevent_context *ev);
void tevent_common_threaded_activate_immediate(struct tevent_context *ev);
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index efdac9856dd1..9410765266e4 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -482,6 +482,12 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
if ((im->event_ctx != NULL) || (handler == NULL)) {
abort();
}
+ if (im->destroyed) {
+ abort();
+ }
+ if (im->busy) {
+ abort();
+ }
*im = (struct tevent_immediate) {
.event_ctx = ev,
--
2.17.1
From daa635bd1f60a92e338333183ca1d8970f1884ea Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 14:45:33 +0200
Subject: [PATCH 18/37] tevent: split out tevent_common_invoke_fd_handler()
We'll remove _PRIVATE_ with the next release.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent_epoll.c | 3 +--
lib/tevent/tevent_fd.c | 40 ++++++++++++++++++++++++++++++++++++
lib/tevent/tevent_internal.h | 4 ++++
lib/tevent/tevent_poll.c | 3 +--
4 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 4147c67af2a0..5f7ef5d83d17 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -725,8 +725,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
*/
flags &= fde->flags;
if (flags) {
- fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
- break;
+ return tevent_common_invoke_fd_handler(fde, flags, NULL);
}
}
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
index f33ae841b396..f8234641ad3d 100644
--- a/lib/tevent/tevent_fd.c
+++ b/lib/tevent/tevent_fd.c
@@ -30,6 +30,12 @@
int tevent_common_fd_destructor(struct tevent_fd *fde)
{
+ if (fde->destroyed) {
+ tevent_common_check_double_free(fde, "tevent_fd double free");
+ goto done;
+ }
+ fde->destroyed = true;
+
if (fde->event_ctx) {
DLIST_REMOVE(fde->event_ctx->fd_events, fde);
}
@@ -37,6 +43,13 @@ int tevent_common_fd_destructor(struct tevent_fd *fde)
if (fde->close_fn) {
fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data);
fde->fd = -1;
+ fde->close_fn = NULL;
+ }
+
+ fde->event_ctx = NULL;
+done:
+ if (fde->busy) {
+ return -1;
}
return 0;
@@ -92,3 +105,30 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
{
fde->close_fn = close_fn;
}
+
+_PRIVATE_
+int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
+ bool *removed)
+{
+ if (removed != NULL) {
+ *removed = false;
+ }
+
+ if (fde->event_ctx == NULL) {
+ return 0;
+ }
+
+ fde->busy = true;
+ fde->handler(fde->event_ctx, fde, flags, fde->private_data);
+ fde->busy = false;
+
+ if (fde->destroyed) {
+ talloc_set_destructor(fde, NULL);
+ TALLOC_FREE(fde);
+ if (removed != NULL) {
+ *removed = true;
+ }
+ }
+
+ return 0;
+}
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index a590a5bb3b75..ed39aa2bebe4 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -170,6 +170,8 @@ struct tevent_req {
struct tevent_fd {
struct tevent_fd *prev, *next;
struct tevent_context *event_ctx;
+ bool busy;
+ bool destroyed;
int fd;
uint16_t flags; /* see TEVENT_FD_* flags */
tevent_fd_handler_t handler;
@@ -343,6 +345,8 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
tevent_fd_close_fn_t close_fn);
uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
+int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
+ bool *removed);
struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index f1d52533f5de..a1f7ef22206d 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -603,8 +603,7 @@ static int poll_event_loop_poll(struct tevent_context *ev,
flags &= fde->flags;
if (flags != 0) {
DLIST_DEMOTE(ev->fd_events, fde);
- fde->handler(ev, fde, flags, fde->private_data);
- return 0;
+ return tevent_common_invoke_fd_handler(fde, flags, NULL);
}
}
--
2.17.1
From c6cc0cbc10461cf43eaccfcf0120bdf8962a0822 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 May 2018 15:43:12 +0200
Subject: [PATCH 19/37] tevent: make use of #include "system/threads.h"
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/testsuite.c | 2 +-
lib/tevent/tevent_threads.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index 08aa7588acee..dba8f5895f76 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -32,7 +32,7 @@
#include "torture/torture.h"
#include "torture/local/proto.h"
#ifdef HAVE_PTHREAD
-#include <pthread.h>
+#include "system/threads.h"
#include <assert.h>
#endif
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index 9410765266e4..5d4e0c426769 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -28,8 +28,8 @@
#include "tevent_internal.h"
#include "tevent_util.h"
-#if defined(HAVE_PTHREAD)
-#include <pthread.h>
+#ifdef HAVE_PTHREAD
+#include "system/threads.h"
struct tevent_immediate_list {
struct tevent_immediate_list *next, *prev;
--
2.17.1
From f5a35f3fdb0ff17ca6395bfc9207bceeaf65af69 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jul 2014 16:51:38 +0200
Subject: [PATCH 20/37] tevent: add tevent_context_wrapper_create()
infrastructure
This allows to specify wrapper tevent_contexts, which adds the ability
to run functions before and after the event handler functions.
This can be used to implement impersonation hooks
or advanced debugging/profiling hooks.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/tevent.c | 18 ++
lib/tevent/tevent.h | 213 +++++++++++++++++
lib/tevent/tevent_debug.c | 16 ++
lib/tevent/tevent_fd.c | 25 +-
lib/tevent/tevent_immediate.c | 22 +-
lib/tevent/tevent_internal.h | 28 +++
lib/tevent/tevent_signal.c | 28 ++-
lib/tevent/tevent_threads.c | 40 ++--
lib/tevent/tevent_timed.c | 27 ++-
lib/tevent/tevent_wrapper.c | 418 ++++++++++++++++++++++++++++++++++
lib/tevent/wscript | 2 +-
11 files changed, 819 insertions(+), 18 deletions(-)
create mode 100644 lib/tevent/tevent_wrapper.c
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index d12ec10720e9..802dce43552b 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -298,6 +298,7 @@ int tevent_common_context_destructor(struct tevent_context *ev)
struct tevent_timer *te, *tn;
struct tevent_immediate *ie, *in;
struct tevent_signal *se, *sn;
+ struct tevent_wrapper_glue *gl, *gn;
#ifdef HAVE_PTHREAD
int ret;
@@ -345,6 +346,13 @@ int tevent_common_context_destructor(struct tevent_context *ev)
}
#endif
+ for (gl = ev->wrapper.list; gl; gl = gn) {
+ gn = gl->next;
+
+ gl->main_ev = NULL;
+ DLIST_REMOVE(ev->wrapper.list, gl);
+ }
+
tevent_common_wakeup_fini(ev);
for (fd = ev->fd_events; fd; fd = fn) {
@@ -677,6 +685,16 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
void tevent_loop_allow_nesting(struct tevent_context *ev)
{
+ if (ev->wrapper.glue != NULL) {
+ tevent_abort(ev, "tevent_loop_allow_nesting() on wrapper");
+ return;
+ }
+
+ if (ev->wrapper.list != NULL) {
+ tevent_abort(ev, "tevent_loop_allow_nesting() with wrapper");
+ return;
+ }
+
ev->nesting.allowed = true;
}
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 0e2e806ee5c4..2fa7221c4a4a 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -1967,6 +1967,219 @@ bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
/* @} */
+/**
+ * @defgroup tevent_wrapper_ops The tevent wrapper operation functions
+ * @ingroup tevent
+ *
+ * The following structure and registration functions are exclusively
+ * needed for people writing wrapper functions for event handlers
+ * e.g. wrappers can be used for debugging/profiling or impersonation.
+ *
+ * There is nothing useful for normal tevent user in here.
+ * @{
+ */
+
+struct tevent_wrapper_ops {
+ const char *name;
+
+ bool (*before_use)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ const char *location);
+ void (*after_use)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ const char *location);
+
+ void (*before_fd_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location);
+ void (*after_fd_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location);
+
+ void (*before_timer_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location);
+ void (*after_timer_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location);
+
+ void (*before_immediate_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location);
+ void (*after_immediate_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location);
+
+ void (*before_signal_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location);
+ void (*after_signal_handler)(struct tevent_context *wrap_ev,
+ void *private_state,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location);
+};
+
+#ifdef DOXYGEN
+/**
+ * @brief Create a wrapper tevent_context.
+ *
+ * @param[in] main_ev The main event context to work on.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] ops The tevent_wrapper_ops function table.
+ *
+ * @param[out] private_state The private state use by the wrapper functions.
+ *
+ * @param[in] private_type The talloc type of the private_state.
+ *
+ * @return The wrapper event context, NULL on error.
+ *
+ * @note Available as of tevent 0.9.37
+ */
+struct tevent_context *tevent_context_wrapper_create(struct tevent_context *main_ev,
+ TALLOC_CTX *mem_ctx,
+ const struct tevent_wrapper_ops *ops,
+ void **private_state,
+ const char *private_type);
+#else
+struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev,
+ TALLOC_CTX *mem_ctx,
+ const struct tevent_wrapper_ops *ops,
+ void *pstate,
+ size_t psize,
+ const char *type,
+ const char *location);
+#define tevent_context_wrapper_create(main_ev, mem_ctx, ops, state, type) \
+ _tevent_context_wrapper_create(main_ev, mem_ctx, ops, \
+ state, sizeof(type), #type, __location__)
+#endif
+
+/**
+ * @brief Check if the event context is a wrapper event context.
+ *
+ * @param[in] ev The event context to work on.
+ *
+ * @return Is a wrapper (true), otherwise (false).
+ *
+ * @see tevent_context_wrapper_create()
+ *
+ * @note Available as of tevent 0.9.37
+ */
+bool tevent_context_is_wrapper(struct tevent_context *ev);
+
+#ifdef DOXYGEN
+/**
+ * @brief Prepare the environment of a (wrapper) event context.
+ *
+ * A caller might call this before passing a wrapper event context
+ * to a tevent_req based *_send() function.
+ *
+ * The wrapper event context might do something like impersonation.
+ *
+ * @param[in] ev The event context to work on.
+ *
+ * @return Success (true) or failure (false).
+ *
+ * @note This is only needed if wrapper event contexts are in use.
+ *
+ * @see tevent_context_after_use
+ *
+ * @note Available as of tevent 0.9.37
+ */
+bool tevent_context_before_use(struct tevent_context *ev);
+#else
+bool _tevent_context_before_use(struct tevent_context *ev,
+ const char *location);
+#define tevent_context_before_use(ev) \
+ _tevent_context_before_use(ev, __location__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Release the environment of a (wrapper) event context.
+ *
+ * A caller might call this after receiving the result from
+ * a *_recv function of a tevent_req based function pair.
+ *
+ * The wrapper event context might undo something like impersonation.
+ *
+ * @param[in] ev The event context to work on.
+ *
+ * @note This is only needed if wrapper event contexts are in use.
+ *
+ * @see tevent_context_before_use
+ *
+ * @note Available as of tevent 0.9.37
+ */
+void tevent_context_after_use(struct tevent_context *ev);
+#else
+void _tevent_context_after_use(struct tevent_context *ev,
+ const char *location);
+#define tevent_context_after_use(ev) \
+ _tevent_context_after_use(ev, __location__)
+#endif
+
+/**
+ * @brief Check is the two context pointers belong to the same low level loop
+ *
+ * With the introduction of wrapper contexts it's not trivial
+ * to check if two context pointers belong to the same low level
+ * event loop. Some code may need to know this in order
+ * to make some caching decisions.
+ *
+ * @param[in] ev1 The first event context.
+ * @param[in] ev2 The second event context.
+ *
+ * @return true if both contexts belong to the same (still existing) context
+ * loop, false otherwise.
+ *
+ * @see tevent_context_wrapper_create
+ *
+ * @note Available as of tevent 0.9.37
+ */
+bool tevent_context_same_loop(struct tevent_context *ev1,
+ struct tevent_context *ev2);
+
+/* @} */
+
/**
* @defgroup tevent_compat The tevent compatibility functions
* @ingroup tevent
diff --git a/lib/tevent/tevent_debug.c b/lib/tevent/tevent_debug.c
index 31da7b968366..0a57639076e2 100644
--- a/lib/tevent/tevent_debug.c
+++ b/lib/tevent/tevent_debug.c
@@ -41,6 +41,13 @@ int tevent_set_debug(struct tevent_context *ev,
va_list ap) PRINTF_ATTRIBUTE(3,0),
void *context)
{
+ if (ev->wrapper.glue != NULL) {
+ ev = tevent_wrapper_main_ev(ev);
+ tevent_abort(ev, "tevent_set_debug() on wrapper");
+ errno = EINVAL;
+ return -1;
+ }
+
ev->debug_ops.debug = debug;
ev->debug_ops.context = context;
return 0;
@@ -86,6 +93,9 @@ void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
if (!ev) {
return;
}
+ if (ev->wrapper.glue != NULL) {
+ ev = tevent_wrapper_main_ev(ev);
+ }
if (ev->debug_ops.debug == NULL) {
return;
}
@@ -98,6 +108,12 @@ void tevent_set_trace_callback(struct tevent_context *ev,
tevent_trace_callback_t cb,
void *private_data)
{
+ if (ev->wrapper.glue != NULL) {
+ ev = tevent_wrapper_main_ev(ev);
+ tevent_abort(ev, "tevent_set_trace_callback() on wrapper");
+ return;
+ }
+
ev->tracing.callback = cb;
ev->tracing.private_data = private_data;
}
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
index f8234641ad3d..38d0eaeba73a 100644
--- a/lib/tevent/tevent_fd.c
+++ b/lib/tevent/tevent_fd.c
@@ -110,6 +110,8 @@ _PRIVATE_
int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
bool *removed)
{
+ struct tevent_context *handler_ev = fde->event_ctx;
+
if (removed != NULL) {
*removed = false;
}
@@ -119,7 +121,28 @@ int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
}
fde->busy = true;
- fde->handler(fde->event_ctx, fde, flags, fde->private_data);
+ if (fde->wrapper != NULL) {
+ fde->wrapper->ops->before_fd_handler(
+ fde->wrapper->wrap_ev,
+ fde->wrapper->private_state,
+ fde->wrapper->main_ev,
+ fde,
+ flags,
+ fde->handler_name,
+ fde->location);
+ handler_ev = fde->wrapper->wrap_ev;
+ }
+ fde->handler(handler_ev, fde, flags, fde->private_data);
+ if (fde->wrapper != NULL) {
+ fde->wrapper->ops->after_fd_handler(
+ fde->wrapper->wrap_ev,
+ fde->wrapper->private_state,
+ fde->wrapper->main_ev,
+ fde,
+ flags,
+ fde->handler_name,
+ fde->location);
+ }
fde->busy = false;
if (fde->destroyed) {
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index abcaca41fb80..ee4d8fa6e2a6 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -129,6 +129,7 @@ _PRIVATE_
int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
bool *removed)
{
+ struct tevent_context *handler_ev = im->event_ctx;
struct tevent_context *ev = im->event_ctx;
struct tevent_immediate cur = *im;
@@ -148,7 +149,26 @@ int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
im->busy = true;
im->handler_name = NULL;
tevent_common_immediate_cancel(im);
- cur.handler(ev, im, cur.private_data);
+ if (cur.wrapper != NULL) {
+ cur.wrapper->ops->before_immediate_handler(
+ cur.wrapper->wrap_ev,
+ cur.wrapper->private_state,
+ cur.wrapper->main_ev,
+ im,
+ cur.handler_name,
+ cur.schedule_location);
+ handler_ev = cur.wrapper->wrap_ev;
+ }
+ cur.handler(handler_ev, im, cur.private_data);
+ if (cur.wrapper != NULL) {
+ cur.wrapper->ops->after_immediate_handler(
+ cur.wrapper->wrap_ev,
+ cur.wrapper->private_state,
+ cur.wrapper->main_ev,
+ im,
+ cur.handler_name,
+ cur.schedule_location);
+ }
im->busy = false;
if (im->destroyed) {
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index ed39aa2bebe4..e90dd5ef8268 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -170,6 +170,7 @@ struct tevent_req {
struct tevent_fd {
struct tevent_fd *prev, *next;
struct tevent_context *event_ctx;
+ struct tevent_wrapper_glue *wrapper;
bool busy;
bool destroyed;
int fd;
@@ -189,6 +190,7 @@ struct tevent_fd {
struct tevent_timer {
struct tevent_timer *prev, *next;
struct tevent_context *event_ctx;
+ struct tevent_wrapper_glue *wrapper;
bool busy;
bool destroyed;
struct timeval next_event;
@@ -205,6 +207,7 @@ struct tevent_timer {
struct tevent_immediate {
struct tevent_immediate *prev, *next;
struct tevent_context *event_ctx;
+ struct tevent_wrapper_glue *wrapper;
bool busy;
bool destroyed;
tevent_immediate_handler_t handler;
@@ -222,6 +225,7 @@ struct tevent_immediate {
struct tevent_signal {
struct tevent_signal *prev, *next;
struct tevent_context *event_ctx;
+ struct tevent_wrapper_glue *wrapper;
bool busy;
bool destroyed;
int signum;
@@ -314,6 +318,18 @@ struct tevent_context {
void *private_data;
} tracing;
+ struct {
+ /*
+ * This is used on the main event context
+ */
+ struct tevent_wrapper_glue *list;
+
+ /*
+ * This is used on the wrapper event context
+ */
+ struct tevent_wrapper_glue *glue;
+ } wrapper;
+
/*
* an optimization pointer into timer_events
* used by used by common code via
@@ -397,6 +413,18 @@ int tevent_common_invoke_signal_handler(struct tevent_signal *se,
int signum, int count, void *siginfo,
bool *removed);
+struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev);
+
+struct tevent_wrapper_ops;
+
+struct tevent_wrapper_glue {
+ struct tevent_wrapper_glue *prev, *next;
+ struct tevent_context *wrap_ev;
+ struct tevent_context *main_ev;
+ const struct tevent_wrapper_ops *ops;
+ void *private_state;
+};
+
bool tevent_standard_init(void);
bool tevent_poll_init(void);
void tevent_poll_event_add_fd_internal(struct tevent_context *ev,
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index 3ca03334c92f..e0665cbafee6 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -338,6 +338,7 @@ int tevent_common_invoke_signal_handler(struct tevent_signal *se,
int signum, int count, void *siginfo,
bool *removed)
{
+ struct tevent_context *handler_ev = se->event_ctx;
bool remove = false;
if (removed != NULL) {
@@ -349,7 +350,32 @@ int tevent_common_invoke_signal_handler(struct tevent_signal *se,
}
se->busy = true;
- se->handler(se->event_ctx, se, signum, count, siginfo, se->private_data);
+ if (se->wrapper != NULL) {
+ se->wrapper->ops->before_signal_handler(
+ se->wrapper->wrap_ev,
+ se->wrapper->private_state,
+ se->wrapper->main_ev,
+ se,
+ signum,
+ count,
+ siginfo,
+ se->handler_name,
+ se->location);
+ handler_ev = se->wrapper->wrap_ev;
+ }
+ se->handler(handler_ev, se, signum, count, siginfo, se->private_data);
+ if (se->wrapper != NULL) {
+ se->wrapper->ops->after_signal_handler(
+ se->wrapper->wrap_ev,
+ se->wrapper->private_state,
+ se->wrapper->main_ev,
+ se,
+ signum,
+ count,
+ siginfo,
+ se->handler_name,
+ se->location);
+ }
se->busy = false;
#ifdef SA_RESETHAND
diff --git a/lib/tevent/tevent_threads.c b/lib/tevent/tevent_threads.c
index 5d4e0c426769..85a6cbf55e33 100644
--- a/lib/tevent/tevent_threads.c
+++ b/lib/tevent/tevent_threads.c
@@ -217,6 +217,18 @@ struct tevent_thread_proxy *tevent_thread_proxy_create(
int pipefds[2];
struct tevent_thread_proxy *tp;
+ if (dest_ev_ctx->wrapper.glue != NULL) {
+ /*
+ * stacking of wrappers is not supported
+ */
+ tevent_debug(dest_ev_ctx->wrapper.glue->main_ev,
+ TEVENT_DEBUG_FATAL,
+ "%s() not allowed on a wrapper context\n",
+ __func__);
+ errno = EINVAL;
+ return NULL;
+ }
+
tp = talloc_zero(dest_ev_ctx, struct tevent_thread_proxy);
if (tp == NULL) {
return NULL;
@@ -375,10 +387,11 @@ void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp,
static int tevent_threaded_context_destructor(
struct tevent_threaded_context *tctx)
{
+ struct tevent_context *main_ev = tevent_wrapper_main_ev(tctx->event_ctx);
int ret;
- if (tctx->event_ctx != NULL) {
- DLIST_REMOVE(tctx->event_ctx->threaded_contexts, tctx);
+ if (main_ev != NULL) {
+ DLIST_REMOVE(main_ev->threaded_contexts, tctx);
}
/*
@@ -410,10 +423,11 @@ struct tevent_threaded_context *tevent_threaded_context_create(
TALLOC_CTX *mem_ctx, struct tevent_context *ev)
{
#ifdef HAVE_PTHREAD
+ struct tevent_context *main_ev = tevent_wrapper_main_ev(ev);
struct tevent_threaded_context *tctx;
int ret;
- ret = tevent_common_wakeup_init(ev);
+ ret = tevent_common_wakeup_init(main_ev);
if (ret != 0) {
errno = ret;
return NULL;
@@ -431,7 +445,7 @@ struct tevent_threaded_context *tevent_threaded_context_create(
return NULL;
}
- DLIST_ADD(ev->threaded_contexts, tctx);
+ DLIST_ADD(main_ev->threaded_contexts, tctx);
talloc_set_destructor(tctx, tevent_threaded_context_destructor);
return tctx;
@@ -458,7 +472,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
{
#ifdef HAVE_PTHREAD
const char *create_location = im->create_location;
- struct tevent_context *ev;
+ struct tevent_context *main_ev = NULL;
int ret, wakeup_fd;
ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
@@ -466,9 +480,7 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
abort();
}
- ev = tctx->event_ctx;
-
- if (ev == NULL) {
+ if (tctx->event_ctx == NULL) {
/*
* Our event context is already gone.
*/
@@ -489,8 +501,10 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
abort();
}
+ main_ev = tevent_wrapper_main_ev(tctx->event_ctx);
+
*im = (struct tevent_immediate) {
- .event_ctx = ev,
+ .event_ctx = tctx->event_ctx,
.handler = handler,
.private_data = private_data,
.handler_name = handler_name,
@@ -506,15 +520,15 @@ void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx,
*/
talloc_set_destructor(im, tevent_threaded_schedule_immediate_destructor);
- ret = pthread_mutex_lock(&ev->scheduled_mutex);
+ ret = pthread_mutex_lock(&main_ev->scheduled_mutex);
if (ret != 0) {
abort();
}
- DLIST_ADD_END(ev->scheduled_immediates, im);
- wakeup_fd = ev->wakeup_fd;
+ DLIST_ADD_END(main_ev->scheduled_immediates, im);
+ wakeup_fd = main_ev->wakeup_fd;
- ret = pthread_mutex_unlock(&ev->scheduled_mutex);
+ ret = pthread_mutex_unlock(&main_ev->scheduled_mutex);
if (ret != 0) {
abort();
}
diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c
index d460e7001dca..5ede71696af4 100644
--- a/lib/tevent/tevent_timed.c
+++ b/lib/tevent/tevent_timed.c
@@ -321,6 +321,8 @@ int tevent_common_invoke_timer_handler(struct tevent_timer *te,
struct timeval current_time,
bool *removed)
{
+ struct tevent_context *handler_ev = te->event_ctx;
+
if (removed != NULL) {
*removed = false;
}
@@ -351,7 +353,30 @@ int tevent_common_invoke_timer_handler(struct tevent_timer *te,
* otherwise we pass the current time
*/
te->busy = true;
- te->handler(te->event_ctx, te, current_time, te->private_data);
+ if (te->wrapper != NULL) {
+ te->wrapper->ops->before_timer_handler(
+ te->wrapper->wrap_ev,
+ te->wrapper->private_state,
+ te->wrapper->main_ev,
+ te,
+ te->next_event,
+ current_time,
+ te->handler_name,
+ te->location);
+ handler_ev = te->wrapper->wrap_ev;
+ }
+ te->handler(handler_ev, te, current_time, te->private_data);
+ if (te->wrapper != NULL) {
+ te->wrapper->ops->after_timer_handler(
+ te->wrapper->wrap_ev,
+ te->wrapper->private_state,
+ te->wrapper->main_ev,
+ te,
+ te->next_event,
+ current_time,
+ te->handler_name,
+ te->location);
+ }
te->busy = false;
tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE,
diff --git a/lib/tevent/tevent_wrapper.c b/lib/tevent/tevent_wrapper.c
new file mode 100644
index 000000000000..8305a50dfca5
--- /dev/null
+++ b/lib/tevent/tevent_wrapper.c
@@ -0,0 +1,418 @@
+/*
+ Infrastructure for event context wrappers
+
+ Copyright (C) Stefan Metzmacher 2014
+
+ ** NOTE! The following LGPL license applies to the tevent
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#ifdef HAVE_PTHREAD
+#include "system/threads.h"
+#endif
+#include "tevent.h"
+#include "tevent_internal.h"
+#include "tevent_util.h"
+
+static int tevent_wrapper_glue_context_init(struct tevent_context *ev)
+{
+ return 0;
+}
+
+static struct tevent_fd *tevent_wrapper_glue_add_fd(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int fd, uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
+{
+ struct tevent_wrapper_glue *glue = ev->wrapper.glue;
+ struct tevent_fd *fde = NULL;
+
+ if (glue->main_ev == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ fde = _tevent_add_fd(glue->main_ev, mem_ctx, fd, flags,
+ handler, private_data,
+ handler_name, location);
+ if (fde == NULL) {
+ return NULL;
+ }
+
+ fde->wrapper = glue;
+
+ return fde;
+}
+
+static struct tevent_timer *tevent_wrapper_glue_add_timer(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ struct timeval next_event,
+ tevent_timer_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
+{
+ struct tevent_wrapper_glue *glue = ev->wrapper.glue;
+ struct tevent_timer *te = NULL;
+
+ if (glue->main_ev == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ te = _tevent_add_timer(glue->main_ev, mem_ctx, next_event,
+ handler, private_data,
+ handler_name, location);
+ if (te == NULL) {
+ return NULL;
+ }
+
+ te->wrapper = glue;
+
+ return te;
+}
+
+static void tevent_wrapper_glue_schedule_immediate(struct tevent_immediate *im,
+ struct tevent_context *ev,
+ tevent_immediate_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
+{
+ struct tevent_wrapper_glue *glue = ev->wrapper.glue;
+
+ if (glue->main_ev == NULL) {
+ tevent_abort(ev, location);
+ errno = EINVAL;
+ return;
+ }
+
+ _tevent_schedule_immediate(im, glue->main_ev,
+ handler, private_data,
+ handler_name, location);
+
+ im->wrapper = glue;
+
+ return;
+}
+
+static struct tevent_signal *tevent_wrapper_glue_add_signal(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int signum, int sa_flags,
+ tevent_signal_handler_t handler,
+ void *private_data,
+ const char *handler_name,
+ const char *location)
+{
+ struct tevent_wrapper_glue *glue = ev->wrapper.glue;
+ struct tevent_signal *se = NULL;
+
+ if (glue->main_ev == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ se = _tevent_add_signal(glue->main_ev, mem_ctx,
+ signum, sa_flags,
+ handler, private_data,
+ handler_name, location);
+ if (se == NULL) {
+ return NULL;
+ }
+
+ se->wrapper = glue;
+
+ return se;
+}
+
+static int tevent_wrapper_glue_loop_once(struct tevent_context *ev, const char *location)
+{
+ tevent_abort(ev, "tevent_wrapper_glue_loop_once() called");
+ errno = ENOSYS;
+ return -1;
+}
+
+static int tevent_wrapper_glue_loop_wait(struct tevent_context *ev, const char *location)
+{
+ tevent_abort(ev, "tevent_wrapper_glue_loop_wait() called");
+ errno = ENOSYS;
+ return -1;
+}
+
+static const struct tevent_ops tevent_wrapper_glue_ops = {
+ .context_init = tevent_wrapper_glue_context_init,
+ .add_fd = tevent_wrapper_glue_add_fd,
+ .set_fd_close_fn = tevent_common_fd_set_close_fn,
+ .get_fd_flags = tevent_common_fd_get_flags,
+ .set_fd_flags = tevent_common_fd_set_flags,
+ .add_timer = tevent_wrapper_glue_add_timer,
+ .schedule_immediate = tevent_wrapper_glue_schedule_immediate,
+ .add_signal = tevent_wrapper_glue_add_signal,
+ .loop_once = tevent_wrapper_glue_loop_once,
+ .loop_wait = tevent_wrapper_glue_loop_wait,
+};
+
+static int tevent_wrapper_glue_destructor(struct tevent_wrapper_glue *glue)
+{
+ struct tevent_context *main_ev = glue->main_ev;
+ struct tevent_fd *fd = NULL, *fn = NULL;
+ struct tevent_timer *te = NULL, *tn = NULL;
+ struct tevent_immediate *ie = NULL, *in = NULL;
+ struct tevent_signal *se = NULL, *sn = NULL;
+#ifdef HAVE_PTHREAD
+ struct tevent_threaded_context *tctx = NULL, *tctxn = NULL;
+#endif
+
+ if (main_ev == NULL) {
+ return 0;
+ }
+
+ glue->main_ev = NULL;
+ DLIST_REMOVE(main_ev->wrapper.list, glue);
+
+#ifdef HAVE_PTHREAD
+ for (tctx = main_ev->threaded_contexts; tctx != NULL; tctx = tctxn) {
+ int ret;
+
+ tctxn = tctx->next;
+
+ if (tctx->event_ctx != glue->wrap_ev) {
+ continue;
+ }
+
+ ret = pthread_mutex_lock(&tctx->event_ctx_mutex);
+ if (ret != 0) {
+ abort();
+ }
+
+ /*
+ * Indicate to the thread that the tevent_context is
+ * gone. The counterpart of this is in
+ * _tevent_threaded_schedule_immediate, there we read
+ * this under the threaded_context's mutex.
+ */
+
+ tctx->event_ctx = NULL;
+
+ ret = pthread_mutex_unlock(&tctx->event_ctx_mutex);
+ if (ret != 0) {
+ abort();
+ }
+
+ DLIST_REMOVE(main_ev->threaded_contexts, tctx);
+ }
+#endif
+
+ for (fd = main_ev->fd_events; fd; fd = fn) {
+ fn = fd->next;
+
+ if (fd->wrapper != glue) {
+ continue;
+ }
+
+ tevent_fd_set_flags(fd, 0);
+
+ fd->event_ctx = NULL;
+ DLIST_REMOVE(main_ev->fd_events, fd);
+ }
+
+ for (te = main_ev->timer_events; te; te = tn) {
+ tn = te->next;
+
+ if (te->wrapper != glue) {
+ continue;
+ }
+
+ te->event_ctx = NULL;
+
+ if (main_ev->last_zero_timer == te) {
+ main_ev->last_zero_timer = DLIST_PREV(te);
+ }
+ DLIST_REMOVE(main_ev->timer_events, te);
+ }
+
+ for (ie = main_ev->immediate_events; ie; ie = in) {
+ in = ie->next;
+
+ if (ie->wrapper != glue) {
+ continue;
+ }
+
+ ie->event_ctx = NULL;
+ ie->cancel_fn = NULL;
+ DLIST_REMOVE(main_ev->immediate_events, ie);
+ }
+
+ for (se = main_ev->signal_events; se; se = sn) {
+ sn = se->next;
+
+ if (se->wrapper != glue) {
+ continue;
+ }
+
+ tevent_cleanup_pending_signal_handlers(se);
+ }
+
+ return 0;
+}
+
+_PRIVATE_
+struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev,
+ TALLOC_CTX *mem_ctx,
+ const struct tevent_wrapper_ops *ops,
+ void *pstate,
+ size_t psize,
+ const char *type,
+ const char *location)
+{
+ void **ppstate = (void **)pstate;
+ struct tevent_context *ev = NULL;
+
+ if (main_ev->wrapper.glue != NULL) {
+ /*
+ * stacking of wrappers is not supported
+ */
+ tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL,
+ "%s: %s() stacking not allowed\n",
+ __func__, location);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (main_ev->nesting.allowed) {
+ /*
+ * wrappers conflict with nesting
+ */
+ tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL,
+ "%s: %s() conflicts with nesting\n",
+ __func__, location);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ ev = tevent_context_init_ops(mem_ctx,
+ &tevent_wrapper_glue_ops,
+ NULL);
+ if (ev == NULL) {
+ return NULL;
+ }
+
+ ev->wrapper.glue = talloc_zero(ev, struct tevent_wrapper_glue);
+ if (ev->wrapper.glue == NULL) {
+ talloc_free(ev);
+ return NULL;
+ }
+
+ ev->wrapper.glue->wrap_ev = ev;
+ ev->wrapper.glue->main_ev = main_ev;
+ ev->wrapper.glue->ops = ops;
+ ev->wrapper.glue->private_state = talloc_size(ev->wrapper.glue, psize);
+ if (ev->wrapper.glue->private_state == NULL) {
+ talloc_free(ev);
+ return NULL;
+ }
+ talloc_set_name_const(ev->wrapper.glue->private_state, type);
+
+ DLIST_ADD_END(main_ev->wrapper.list, ev->wrapper.glue);
+
+ talloc_set_destructor(ev->wrapper.glue, tevent_wrapper_glue_destructor);
+
+ *ppstate = ev->wrapper.glue->private_state;
+ return ev;
+}
+
+_PRIVATE_
+bool tevent_context_is_wrapper(struct tevent_context *ev)
+{
+ if (ev->wrapper.glue != NULL) {
+ return true;
+ }
+
+ return false;
+}
+
+_PRIVATE_
+struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev)
+{
+ if (ev == NULL) {
+ return NULL;
+ }
+
+ if (ev->wrapper.glue == NULL) {
+ return ev;
+ }
+
+ return ev->wrapper.glue->main_ev;
+}
+
+_PRIVATE_
+bool _tevent_context_before_use(struct tevent_context *ev,
+ const char *location)
+{
+ if (ev->wrapper.glue == NULL) {
+ return true;
+ }
+
+ if (ev->wrapper.glue->main_ev == NULL) {
+ return false;
+ }
+
+ return ev->wrapper.glue->ops->before_use(ev->wrapper.glue->wrap_ev,
+ ev->wrapper.glue->private_state,
+ ev->wrapper.glue->main_ev,
+ location);
+}
+
+_PRIVATE_
+void _tevent_context_after_use(struct tevent_context *ev,
+ const char *location)
+{
+ if (ev->wrapper.glue == NULL) {
+ return;
+ }
+
+ if (ev->wrapper.glue->main_ev == NULL) {
+ return;
+ }
+
+ ev->wrapper.glue->ops->after_use(ev->wrapper.glue->wrap_ev,
+ ev->wrapper.glue->private_state,
+ ev->wrapper.glue->main_ev,
+ location);
+}
+
+_PRIVATE_
+bool tevent_context_same_loop(struct tevent_context *ev1,
+ struct tevent_context *ev2)
+{
+ struct tevent_context *main_ev1 = tevent_wrapper_main_ev(ev1);
+ struct tevent_context *main_ev2 = tevent_wrapper_main_ev(ev2);
+
+ if (main_ev1 == NULL) {
+ return false;
+ }
+
+ if (main_ev1 == main_ev2) {
+ return true;
+ }
+
+ return false;
+}
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index 94d190f3b605..2395ead9aa93 100644
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript
@@ -77,7 +77,7 @@ def build(bld):
bld.RECURSE('lib/talloc')
SRC = '''tevent.c tevent_debug.c tevent_fd.c tevent_immediate.c
- tevent_queue.c tevent_req.c
+ tevent_queue.c tevent_req.c tevent_wrapper.c
tevent_poll.c tevent_threads.c
tevent_signal.c tevent_standard.c tevent_timed.c tevent_util.c tevent_wakeup.c'''
--
2.17.1
From e204c5733fb7cfe8bb1043a42a2c29f382bca807 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sat, 16 Jun 2018 14:12:01 +0200
Subject: [PATCH 21/37] tevent: add a simple wrapper test
This checks that for all supported event types the before and after
handlers are called.
Signed-off-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/testsuite.c | 327 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 327 insertions(+)
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index dba8f5895f76..ac274223d8bd 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -696,6 +696,329 @@ static bool test_event_fd2(struct torture_context *tctx,
return true;
}
+struct test_wrapper_state {
+ struct torture_context *tctx;
+ int num_events;
+ int num_wrap_handlers;
+};
+
+static bool test_wrapper_before_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+ return true;
+}
+
+static void test_wrapper_after_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_before_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static void test_wrapper_after_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_wrap_handlers++;
+}
+
+static const struct tevent_wrapper_ops test_wrapper_ops = {
+ .name = "test_wrapper",
+ .before_use = test_wrapper_before_use,
+ .after_use = test_wrapper_after_use,
+ .before_fd_handler = test_wrapper_before_fd_handler,
+ .after_fd_handler = test_wrapper_after_fd_handler,
+ .before_timer_handler = test_wrapper_before_timer_handler,
+ .after_timer_handler = test_wrapper_after_timer_handler,
+ .before_immediate_handler = test_wrapper_before_immediate_handler,
+ .after_immediate_handler = test_wrapper_after_immediate_handler,
+ .before_signal_handler = test_wrapper_before_signal_handler,
+ .after_signal_handler = test_wrapper_after_signal_handler,
+};
+
+static void test_wrapper_timer_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval tv,
+ void *private_data)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+
+ torture_comment(state->tctx, "timer handler\n");
+
+ state->num_events++;
+ talloc_free(te);
+ return;
+}
+
+static void test_wrapper_fd_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ unsigned short fd_flags,
+ void *private_data)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ torture_comment(state->tctx, "fd handler\n");
+
+ state->num_events++;
+ talloc_free(fde);
+ return;
+}
+
+static void test_wrapper_immediate_handler(struct tevent_context *ev,
+ struct tevent_immediate *im,
+ void *private_data)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ state->num_events++;
+ talloc_free(im);
+
+ torture_comment(state->tctx, "immediate handler\n");
+
+ tevent_context_before_use(ev);
+ tevent_context_after_use(ev);
+ return;
+}
+
+static void test_wrapper_signal_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ struct test_wrapper_state *state =
+ (struct test_wrapper_state *)private_data;
+
+ torture_comment(state->tctx, "signal handler\n");
+
+ state->num_events++;
+ talloc_free(se);
+ return;
+}
+
+static bool test_wrapper(struct torture_context *tctx,
+ const void *test_data)
+{
+ struct test_wrapper_state *state = NULL;
+ int sock[2] = { -1, -1};
+ uint8_t c = 0;
+ const int num_events = 4;
+ const char *backend = (const char *)test_data;
+ struct tevent_context *ev = NULL;
+ struct tevent_context *wrap_ev = NULL;
+ struct tevent_fd *fde = NULL;
+ struct tevent_timer *te = NULL;
+ struct tevent_signal *se = NULL;
+ struct tevent_immediate *im = NULL;
+ int ret;
+ bool ok = false;
+
+ ev = tevent_context_init_byname(tctx, backend);
+ if (ev == NULL) {
+ torture_skip(tctx, talloc_asprintf(tctx,
+ "event backend '%s' not supported\n",
+ backend));
+ return true;
+ }
+
+ tevent_set_debug_stderr(ev);
+ torture_comment(tctx, "tevent backend '%s'\n", backend);
+
+ wrap_ev = tevent_context_wrapper_create(
+ ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state);
+ torture_assert_not_null_goto(tctx, wrap_ev, ok, done,
+ "tevent_context_wrapper_create failed\n");
+ *state = (struct test_wrapper_state) {
+ .tctx = tctx,
+ };
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n");
+
+ te = tevent_add_timer(wrap_ev, wrap_ev,
+ timeval_current_ofs(0, 0),
+ test_wrapper_timer_handler, state);
+ torture_assert_not_null_goto(tctx, te, ok, done,
+ "tevent_add_timer failed\n");
+
+ fde = tevent_add_fd(wrap_ev, wrap_ev,
+ sock[1],
+ TEVENT_FD_READ,
+ test_wrapper_fd_handler,
+ state);
+ torture_assert_not_null_goto(tctx, fde, ok, done,
+ "tevent_add_fd failed\n");
+
+ im = tevent_create_immediate(wrap_ev);
+ torture_assert_not_null_goto(tctx, im, ok, done,
+ "tevent_create_immediate failed\n");
+
+ se = tevent_add_signal(wrap_ev, wrap_ev,
+ SIGUSR1,
+ 0,
+ test_wrapper_signal_handler,
+ state);
+ torture_assert_not_null_goto(tctx, se, ok, done,
+ "tevent_add_signal failed\n");
+
+ do_write(sock[0], &c, 1);
+ kill(getpid(), SIGUSR1);
+ tevent_schedule_immediate(im,
+ wrap_ev,
+ test_wrapper_immediate_handler,
+ state);
+
+ ret = tevent_loop_wait(ev);
+ torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n");
+
+ torture_comment(tctx, "Num events: %d\n", state->num_events);
+ torture_comment(tctx, "Num wrap handlers: %d\n",
+ state->num_wrap_handlers);
+
+ torture_assert_goto(tctx, state->num_events == num_events, ok, done,
+ "Wrong event count\n");
+ torture_assert_goto(tctx, state->num_wrap_handlers == num_events*2+2,
+ ok, done, "Wrong wrapper count\n");
+
+ ok = true;
+
+done:
+ TALLOC_FREE(wrap_ev);
+ TALLOC_FREE(ev);
+
+ if (sock[0] != -1) {
+ close(sock[0]);
+ }
+ if (sock[1] != -1) {
+ close(sock[1]);
+ }
+ return ok;
+}
+
#ifdef HAVE_PTHREAD
static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1280,6 +1603,10 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
"fd2",
test_event_fd2,
(const void *)list[i]);
+ torture_suite_add_simple_tcase_const(backend_suite,
+ "wrapper",
+ test_wrapper,
+ (const void *)list[i]);
torture_suite_add_suite(suite, backend_suite);
}
--
2.17.1
From bda6854a2e4d426900401f6fec6d8292e3f11c43 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sat, 16 Jun 2018 16:55:44 +0200
Subject: [PATCH 22/37] tevent: add a test that frees wrapper_ev with pending
events
Signed-off-by: Ralph Boehme <slow at samba.org>
---
lib/tevent/testsuite.c | 165 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index ac274223d8bd..a76df44dc880 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -1019,6 +1019,167 @@ done:
return ok;
}
+struct test_free_wrapper_state {
+ struct torture_context *tctx;
+ int num_wrap_handlers;
+};
+
+static void test_free_wrapper_signal_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ struct test_free_wrapper_state *state =
+ (struct test_free_wrapper_state *)private_data;
+
+ torture_comment(state->tctx, "signal handler\n");
+
+ talloc_free(se);
+
+ /*
+ * signal handlers have highest priority in tevent, so this signal
+ * handler will always be started before the other handlers
+ * below. Freeing the (wrapper) event context here tests that the
+ * wrapper implementation correclty handles the wrapper ev going away
+ * with pending events.
+ */
+ talloc_free(ev);
+ return;
+}
+
+static void test_free_wrapper_fd_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ unsigned short fd_flags,
+ void *private_data)
+{
+ struct test_free_wrapper_state *state =
+ (struct test_free_wrapper_state *)private_data;
+
+ torture_comment(state->tctx, "fd handler\n");
+
+ talloc_free(fde);
+ return;
+}
+
+static void test_free_wrapper_immediate_handler(struct tevent_context *ev,
+ struct tevent_immediate *im,
+ void *private_data)
+{
+ struct test_free_wrapper_state *state =
+ (struct test_free_wrapper_state *)private_data;
+
+ torture_comment(state->tctx, "immediate handler\n");
+
+ talloc_free(im);
+ return;
+}
+
+static void test_free_wrapper_timer_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval tv,
+ void *private_data)
+{
+ struct test_free_wrapper_state *state =
+ (struct test_free_wrapper_state *)private_data;
+
+
+ torture_comment(state->tctx, "timer handler\n");
+
+ talloc_free(te);
+ return;
+}
+
+static bool test_free_wrapper(struct torture_context *tctx,
+ const void *test_data)
+{
+ struct test_free_wrapper_state *state = NULL;
+ int sock[2] = { -1, -1};
+ uint8_t c = 0;
+ const char *backend = (const char *)test_data;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev = NULL;
+ struct tevent_context *wrap_ev = NULL;
+ struct tevent_fd *fde = NULL;
+ struct tevent_timer *te = NULL;
+ struct tevent_signal *se = NULL;
+ struct tevent_immediate *im = NULL;
+ int ret;
+ bool ok = false;
+
+ ev = tevent_context_init_byname(frame, backend);
+ if (ev == NULL) {
+ torture_skip(tctx, talloc_asprintf(tctx,
+ "event backend '%s' not supported\n",
+ backend));
+ return true;
+ }
+
+ tevent_set_debug_stderr(ev);
+ torture_comment(tctx, "tevent backend '%s'\n", backend);
+
+ wrap_ev = tevent_context_wrapper_create(
+ ev, ev, &test_wrapper_ops, &state, struct test_free_wrapper_state);
+ torture_assert_not_null_goto(tctx, wrap_ev, ok, done,
+ "tevent_context_wrapper_create failed\n");
+ *state = (struct test_free_wrapper_state) {
+ .tctx = tctx,
+ };
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n");
+
+ fde = tevent_add_fd(wrap_ev, frame,
+ sock[1],
+ TEVENT_FD_READ,
+ test_free_wrapper_fd_handler,
+ state);
+ torture_assert_not_null_goto(tctx, fde, ok, done,
+ "tevent_add_fd failed\n");
+
+ te = tevent_add_timer(wrap_ev, frame,
+ timeval_current_ofs(0, 0),
+ test_free_wrapper_timer_handler, state);
+ torture_assert_not_null_goto(tctx, te, ok, done,
+ "tevent_add_timer failed\n");
+
+ im = tevent_create_immediate(frame);
+ torture_assert_not_null_goto(tctx, im, ok, done,
+ "tevent_create_immediate failed\n");
+
+ se = tevent_add_signal(wrap_ev, frame,
+ SIGUSR1,
+ 0,
+ test_free_wrapper_signal_handler,
+ state);
+ torture_assert_not_null_goto(tctx, se, ok, done,
+ "tevent_add_signal failed\n");
+
+ do_write(sock[0], &c, 1);
+ kill(getpid(), SIGUSR1);
+ tevent_schedule_immediate(im,
+ wrap_ev,
+ test_free_wrapper_immediate_handler,
+ state);
+
+ ret = tevent_loop_wait(ev);
+ torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n");
+
+ ok = true;
+
+done:
+ TALLOC_FREE(frame);
+
+ if (sock[0] != -1) {
+ close(sock[0]);
+ }
+ if (sock[1] != -1) {
+ close(sock[1]);
+ }
+ return ok;
+}
+
#ifdef HAVE_PTHREAD
static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1607,6 +1768,10 @@ struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
"wrapper",
test_wrapper,
(const void *)list[i]);
+ torture_suite_add_simple_tcase_const(backend_suite,
+ "free_wrapper",
+ test_free_wrapper,
+ (const void *)list[i]);
torture_suite_add_suite(suite, backend_suite);
}
--
2.17.1
From 73a0922a976f2ad48de2fd56b0ea22cad1ac9263 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 14 Aug 2014 21:51:09 +0200
Subject: [PATCH 23/37] TODO: tevent: version 0.9.37
* make tevent_abort() reachable for backends
* add tevent_common_invoke_*_handler() functions
* add tevent_context_same_loop() function
* add tevent_context_wrapper_create() infrastructure
---
lib/tevent/ABI/tevent-0.9.37.sigs | 111 ++++++++++++++++++++++++++++++
lib/tevent/tevent.c | 2 -
lib/tevent/tevent_fd.c | 1 -
lib/tevent/tevent_immediate.c | 1 -
lib/tevent/tevent_signal.c | 1 -
lib/tevent/tevent_timed.c | 1 -
lib/tevent/tevent_wrapper.c | 5 --
lib/tevent/wscript | 2 +-
8 files changed, 112 insertions(+), 12 deletions(-)
create mode 100644 lib/tevent/ABI/tevent-0.9.37.sigs
diff --git a/lib/tevent/ABI/tevent-0.9.37.sigs b/lib/tevent/ABI/tevent-0.9.37.sigs
new file mode 100644
index 000000000000..85bf4a89ae2e
--- /dev/null
+++ b/lib/tevent/ABI/tevent-0.9.37.sigs
@@ -0,0 +1,111 @@
+_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
+_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
+_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+_tevent_context_after_use: void (struct tevent_context *, const char *)
+_tevent_context_before_use: bool (struct tevent_context *, const char *)
+_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *)
+_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *)
+_tevent_loop_once: int (struct tevent_context *, const char *)
+_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *)
+_tevent_loop_wait: int (struct tevent_context *, const char *)
+_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *)
+_tevent_req_callback_data: void *(struct tevent_req *)
+_tevent_req_cancel: bool (struct tevent_req *, const char *)
+_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *)
+_tevent_req_data: void *(struct tevent_req *)
+_tevent_req_done: void (struct tevent_req *, const char *)
+_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *)
+_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *)
+_tevent_req_notify_callback: void (struct tevent_req *, const char *)
+_tevent_req_oom: void (struct tevent_req *, const char *)
+_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *)
+_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *)
+tevent_abort: void (struct tevent_context *, const char *)
+tevent_backend_list: const char **(TALLOC_CTX *)
+tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *)
+tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
+tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
+tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_check_double_free: void (TALLOC_CTX *, const char *)
+tevent_common_check_signal: int (struct tevent_context *)
+tevent_common_context_destructor: int (struct tevent_context *)
+tevent_common_fd_destructor: int (struct tevent_fd *)
+tevent_common_fd_get_flags: uint16_t (struct tevent_fd *)
+tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
+tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t)
+tevent_common_have_events: bool (struct tevent_context *)
+tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *)
+tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *)
+tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *)
+tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *)
+tevent_common_loop_immediate: bool (struct tevent_context *)
+tevent_common_loop_timer_delay: struct timeval (struct tevent_context *)
+tevent_common_loop_wait: int (struct tevent_context *, const char *)
+tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *)
+tevent_common_threaded_activate_immediate: void (struct tevent_context *)
+tevent_common_wakeup: int (struct tevent_context *)
+tevent_common_wakeup_fd: int (int)
+tevent_common_wakeup_init: int (struct tevent_context *)
+tevent_context_init: struct tevent_context *(TALLOC_CTX *)
+tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *)
+tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *)
+tevent_context_is_wrapper: bool (struct tevent_context *)
+tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *)
+tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...)
+tevent_fd_get_flags: uint16_t (struct tevent_fd *)
+tevent_fd_set_auto_close: void (struct tevent_fd *)
+tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
+tevent_fd_set_flags: void (struct tevent_fd *, uint16_t)
+tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *)
+tevent_loop_allow_nesting: void (struct tevent_context *)
+tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *)
+tevent_num_signals: size_t (void)
+tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_entry_untrigger: void (struct tevent_queue_entry *)
+tevent_queue_length: size_t (struct tevent_queue *)
+tevent_queue_running: bool (struct tevent_queue *)
+tevent_queue_start: void (struct tevent_queue *)
+tevent_queue_stop: void (struct tevent_queue *)
+tevent_queue_wait_recv: bool (struct tevent_req *)
+tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *)
+tevent_re_initialise: int (struct tevent_context *)
+tevent_register_backend: bool (const char *, const struct tevent_ops *)
+tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *)
+tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *)
+tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *)
+tevent_req_is_in_progress: bool (struct tevent_req *)
+tevent_req_poll: bool (struct tevent_req *, struct tevent_context *)
+tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *)
+tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *)
+tevent_req_received: void (struct tevent_req *)
+tevent_req_reset_endtime: void (struct tevent_req *)
+tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *)
+tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn)
+tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn)
+tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval)
+tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn)
+tevent_sa_info_queue_count: size_t (void)
+tevent_set_abort_fn: void (void (*)(const char *))
+tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *)
+tevent_set_debug_stderr: int (struct tevent_context *)
+tevent_set_default_backend: void (const char *)
+tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *)
+tevent_signal_support: bool (struct tevent_context *)
+tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *)
+tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *)
+tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *)
+tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t)
+tevent_timeval_compare: int (const struct timeval *, const struct timeval *)
+tevent_timeval_current: struct timeval (void)
+tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t)
+tevent_timeval_is_zero: bool (const struct timeval *)
+tevent_timeval_set: struct timeval (uint32_t, uint32_t)
+tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *)
+tevent_timeval_zero: struct timeval (void)
+tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point)
+tevent_update_timer: void (struct tevent_timer *, struct timeval)
+tevent_wakeup_recv: bool (struct tevent_req *)
+tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval)
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 802dce43552b..548aa6db33e0 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -437,7 +437,6 @@ static int tevent_common_context_constructor(struct tevent_context *ev)
return 0;
}
-_PRIVATE_
void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason)
{
void *parent_ptr = talloc_parent(ptr);
@@ -601,7 +600,6 @@ void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
tevent_abort_fn = abort_fn;
}
-_PRIVATE_
void tevent_abort(struct tevent_context *ev, const char *reason)
{
if (ev != NULL) {
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
index 38d0eaeba73a..47c842c3ac72 100644
--- a/lib/tevent/tevent_fd.c
+++ b/lib/tevent/tevent_fd.c
@@ -106,7 +106,6 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
fde->close_fn = close_fn;
}
-_PRIVATE_
int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
bool *removed)
{
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
index ee4d8fa6e2a6..22e6a3e7f13f 100644
--- a/lib/tevent/tevent_immediate.c
+++ b/lib/tevent/tevent_immediate.c
@@ -125,7 +125,6 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im,
handler_name, im);
}
-_PRIVATE_
int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
bool *removed)
{
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index e0665cbafee6..3f3fdcec1c29 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -333,7 +333,6 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
return se;
}
-_PRIVATE_
int tevent_common_invoke_signal_handler(struct tevent_signal *se,
int signum, int count, void *siginfo,
bool *removed)
diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c
index 5ede71696af4..1f5ec0953fff 100644
--- a/lib/tevent/tevent_timed.c
+++ b/lib/tevent/tevent_timed.c
@@ -316,7 +316,6 @@ void tevent_update_timer(struct tevent_timer *te, struct timeval next_event)
tevent_common_insert_timer(ev, te, false);
}
-_PRIVATE_
int tevent_common_invoke_timer_handler(struct tevent_timer *te,
struct timeval current_time,
bool *removed)
diff --git a/lib/tevent/tevent_wrapper.c b/lib/tevent/tevent_wrapper.c
index 8305a50dfca5..2bc2b82d34a6 100644
--- a/lib/tevent/tevent_wrapper.c
+++ b/lib/tevent/tevent_wrapper.c
@@ -274,7 +274,6 @@ static int tevent_wrapper_glue_destructor(struct tevent_wrapper_glue *glue)
return 0;
}
-_PRIVATE_
struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev,
TALLOC_CTX *mem_ctx,
const struct tevent_wrapper_ops *ops,
@@ -339,7 +338,6 @@ struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *mai
return ev;
}
-_PRIVATE_
bool tevent_context_is_wrapper(struct tevent_context *ev)
{
if (ev->wrapper.glue != NULL) {
@@ -363,7 +361,6 @@ struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev)
return ev->wrapper.glue->main_ev;
}
-_PRIVATE_
bool _tevent_context_before_use(struct tevent_context *ev,
const char *location)
{
@@ -381,7 +378,6 @@ bool _tevent_context_before_use(struct tevent_context *ev,
location);
}
-_PRIVATE_
void _tevent_context_after_use(struct tevent_context *ev,
const char *location)
{
@@ -399,7 +395,6 @@ void _tevent_context_after_use(struct tevent_context *ev,
location);
}
-_PRIVATE_
bool tevent_context_same_loop(struct tevent_context *ev1,
struct tevent_context *ev2)
{
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index 2395ead9aa93..54330d27cadb 100644
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript
@@ -1,7 +1,7 @@
#!/usr/bin/env python
APPNAME = 'tevent'
-VERSION = '0.9.36'
+VERSION = '0.9.37'
blddir = 'bin'
--
2.17.1
From 541f38b8345745858a376ccd165d91f4cce27b65 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 18 May 2018 16:28:47 +0200
Subject: [PATCH 24/37] s3:messages: protect against usage of wrapper
tevent_context objects for messaging
This makes a lot of assumtion easier to understand and the introduction
of wrapper tevent contexts will not change the existing behaviour.
We'll relax this a bit in the next commits.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/lib/messages.c | 23 +++++++++++++++++++++++
source3/lib/messages_ctdb.c | 8 ++++++++
source3/lib/messages_ctdb_ref.c | 12 ++++++++++++
source3/lib/messages_dgm.c | 14 ++++++++++++++
source3/lib/messages_dgm_ref.c | 12 ++++++++++++
5 files changed, 69 insertions(+)
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 82a177856f60..1a5ea4659aa4 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -365,6 +365,11 @@ static bool messaging_alert_event_contexts(struct messaging_context *ctx)
* alternatively would be to track whether the
* immediate has already been scheduled. For
* now, avoid that complexity here.
+ *
+ * reg->ev and ctx->event_ctx can't
+ * be wrapper tevent_context pointers
+ * so we don't need to use
+ * tevent_context_same_loop().
*/
if (reg->ev == ctx->event_ctx) {
@@ -493,6 +498,12 @@ static NTSTATUS messaging_init_internal(TALLOC_CTX *mem_ctx,
sec_init();
+ if (tevent_context_is_wrapper(ev)) {
+ /* This is really a programmer error! */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
lck_path = lock_path("msg.lock");
if (lck_path == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -1023,6 +1034,13 @@ struct tevent_req *messaging_filtered_read_send(
state->filter = filter;
state->private_data = private_data;
+ if (tevent_context_is_wrapper(ev)) {
+ /* This is really a programmer error! */
+ DBG_ERR("Wrapper tevent context doesn't use main context.\n");
+ tevent_req_error(req, EINVAL);
+ return tevent_req_post(req, ev);
+ }
+
/*
* We have to defer the callback here, as we might be called from
* within a different tevent_context than state->ev
@@ -1343,6 +1361,11 @@ static void messaging_dispatch_rec(struct messaging_context *msg_ctx,
bool consumed;
size_t i;
+ /*
+ * ev and msg_ctx->event_ctx can't be wrapper tevent_context pointers
+ * so we don't need to use tevent_context_same_loop().
+ */
+
if (ev == msg_ctx->event_ctx) {
consumed = messaging_dispatch_classic(msg_ctx, rec);
if (consumed) {
diff --git a/source3/lib/messages_ctdb.c b/source3/lib/messages_ctdb.c
index d3e2e3f85893..a1aeb37af198 100644
--- a/source3/lib/messages_ctdb.c
+++ b/source3/lib/messages_ctdb.c
@@ -209,6 +209,14 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
return NULL;
}
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return NULL;
+ }
+
fde = talloc(mem_ctx, struct messaging_ctdb_fde);
if (fde == NULL) {
return NULL;
diff --git a/source3/lib/messages_ctdb_ref.c b/source3/lib/messages_ctdb_ref.c
index 3570ed8ae4c8..47b4b758dac5 100644
--- a/source3/lib/messages_ctdb_ref.c
+++ b/source3/lib/messages_ctdb_ref.c
@@ -52,6 +52,18 @@ void *messaging_ctdb_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
{
struct msg_ctdb_ref *result, *tmp_refs;
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ *
+ * The main/raw tevent context should
+ * have been registered first!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ *err = EINVAL;
+ return NULL;
+ }
+
result = talloc(mem_ctx, struct msg_ctdb_ref);
if (result == NULL) {
*err = ENOMEM;
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
index b8878b68b996..1c76615093c0 100644
--- a/source3/lib/messages_dgm.c
+++ b/source3/lib/messages_dgm.c
@@ -993,6 +993,12 @@ int messaging_dgm_init(struct tevent_context *ev,
return EEXIST;
}
+ if (tevent_context_is_wrapper(ev)) {
+ /* This is really a programmer error! */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return EINVAL;
+ }
+
ctx = talloc_zero(NULL, struct messaging_dgm_context);
if (ctx == NULL) {
goto fail_nomem;
@@ -1673,6 +1679,14 @@ struct messaging_dgm_fde *messaging_dgm_register_tevent_context(
return NULL;
}
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return NULL;
+ }
+
fde = talloc(mem_ctx, struct messaging_dgm_fde);
if (fde == NULL) {
return NULL;
diff --git a/source3/lib/messages_dgm_ref.c b/source3/lib/messages_dgm_ref.c
index 39d22700740c..a22077043651 100644
--- a/source3/lib/messages_dgm_ref.c
+++ b/source3/lib/messages_dgm_ref.c
@@ -54,6 +54,18 @@ void *messaging_dgm_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
{
struct msg_dgm_ref *result, *tmp_refs;
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ *
+ * The main/raw tevent context should
+ * have been registered first!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ *err = EINVAL;
+ return NULL;
+ }
+
result = talloc(mem_ctx, struct msg_dgm_ref);
if (result == NULL) {
*err = ENOMEM;
--
2.17.1
From 9451a7f71a9c954d04626e16c21b97c281918be3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 23 Mar 2018 14:48:46 +0100
Subject: [PATCH 25/37] s3:messages: allow
messaging_{dgm,ctdb}_register_tevent_context() to use wrapper tevent_context
This is only allowed if the raw tevent context is already registered.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/lib/messages_ctdb.c | 38 ++++++++++++++++++++++++++++---------
source3/lib/messages_dgm.c | 38 ++++++++++++++++++++++++++++---------
2 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/source3/lib/messages_ctdb.c b/source3/lib/messages_ctdb.c
index a1aeb37af198..11fe72661cc3 100644
--- a/source3/lib/messages_ctdb.c
+++ b/source3/lib/messages_ctdb.c
@@ -209,14 +209,6 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
return NULL;
}
- if (tevent_context_is_wrapper(ev)) {
- /*
- * This is really a programmer error!
- */
- DBG_ERR("Should not be used with a wrapper tevent context\n");
- return NULL;
- }
-
fde = talloc(mem_ctx, struct messaging_ctdb_fde);
if (fde == NULL) {
return NULL;
@@ -234,7 +226,24 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
*/
continue;
}
- if (fde_ev->ev == ev) {
+
+ /*
+ * We can only have one tevent_fd
+ * per low level tevent_context.
+ *
+ * This means any wrapper tevent_context
+ * needs to share the structure with
+ * the main tevent_context and/or
+ * any sibling wrapper tevent_context.
+ *
+ * This means we need to use tevent_context_same_loop()
+ * instead of just (fde_ev->ev == ev).
+ *
+ * Note: the tevent_context_is_wrapper() check below
+ * makes sure that fde_ev->ev is always a raw
+ * tevent context.
+ */
+ if (tevent_context_same_loop(fde_ev->ev, ev)) {
break;
}
}
@@ -242,6 +251,17 @@ struct messaging_ctdb_fde *messaging_ctdb_register_tevent_context(
if (fde_ev == NULL) {
int sock = ctdbd_conn_get_fd(ctx->conn);
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ *
+ * The main/raw tevent context should
+ * have been registered first!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return NULL;
+ }
+
fde_ev = talloc(fde, struct messaging_ctdb_fde_ev);
if (fde_ev == NULL) {
return NULL;
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c
index 1c76615093c0..0ad8f46e09f1 100644
--- a/source3/lib/messages_dgm.c
+++ b/source3/lib/messages_dgm.c
@@ -1679,14 +1679,6 @@ struct messaging_dgm_fde *messaging_dgm_register_tevent_context(
return NULL;
}
- if (tevent_context_is_wrapper(ev)) {
- /*
- * This is really a programmer error!
- */
- DBG_ERR("Should not be used with a wrapper tevent context\n");
- return NULL;
- }
-
fde = talloc(mem_ctx, struct messaging_dgm_fde);
if (fde == NULL) {
return NULL;
@@ -1704,12 +1696,40 @@ struct messaging_dgm_fde *messaging_dgm_register_tevent_context(
*/
continue;
}
- if (fde_ev->ev == ev) {
+
+ /*
+ * We can only have one tevent_fd
+ * per low level tevent_context.
+ *
+ * This means any wrapper tevent_context
+ * needs to share the structure with
+ * the main tevent_context and/or
+ * any sibling wrapper tevent_context.
+ *
+ * This means we need to use tevent_context_same_loop()
+ * instead of just (fde_ev->ev == ev).
+ *
+ * Note: the tevent_context_is_wrapper() check below
+ * makes sure that fde_ev->ev is always a raw
+ * tevent context.
+ */
+ if (tevent_context_same_loop(fde_ev->ev, ev)) {
break;
}
}
if (fde_ev == NULL) {
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ *
+ * The main/raw tevent context should
+ * have been registered first!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ return NULL;
+ }
+
fde_ev = talloc(fde, struct messaging_dgm_fde_ev);
if (fde_ev == NULL) {
return NULL;
--
2.17.1
From 3082e5147c2fcdb6d4f6a2dce421412959e305ad Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 23 Mar 2018 14:48:46 +0100
Subject: [PATCH 26/37] s3:messages: allow messaging_dgm_ref() to use wrapper
tevent_context
This is only allowed if the raw tevent context is already registered.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/lib/messages_dgm_ref.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/source3/lib/messages_dgm_ref.c b/source3/lib/messages_dgm_ref.c
index a22077043651..8fb3bd612086 100644
--- a/source3/lib/messages_dgm_ref.c
+++ b/source3/lib/messages_dgm_ref.c
@@ -54,18 +54,6 @@ void *messaging_dgm_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
{
struct msg_dgm_ref *result, *tmp_refs;
- if (tevent_context_is_wrapper(ev)) {
- /*
- * This is really a programmer error!
- *
- * The main/raw tevent context should
- * have been registered first!
- */
- DBG_ERR("Should not be used with a wrapper tevent context\n");
- *err = EINVAL;
- return NULL;
- }
-
result = talloc(mem_ctx, struct msg_dgm_ref);
if (result == NULL) {
*err = ENOMEM;
@@ -86,6 +74,18 @@ void *messaging_dgm_ref(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
if (refs == NULL) {
int ret;
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ *
+ * The main/raw tevent context should
+ * have been registered first!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ *err = EINVAL;
+ return NULL;
+ }
+
ret = messaging_dgm_init(ev, unique, socket_dir, lockfile_dir,
msg_dgm_ref_recv, NULL);
DBG_DEBUG("messaging_dgm_init returned %s\n", strerror(ret));
--
2.17.1
From 1a4c554b30ce532347759ea74c9c9c838e392502 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 23 Mar 2018 14:48:46 +0100
Subject: [PATCH 27/37] s3:messages: allow messaging_filtered_read_send() to
use wrapper tevent_context
As it gets 'messaging_context' as argument, we're sure a messaging context
with a raw tevent context already exist.
It means we can allow a wrapper tevent context that wrapps the main tevent
context of the messaging context.
The use of tevent_req_defer_callback() makes sure that the callers
callback function calls messaging_filtered_read_recv() from the
correct "wrapped" environment.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/lib/messages.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 1a5ea4659aa4..dab53f1c48e3 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -206,7 +206,7 @@ static bool messaging_register_event_context(struct messaging_context *ctx,
continue;
}
- if (reg->ev == ev) {
+ if (tevent_context_same_loop(reg->ev, ev)) {
reg->refcount += 1;
return true;
}
@@ -255,7 +255,7 @@ static bool messaging_deregister_event_context(struct messaging_context *ctx,
continue;
}
- if (reg->ev == ev) {
+ if (tevent_context_same_loop(reg->ev, ev)) {
reg->refcount -= 1;
if (reg->refcount == 0) {
@@ -1034,7 +1034,9 @@ struct tevent_req *messaging_filtered_read_send(
state->filter = filter;
state->private_data = private_data;
- if (tevent_context_is_wrapper(ev)) {
+ if (tevent_context_is_wrapper(ev) &&
+ !tevent_context_same_loop(ev, msg_ctx->event_ctx))
+ {
/* This is really a programmer error! */
DBG_ERR("Wrapper tevent context doesn't use main context.\n");
tevent_req_error(req, EINVAL);
@@ -1043,7 +1045,11 @@ struct tevent_req *messaging_filtered_read_send(
/*
* We have to defer the callback here, as we might be called from
- * within a different tevent_context than state->ev
+ * within a different tevent_context than state->ev.
+ *
+ * This is important for two cases:
+ * 1. nested event contexts, used by blocking ctdb calls
+ * 2. possible impersonation using wrapper tevent contexts.
*/
tevent_req_defer_callback(req, state->ev);
@@ -1339,7 +1345,7 @@ static bool messaging_dispatch_waiters(struct messaging_context *msg_ctx,
state = tevent_req_data(
req, struct messaging_filtered_read_state);
- if ((ev == state->ev) &&
+ if (tevent_context_same_loop(ev, state->ev) &&
state->filter(rec, state->private_data)) {
messaging_filtered_read_done(req, rec);
return true;
--
2.17.1
From f4bae1e1e906cf7842db80603a23215cffe24374 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 19 May 2018 10:14:25 +0200
Subject: [PATCH 28/37] s4:messaging: allow imessaging_post_handler() to free
the messaging context from a handler
In usecases like using messaging_client_init() with irpc processing we may
free the imessaging_context during the messaging handler.
imessaging_post_handler() is not yet really used, but it will change in
the next commits. imessaging_post_state is a child of imessaging_context
and might be implicitly free'ed before the explicit TALLOC_FREE(state).
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source4/lib/messaging/messaging.c | 33 +++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index b8d4e50f12c7..8903322bdc7f 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -433,18 +433,48 @@ fail:
struct imessaging_post_state {
struct imessaging_context *msg_ctx;
+ struct imessaging_post_state **busy_ref;
size_t buf_len;
uint8_t buf[];
};
+static int imessaging_post_state_destructor(struct imessaging_post_state *state)
+{
+ if (state->busy_ref != NULL) {
+ *state->busy_ref = NULL;
+ state->busy_ref = NULL;
+ }
+ return 0;
+}
+
static void imessaging_post_handler(struct tevent_context *ev,
struct tevent_immediate *ti,
void *private_data)
{
struct imessaging_post_state *state = talloc_get_type_abort(
private_data, struct imessaging_post_state);
+
+ /*
+ * In usecases like using messaging_client_init() with irpc processing
+ * we may free the imessaging_context during the messaging handler.
+ * imessaging_post_state is a child of imessaging_context and
+ * might be implicitly free'ed before the explicit TALLOC_FREE(state).
+ *
+ * The busy_ref pointer makes sure the destructor clears
+ * the local 'state' variable.
+ */
+
+ SMB_ASSERT(state->busy_ref == NULL);
+ state->busy_ref = &state;
+
imessaging_dgm_recv(ev, state->buf, state->buf_len, NULL, 0,
state->msg_ctx);
+
+ if (state == NULL) {
+ return;
+ }
+
+ state->busy_ref = NULL;
TALLOC_FREE(state);
}
@@ -461,6 +491,8 @@ static int imessaging_post_self(struct imessaging_context *msg,
}
talloc_set_name_const(state, "struct imessaging_post_state");
+ talloc_set_destructor(state, imessaging_post_state_destructor);
+
ti = tevent_create_immediate(state);
if (ti == NULL) {
TALLOC_FREE(state);
@@ -468,6 +500,7 @@ static int imessaging_post_self(struct imessaging_context *msg,
}
state->msg_ctx = msg;
+ state->busy_ref = NULL;
state->buf_len = buf_len;
memcpy(state->buf, buf, buf_len);
--
2.17.1
From 30e323d7c8ee44c1d96e5839f26fed4a511d5dad Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 18 May 2018 16:28:47 +0200
Subject: [PATCH 29/37] s4:messaging: make sure only imessaging_client_init()
can be used with a wrapper tevent_context wrapper
imessaging_client_init() can be used with a wrapper tevent_context,
but only if a global messaging_dgm_ref() already exist.
All other uses of imessaging_init() and imessaging_client_init()
require a raw tevent_context.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source4/lib/messaging/messaging.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 8903322bdc7f..935951f3fbae 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -319,7 +319,7 @@ NTSTATUS imessaging_reinit_all(void)
/*
create the listening socket and setup the dispatcher
*/
-struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx,
+static struct imessaging_context *imessaging_init_internal(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
struct server_id server_id,
struct tevent_context *ev)
@@ -573,6 +573,30 @@ static void imessaging_dgm_recv(struct tevent_context *ev,
}
}
+struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct server_id server_id,
+ struct tevent_context *ev)
+{
+ if (ev == NULL) {
+ return NULL;
+ }
+
+ if (tevent_context_is_wrapper(ev)) {
+ /*
+ * This is really a programmer error!
+ *
+ * The main/raw tevent context should
+ * have been registered first!
+ */
+ DBG_ERR("Should not be used with a wrapper tevent context\n");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return imessaging_init_internal(mem_ctx, lp_ctx, server_id, ev);
+}
+
/*
A hack, for the short term until we get 'client only' messaging in place
*/
@@ -589,7 +613,7 @@ struct imessaging_context *imessaging_client_init(TALLOC_CTX *mem_ctx,
/* This is because we are not in the s3 serverid database */
id.unique_id = SERVERID_UNIQUE_ID_NOT_TO_VERIFY;
- return imessaging_init(mem_ctx, lp_ctx, id, ev);
+ return imessaging_init_internal(mem_ctx, lp_ctx, id, ev);
}
/*
a list of registered irpc server functions
--
2.17.1
From 86353ffe29515654854ed643e0e83a1f8b7c9e98 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 25 May 2018 16:22:33 +0200
Subject: [PATCH 30/37] smbd: add [un]become_guest() helper functions
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/smbd/proto.h | 2 ++
source3/smbd/uid.c | 28 ++++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index ab4a8d68d3f1..cbb43829fe08 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1203,6 +1203,8 @@ void become_root(void);
void unbecome_root(void);
void smbd_become_root(void);
void smbd_unbecome_root(void);
+bool become_guest(void);
+void unbecome_guest(void);
bool become_user(connection_struct *conn, uint64_t vuid);
bool become_user_by_fsp(struct files_struct *fsp);
bool become_user_by_session(connection_struct *conn,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index e021031a8b75..0732a88d5295 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -594,6 +594,34 @@ void smbd_unbecome_root(void)
pop_conn_ctx();
}
+bool become_guest(void)
+{
+ bool ok;
+
+ ok = push_sec_ctx();
+ if (!ok) {
+ return false;
+ }
+
+ push_conn_ctx();
+
+ ok = change_to_guest();
+ if (!ok) {
+ pop_sec_ctx();
+ pop_conn_ctx();
+ return false;
+ }
+
+ return true;
+}
+
+void unbecome_guest(void)
+{
+ pop_sec_ctx();
+ pop_conn_ctx();
+ return;
+}
+
/****************************************************************************
Push the current security context then force a change via change_to_user().
Saves and restores the connection context.
--
2.17.1
From 08091cb84d8049223f00def9b3b39dbf7212eefa Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 23 Mar 2018 07:47:38 +0100
Subject: [PATCH 31/37] smbd: add smbd_impersonate_debug_create() helper
This will be used to implement no-op impersonation
for the create_conn_struct_as_root() case were we
don't really have other unrelated events in the loop
and only need a valid tevent wrapper context to avoid
double free on the raw event context on teardown.
This also adds useful debugging instead of being
a full no-op wrapper.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/smbd/proto.h | 6 ++
source3/smbd/uid.c | 229 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 235 insertions(+)
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index cbb43829fe08..f31ef98624c7 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1189,6 +1189,12 @@ void reply_transs2(struct smb_request *req);
/* The following definitions come from smbd/uid.c */
+#define smbd_impersonate_debug_create(main_ev, name, dbg_lvl) \
+ _smbd_impersonate_debug_create(main_ev, name, dbg_lvl, __location__)
+struct tevent_context *_smbd_impersonate_debug_create(struct tevent_context *main_ev,
+ const char *name,
+ int dbg_lvl,
+ const char *location);
bool change_to_guest(void);
NTSTATUS check_user_share_access(connection_struct *conn,
const struct auth_session_info *session_info,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 0732a88d5295..2ac0d885ee3c 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -25,6 +25,235 @@
#include "libcli/security/security.h"
#include "passdb/lookup_sid.h"
#include "auth.h"
+#include "lib/util/time_basic.h"
+
+struct smbd_impersonate_debug_state {
+ int dbg_lvl;
+ const char *name;
+};
+
+static bool smbd_impersonate_debug_before_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev, location));
+
+ return true;
+}
+
+static void smbd_impersonate_debug_after_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev, location));
+}
+
+static void smbd_impersonate_debug_before_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "fde[%p] flags[0x%X] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev,
+ fde, flags, handler_name, location));
+}
+
+static void smbd_impersonate_debug_after_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "fde[%p] flags[0x%X] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev,
+ fde, flags, handler_name, location));
+}
+
+static void smbd_impersonate_debug_before_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+ struct timeval_buf requested_buf;
+ struct timeval_buf trigger_buf;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "te[%p] requested_time[%s] trigger_time[%s] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev, te,
+ timeval_str_buf(&requested_time, true, true, &requested_buf),
+ timeval_str_buf(&trigger_time, true, true, &trigger_buf),
+ handler_name, location));
+}
+
+static void smbd_impersonate_debug_after_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+ struct timeval_buf requested_buf;
+ struct timeval_buf trigger_buf;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "te[%p] requested_time[%s] trigger_time[%s] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev, te,
+ timeval_str_buf(&requested_time, true, true, &requested_buf),
+ timeval_str_buf(&trigger_time, true, true, &trigger_buf),
+ handler_name, location));
+}
+
+static void smbd_impersonate_debug_before_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "im[%p] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev,
+ im, handler_name, location));
+}
+
+static void smbd_impersonate_debug_after_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "im[%p] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev,
+ im, handler_name, location));
+}
+
+static void smbd_impersonate_debug_before_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "se[%p] signum[%d] count[%d] siginfo[%p] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev,
+ se, signum, count, siginfo, handler_name, location));
+}
+
+static void smbd_impersonate_debug_after_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ struct smbd_impersonate_debug_state *state =
+ (struct smbd_impersonate_debug_state *)private_data;
+
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
+ "se[%p] signum[%d] count[%d] siginfo[%p] handler_name[%s] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev,
+ se, signum, count, siginfo, handler_name, location));
+}
+
+static const struct tevent_wrapper_ops smbd_impersonate_debug_ops = {
+ .name = "smbd_impersonate_debug",
+ .before_use = smbd_impersonate_debug_before_use,
+ .after_use = smbd_impersonate_debug_after_use,
+ .before_fd_handler = smbd_impersonate_debug_before_fd_handler,
+ .after_fd_handler = smbd_impersonate_debug_after_fd_handler,
+ .before_timer_handler = smbd_impersonate_debug_before_timer_handler,
+ .after_timer_handler = smbd_impersonate_debug_after_timer_handler,
+ .before_immediate_handler = smbd_impersonate_debug_before_immediate_handler,
+ .after_immediate_handler = smbd_impersonate_debug_after_immediate_handler,
+ .before_signal_handler = smbd_impersonate_debug_before_signal_handler,
+ .after_signal_handler = smbd_impersonate_debug_after_signal_handler,
+};
+
+struct tevent_context *_smbd_impersonate_debug_create(struct tevent_context *main_ev,
+ const char *name,
+ int dbg_lvl,
+ const char *location)
+{
+ struct tevent_context *wrap_ev = NULL;
+ struct smbd_impersonate_debug_state *state = NULL;
+
+ wrap_ev = tevent_context_wrapper_create(main_ev,
+ main_ev,
+ &smbd_impersonate_debug_ops,
+ &state,
+ struct smbd_impersonate_debug_state);
+ if (wrap_ev == NULL) {
+ return NULL;
+ }
+ state->name = name;
+ state->dbg_lvl = dbg_lvl;
+ DEBUG(state->dbg_lvl, (
+ "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
+ __func__, state->name, wrap_ev, state, main_ev, location));
+
+ return wrap_ev;
+}
/* what user is current? */
extern struct current_user current_user;
--
2.17.1
From 1bffff6b97f0232a2ae8f16d472aba87cfc7661f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 32/37] smbd: add simple noop
smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers
As a start these are just wrappers arround
smbd_impersonate_debug_create(), without any real impersonation.
But this will change shortly.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/smbd/proto.h | 11 ++++++++++
source3/smbd/uid.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index f31ef98624c7..29121d5c4961 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1222,6 +1222,17 @@ const struct security_unix_token *get_current_utok(connection_struct *conn);
const struct security_token *get_current_nttok(connection_struct *conn);
uint64_t get_current_vuid(connection_struct *conn);
+struct tevent_context *smbd_impersonate_conn_vuid_create(
+ struct tevent_context *main_ev,
+ struct connection_struct *conn,
+ uint64_t vuid);
+struct tevent_context *smbd_impersonate_conn_sess_create(
+ struct tevent_context *main_ev,
+ struct connection_struct *conn,
+ struct auth_session_info *session_info);
+struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev);
+struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev);
+
/* The following definitions come from smbd/utmp.c */
void sys_utmp_claim(const char *username, const char *hostname,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 2ac0d885ee3c..f23a6b680d05 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -953,3 +953,53 @@ uint64_t get_current_vuid(connection_struct *conn)
{
return current_user.vuid;
}
+
+struct tevent_context *smbd_impersonate_conn_vuid_create(
+ struct tevent_context *main_ev,
+ struct connection_struct *conn,
+ uint64_t vuid)
+{
+ struct tevent_context *wrap_ev = NULL;
+
+ wrap_ev = smbd_impersonate_debug_create(main_ev,
+ "conn_vuid",
+ DBGLVL_DEBUG);
+
+ return wrap_ev;
+}
+
+struct tevent_context *smbd_impersonate_conn_sess_create(
+ struct tevent_context *main_ev,
+ struct connection_struct *conn,
+ struct auth_session_info *session_info)
+{
+ struct tevent_context *wrap_ev = NULL;
+
+ wrap_ev = smbd_impersonate_debug_create(main_ev,
+ "conn_sess",
+ DBGLVL_DEBUG);
+
+ return wrap_ev;
+}
+
+struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev)
+{
+ struct tevent_context *wrap_ev = NULL;
+
+ wrap_ev = smbd_impersonate_debug_create(main_ev,
+ "root",
+ DBGLVL_DEBUG);
+
+ return wrap_ev;
+}
+
+struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev)
+{
+ struct tevent_context *wrap_ev = NULL;
+
+ wrap_ev = smbd_impersonate_debug_create(main_ev,
+ "guest",
+ DBGLVL_DEBUG);
+
+ return wrap_ev;
+}
--
2.17.1
From 648e614d3db12e14c39529f39c7c6a0321d4c4ac Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 22 Mar 2018 10:54:41 +0100
Subject: [PATCH 33/37] smbd: make use of
smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers
For now they just add debugging, but that will change shortly.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/modules/vfs_readonly.c | 2 +-
source3/smbd/conn.c | 2 +-
source3/smbd/msdfs.c | 34 +++++++++++++++++++++++++++++++---
source3/smbd/process.c | 18 ++++++++++++++++--
source3/smbd/uid.c | 20 ++++++++++++++++++--
5 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index 570eb7c4d15a..e7e12747a222 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -84,7 +84,7 @@ static int readonly_connect(vfs_handle_struct *handle,
for (i=0; i< VUID_CACHE_SIZE; i++) {
struct vuid_cache_entry *ent = &conn->vuid_cache->array[i];
ent->vuid = UID_FIELD_INVALID;
- ent->user_ev_ctx = NULL;
+ TALLOC_FREE(ent->user_ev_ctx);
TALLOC_FREE(ent->session_info);
ent->read_only = false;
ent->share_access = 0;
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 3b9aaac7834b..cfff6404608f 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -98,7 +98,7 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
if (conn->user_ev_ctx == ent->user_ev_ctx) {
conn->user_ev_ctx = NULL;
}
- ent->user_ev_ctx = NULL;
+ TALLOC_FREE(ent->user_ev_ctx);
/*
* We need to keep conn->session_info around
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index bac9d8f6bf66..dae1707429a0 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -263,8 +263,17 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
return NT_STATUS_NO_MEMORY;
}
- sconn->root_ev_ctx = sconn->raw_ev_ctx;
- sconn->guest_ev_ctx = sconn->raw_ev_ctx;
+ sconn->root_ev_ctx = smbd_impersonate_root_create(sconn->raw_ev_ctx);
+ if (sconn->root_ev_ctx == NULL) {
+ TALLOC_FREE(sconn);
+ return NT_STATUS_NO_MEMORY;
+ }
+ sconn->guest_ev_ctx = smbd_impersonate_guest_create(sconn->raw_ev_ctx);
+ if (sconn->guest_ev_ctx == NULL) {
+ TALLOC_FREE(sconn);
+ return NT_STATUS_NO_MEMORY;
+ }
+
sconn->msg_ctx = msg;
conn = conn_new(sconn);
@@ -313,7 +322,26 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
vfs_user = get_current_username();
}
- conn->user_ev_ctx = sconn->raw_ev_ctx;
+ /*
+ * The impersonation has to be done by the caller
+ * of create_conn_struct_tos[_cwd]().
+ *
+ * Note: the context can't be changed anyway
+ * as we're using our own tevent_context
+ * and not a global one were other requests
+ * could change the current unix token.
+ *
+ * We just use a wrapper tevent_context in order
+ * to avoid crashes because TALLOC_FREE(conn->user_ev_ctx)
+ * would also remove sconn->raw_ev_ctx.
+ */
+ conn->user_ev_ctx = smbd_impersonate_debug_create(sconn->raw_ev_ctx,
+ "FAKE impersonation",
+ DBGLVL_DEBUG);
+ if (conn->user_ev_ctx == NULL) {
+ TALLOC_FREE(conn);
+ return NT_STATUS_NO_MEMORY;
+ }
set_conn_connectpath(conn, connpath);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index a3571ee811ab..dc95af17393b 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -3900,6 +3900,8 @@ void smbd_process(struct tevent_context *ev_ctx,
.ev = ev_ctx,
.frame = talloc_stackframe(),
};
+ struct tevent_context *root_ev_ctx = NULL;
+ struct tevent_context *guest_ev_ctx = NULL;
struct smbXsrv_client *client = NULL;
struct smbd_server_connection *sconn = NULL;
struct smbXsrv_connection *xconn = NULL;
@@ -3912,6 +3914,18 @@ void smbd_process(struct tevent_context *ev_ctx,
char *chroot_dir = NULL;
int rc;
+ root_ev_ctx = smbd_impersonate_root_create(ev_ctx);
+ if (root_ev_ctx == NULL) {
+ DEBUG(0,("smbd_impersonate_root_create() failed\n"));
+ exit_server_cleanly("smbd_impersonate_root_create().\n");
+ }
+
+ guest_ev_ctx = smbd_impersonate_guest_create(ev_ctx);
+ if (guest_ev_ctx == NULL) {
+ DEBUG(0,("smbd_impersonate_guest_create() failed\n"));
+ exit_server_cleanly("smbd_impersonate_guest_create().\n");
+ }
+
status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
@@ -3932,8 +3946,8 @@ void smbd_process(struct tevent_context *ev_ctx,
sconn->client = client;
sconn->raw_ev_ctx = ev_ctx;
- sconn->root_ev_ctx = ev_ctx;
- sconn->guest_ev_ctx = ev_ctx;
+ sconn->root_ev_ctx = root_ev_ctx;
+ sconn->guest_ev_ctx = guest_ev_ctx;
sconn->msg_ctx = msg_ctx;
ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index f23a6b680d05..6f586e03a5aa 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -306,7 +306,7 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
}
}
/* Not used, safe to free. */
- conn->user_ev_ctx = NULL;
+ TALLOC_FREE(conn->user_ev_ctx);
TALLOC_FREE(conn->session_info);
}
@@ -481,7 +481,23 @@ static bool check_user_ok(connection_struct *conn,
ent->session_info->unix_token->uid = sec_initial_uid();
}
- ent->user_ev_ctx = conn->sconn->raw_ev_ctx;
+ if (vuid == UID_FIELD_INVALID) {
+ ent->user_ev_ctx = smbd_impersonate_conn_sess_create(
+ conn->sconn->raw_ev_ctx, conn, ent->session_info);
+ if (ent->user_ev_ctx == NULL) {
+ TALLOC_FREE(ent->session_info);
+ ent->vuid = UID_FIELD_INVALID;
+ return false;
+ }
+ } else {
+ ent->user_ev_ctx = smbd_impersonate_conn_vuid_create(
+ conn->sconn->raw_ev_ctx, conn, vuid);
+ if (ent->user_ev_ctx == NULL) {
+ TALLOC_FREE(ent->session_info);
+ ent->vuid = UID_FIELD_INVALID;
+ return false;
+ }
+ }
/*
* It's actually OK to call check_user_ok() with
--
2.17.1
From c2473b7b40ecf8bebb172f2add7f982a02534dbf Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 11 May 2012 15:51:42 +0200
Subject: [PATCH 34/37] TODO debug at level 11? smbd: implement
smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers
This makes sure we're doing the correct impersonation for async
requests, which is a requirement to start adding path based
async SMB_VFS calls.
---
source3/smbd/uid.c | 697 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 676 insertions(+), 21 deletions(-)
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 6f586e03a5aa..3872d3866db2 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -970,52 +970,707 @@ uint64_t get_current_vuid(connection_struct *conn)
return current_user.vuid;
}
+struct smbd_impersonate_conn_vuid_state {
+ struct connection_struct *conn;
+ uint64_t vuid;
+};
+
+static bool smbd_impersonate_conn_vuid_before_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct smbd_impersonate_conn_vuid_state *state =
+ talloc_get_type_abort(private_data,
+ struct smbd_impersonate_conn_vuid_state);
+ bool ok;
+
+ ok = change_to_user(state->conn, state->vuid);
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
+static void smbd_impersonate_conn_vuid_after_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct smbd_impersonate_conn_vuid_state *state =
+ talloc_get_type_abort(private_data,
+ struct smbd_impersonate_conn_vuid_state);
+ const struct smb_filename root_fname = {
+ .base_name = discard_const_p(char, "/"),
+ };
+
+ vfs_ChDir(state->conn, &root_fname);
+ change_to_root_user();
+}
+
+static void smbd_impersonate_conn_vuid_before_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_vuid_after_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer change_to_root_user() */
+}
+
+static void smbd_impersonate_conn_vuid_before_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_vuid_after_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer change_to_root_user() */
+}
+
+static void smbd_impersonate_conn_vuid_before_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_vuid_after_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer unbecome_user() */
+}
+
+static void smbd_impersonate_conn_vuid_before_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_vuid_after_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer change_to_root_user() */
+}
+
+static const struct tevent_wrapper_ops smbd_impersonate_conn_vuid_ops = {
+ .name = "smbd_impersonate_conn_vuid",
+ .before_use = smbd_impersonate_conn_vuid_before_use,
+ .after_use = smbd_impersonate_conn_vuid_after_use,
+ .before_fd_handler = smbd_impersonate_conn_vuid_before_fd_handler,
+ .after_fd_handler = smbd_impersonate_conn_vuid_after_fd_handler,
+ .before_timer_handler = smbd_impersonate_conn_vuid_before_timer_handler,
+ .after_timer_handler = smbd_impersonate_conn_vuid_after_timer_handler,
+ .before_immediate_handler = smbd_impersonate_conn_vuid_before_immediate_handler,
+ .after_immediate_handler = smbd_impersonate_conn_vuid_after_immediate_handler,
+ .before_signal_handler = smbd_impersonate_conn_vuid_before_signal_handler,
+ .after_signal_handler = smbd_impersonate_conn_vuid_after_signal_handler,
+};
+
struct tevent_context *smbd_impersonate_conn_vuid_create(
struct tevent_context *main_ev,
struct connection_struct *conn,
uint64_t vuid)
{
- struct tevent_context *wrap_ev = NULL;
+ struct tevent_context *ev = NULL;
+ struct smbd_impersonate_conn_vuid_state *state = NULL;
+
+ ev = tevent_context_wrapper_create(main_ev,
+ conn,
+ &smbd_impersonate_conn_vuid_ops,
+ &state,
+ struct smbd_impersonate_conn_vuid_state);
+ if (ev == NULL) {
+ return NULL;
+ }
+ state->conn = conn;
+ state->vuid = vuid;
- wrap_ev = smbd_impersonate_debug_create(main_ev,
- "conn_vuid",
- DBGLVL_DEBUG);
+ return ev;
+}
- return wrap_ev;
+struct smbd_impersonate_conn_sess_state {
+ struct connection_struct *conn;
+ struct auth_session_info *session_info;
+};
+
+static bool smbd_impersonate_conn_sess_before_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct smbd_impersonate_conn_sess_state *state =
+ talloc_get_type_abort(private_data,
+ struct smbd_impersonate_conn_sess_state);
+ bool ok;
+
+ ok = change_to_user_by_session(state->conn, state->session_info);
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
+static void smbd_impersonate_conn_sess_after_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ struct smbd_impersonate_conn_sess_state *state =
+ talloc_get_type_abort(private_data,
+ struct smbd_impersonate_conn_sess_state);
+ const struct smb_filename root_fname = {
+ .base_name = discard_const_p(char, "/"),
+ };
+
+ vfs_ChDir(state->conn, &root_fname);
+ change_to_root_user();
}
+static void smbd_impersonate_conn_sess_before_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_sess_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_sess_after_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer change_to_root_user() */
+}
+
+static void smbd_impersonate_conn_sess_before_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_sess_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_sess_after_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer change_to_root_user() */
+}
+
+static void smbd_impersonate_conn_sess_before_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_sess_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_sess_after_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer unbecome_user() */
+}
+
+static void smbd_impersonate_conn_sess_before_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_conn_sess_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_conn_sess_after_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ /* be lazy and defer change_to_root_user() */
+}
+
+static const struct tevent_wrapper_ops smbd_impersonate_conn_sess_ops = {
+ .name = "smbd_impersonate_conn_sess",
+ .before_use = smbd_impersonate_conn_sess_before_use,
+ .after_use = smbd_impersonate_conn_sess_after_use,
+ .before_fd_handler = smbd_impersonate_conn_sess_before_fd_handler,
+ .after_fd_handler = smbd_impersonate_conn_sess_after_fd_handler,
+ .before_timer_handler = smbd_impersonate_conn_sess_before_timer_handler,
+ .after_timer_handler = smbd_impersonate_conn_sess_after_timer_handler,
+ .before_immediate_handler = smbd_impersonate_conn_sess_before_immediate_handler,
+ .after_immediate_handler = smbd_impersonate_conn_sess_after_immediate_handler,
+ .before_signal_handler = smbd_impersonate_conn_sess_before_signal_handler,
+ .after_signal_handler = smbd_impersonate_conn_sess_after_signal_handler,
+};
+
struct tevent_context *smbd_impersonate_conn_sess_create(
struct tevent_context *main_ev,
struct connection_struct *conn,
struct auth_session_info *session_info)
{
- struct tevent_context *wrap_ev = NULL;
+ struct tevent_context *ev = NULL;
+ struct smbd_impersonate_conn_sess_state *state = NULL;
+
+ ev = tevent_context_wrapper_create(main_ev,
+ conn,
+ &smbd_impersonate_conn_sess_ops,
+ &state,
+ struct smbd_impersonate_conn_sess_state);
+ if (ev == NULL) {
+ return NULL;
+ }
+ state->conn = conn;
+ state->session_info = session_info;
- wrap_ev = smbd_impersonate_debug_create(main_ev,
- "conn_sess",
- DBGLVL_DEBUG);
+ return ev;
+}
- return wrap_ev;
+struct smbd_impersonate_root_state {
+ uint8_t _dummy;
+};
+
+static bool smbd_impersonate_root_before_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ become_root();
+ return true;
+}
+
+static void smbd_impersonate_root_after_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ unbecome_root();
+}
+
+static void smbd_impersonate_root_before_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_root_after_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_root_before_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_root_after_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_root_before_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_root_after_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
}
+static void smbd_impersonate_root_before_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_root_after_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static const struct tevent_wrapper_ops smbd_impersonate_root_ops = {
+ .name = "smbd_impersonate_root",
+ .before_use = smbd_impersonate_root_before_use,
+ .after_use = smbd_impersonate_root_after_use,
+ .before_fd_handler = smbd_impersonate_root_before_fd_handler,
+ .after_fd_handler = smbd_impersonate_root_after_fd_handler,
+ .before_timer_handler = smbd_impersonate_root_before_timer_handler,
+ .after_timer_handler = smbd_impersonate_root_after_timer_handler,
+ .before_immediate_handler = smbd_impersonate_root_before_immediate_handler,
+ .after_immediate_handler = smbd_impersonate_root_after_immediate_handler,
+ .before_signal_handler = smbd_impersonate_root_before_signal_handler,
+ .after_signal_handler = smbd_impersonate_root_after_signal_handler,
+};
+
struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev)
{
- struct tevent_context *wrap_ev = NULL;
+ struct tevent_context *ev = NULL;
+ struct smbd_impersonate_root_state *state = NULL;
+
+ ev = tevent_context_wrapper_create(main_ev,
+ main_ev,
+ &smbd_impersonate_root_ops,
+ &state,
+ struct smbd_impersonate_root_state);
+ if (ev == NULL) {
+ return NULL;
+ }
- wrap_ev = smbd_impersonate_debug_create(main_ev,
- "root",
- DBGLVL_DEBUG);
+ return ev;
+}
- return wrap_ev;
+struct smbd_impersonate_guest_state {
+ uint8_t _dummy;
+};
+
+static bool smbd_impersonate_guest_before_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
+{
+ return become_guest();
}
-struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev)
+static void smbd_impersonate_guest_after_use(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ const char *location)
{
- struct tevent_context *wrap_ev = NULL;
+ unbecome_guest();
+}
+
+static void smbd_impersonate_guest_before_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
- wrap_ev = smbd_impersonate_debug_create(main_ev,
- "guest",
- DBGLVL_DEBUG);
+ ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_guest_before_use() - failed");
+ return;
+ }
+}
- return wrap_ev;
+static void smbd_impersonate_guest_after_fd_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_guest_before_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_guest_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_guest_after_timer_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_timer *te,
+ struct timeval requested_time,
+ struct timeval trigger_time,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_guest_before_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_guest_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_guest_after_immediate_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_immediate *im,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static void smbd_impersonate_guest_before_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ bool ok;
+
+ ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
+ main_ev, location);
+ if (!ok) {
+ smb_panic("smbd_impersonate_guest_before_use() - failed");
+ return;
+ }
+}
+
+static void smbd_impersonate_guest_after_signal_handler(struct tevent_context *wrap_ev,
+ void *private_data,
+ struct tevent_context *main_ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ const char *handler_name,
+ const char *location)
+{
+ smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
+}
+
+static const struct tevent_wrapper_ops smbd_impersonate_guest_ops = {
+ .name = "smbd_impersonate_guest",
+ .before_use = smbd_impersonate_guest_before_use,
+ .after_use = smbd_impersonate_guest_after_use,
+ .before_fd_handler = smbd_impersonate_guest_before_fd_handler,
+ .after_fd_handler = smbd_impersonate_guest_after_fd_handler,
+ .before_timer_handler = smbd_impersonate_guest_before_timer_handler,
+ .after_timer_handler = smbd_impersonate_guest_after_timer_handler,
+ .before_immediate_handler = smbd_impersonate_guest_before_immediate_handler,
+ .after_immediate_handler = smbd_impersonate_guest_after_immediate_handler,
+ .before_signal_handler = smbd_impersonate_guest_before_signal_handler,
+ .after_signal_handler = smbd_impersonate_guest_after_signal_handler,
+};
+
+struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev)
+{
+ struct tevent_context *ev = NULL;
+ struct smbd_impersonate_guest_state *state = NULL;
+
+ ev = tevent_context_wrapper_create(main_ev,
+ main_ev,
+ &smbd_impersonate_guest_ops,
+ &state,
+ struct smbd_impersonate_guest_state);
+ if (ev == NULL) {
+ return NULL;
+ }
+
+ return ev;
}
--
2.17.1
From 848da8502547ac86897007e94d7c7957b3819753 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Sun, 17 Jun 2018 11:50:08 +0200
Subject: [PATCH 35/37] FIXUP: add debuggging to impersonation
---
source3/smbd/uid.c | 178 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 178 insertions(+)
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 3872d3866db2..477da82fd25b 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -985,11 +985,22 @@ static bool smbd_impersonate_conn_vuid_before_use(struct tevent_context *wrap_ev
struct smbd_impersonate_conn_vuid_state);
bool ok;
+ DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
+ "old uid[%ju] old gid[%ju] vuid[%ju] cwd[%s]\n",
+ __func__, wrap_ev, main_ev, location,
+ (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ (uintmax_t)state->vuid, state->conn->cwd_fname->base_name));
+
ok = change_to_user(state->conn, state->vuid);
if (!ok) {
return false;
}
+ DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
+ __func__, state->conn->session_info->unix_info->unix_name,
+ (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ state->conn->cwd_fname->base_name));
+
return true;
}
@@ -1005,6 +1016,12 @@ static void smbd_impersonate_conn_vuid_after_use(struct tevent_context *wrap_ev,
.base_name = discard_const_p(char, "/"),
};
+ DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] "
+ "location[%s]\n",
+ __func__, state->conn->session_info->unix_info->unix_name,
+ (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ state->conn->cwd_fname->base_name, location));
+
vfs_ChDir(state->conn, &root_fname);
change_to_root_user();
}
@@ -1019,6 +1036,9 @@ static void smbd_impersonate_conn_vuid_before_fd_handler(struct tevent_context *
{
bool ok;
+ DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
+ __func__, fde, (uintmax_t)flags, handler_name, location));
+
ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1035,6 +1055,9 @@ static void smbd_impersonate_conn_vuid_after_fd_handler(struct tevent_context *w
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
+ __func__, fde, handler_name, location));
+
/* be lazy and defer change_to_root_user() */
}
@@ -1048,6 +1071,15 @@ static void smbd_impersonate_conn_vuid_before_timer_handler(struct tevent_contex
const char *location)
{
bool ok;
+ struct timeval_buf requested_buf;
+ struct timeval_buf trigger_buf;
+
+ DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
+ "handler_name[%s] location[%s]\n",
+ __func__, te,
+ timeval_str_buf(&requested_time, true, true, &requested_buf),
+ timeval_str_buf(&trigger_time, true, true, &trigger_buf),
+ handler_name, location));
ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
main_ev, location);
@@ -1066,6 +1098,9 @@ static void smbd_impersonate_conn_vuid_after_timer_handler(struct tevent_context
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
+ __func__, te, handler_name, location));
+
/* be lazy and defer change_to_root_user() */
}
@@ -1078,6 +1113,9 @@ static void smbd_impersonate_conn_vuid_before_immediate_handler(struct tevent_co
{
bool ok;
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1093,6 +1131,9 @@ static void smbd_impersonate_conn_vuid_after_immediate_handler(struct tevent_con
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
/* be lazy and defer unbecome_user() */
}
@@ -1108,6 +1149,10 @@ static void smbd_impersonate_conn_vuid_before_signal_handler(struct tevent_conte
{
bool ok;
+ DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
+ "handler_name[%s] location[%s]\n",
+ __func__, se, signum, count, siginfo, handler_name, location));
+
ok = smbd_impersonate_conn_vuid_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1126,6 +1171,9 @@ static void smbd_impersonate_conn_vuid_after_signal_handler(struct tevent_contex
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
+ __func__, se, handler_name, location));
+
/* be lazy and defer change_to_root_user() */
}
@@ -1180,11 +1228,23 @@ static bool smbd_impersonate_conn_sess_before_use(struct tevent_context *wrap_ev
struct smbd_impersonate_conn_sess_state);
bool ok;
+ DEBUG(11,("%s: impersonating user[%s] wrap_ev[%p] main_ev[%p] location[%s] "
+ "old uid[%ju] old gid[%ju] cwd[%s]\n",
+ __func__, state->session_info->unix_info->unix_name,
+ wrap_ev, main_ev, location,
+ (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ state->conn->cwd_fname->base_name));
+
ok = change_to_user_by_session(state->conn, state->session_info);
if (!ok) {
return false;
}
+ DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
+ __func__, state->conn->session_info->unix_info->unix_name,
+ (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ state->conn->cwd_fname->base_name));
+
return true;
}
@@ -1200,6 +1260,12 @@ static void smbd_impersonate_conn_sess_after_use(struct tevent_context *wrap_ev,
.base_name = discard_const_p(char, "/"),
};
+ DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] "
+ "location[%s]\n",
+ __func__, state->session_info->unix_info->unix_name,
+ (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ state->conn->cwd_fname->base_name, location));
+
vfs_ChDir(state->conn, &root_fname);
change_to_root_user();
}
@@ -1214,6 +1280,9 @@ static void smbd_impersonate_conn_sess_before_fd_handler(struct tevent_context *
{
bool ok;
+ DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
+ __func__, fde, (uintmax_t)flags, handler_name, location));
+
ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1230,6 +1299,9 @@ static void smbd_impersonate_conn_sess_after_fd_handler(struct tevent_context *w
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
+ __func__, fde, handler_name, location));
+
/* be lazy and defer change_to_root_user() */
}
@@ -1243,6 +1315,15 @@ static void smbd_impersonate_conn_sess_before_timer_handler(struct tevent_contex
const char *location)
{
bool ok;
+ struct timeval_buf requested_buf;
+ struct timeval_buf trigger_buf;
+
+ DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
+ "handler_name[%s] location[%s]\n",
+ __func__, te,
+ timeval_str_buf(&requested_time, true, true, &requested_buf),
+ timeval_str_buf(&trigger_time, true, true, &trigger_buf),
+ handler_name, location));
ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
main_ev, location);
@@ -1261,6 +1342,9 @@ static void smbd_impersonate_conn_sess_after_timer_handler(struct tevent_context
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
+ __func__, te, handler_name, location));
+
/* be lazy and defer change_to_root_user() */
}
@@ -1273,6 +1357,9 @@ static void smbd_impersonate_conn_sess_before_immediate_handler(struct tevent_co
{
bool ok;
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1288,6 +1375,9 @@ static void smbd_impersonate_conn_sess_after_immediate_handler(struct tevent_con
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
/* be lazy and defer unbecome_user() */
}
@@ -1303,6 +1393,10 @@ static void smbd_impersonate_conn_sess_before_signal_handler(struct tevent_conte
{
bool ok;
+ DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
+ "handler_name[%s] location[%s]\n",
+ __func__, se, signum, count, siginfo, handler_name, location));
+
ok = smbd_impersonate_conn_sess_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1321,6 +1415,9 @@ static void smbd_impersonate_conn_sess_after_signal_handler(struct tevent_contex
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
+ __func__, se, handler_name, location));
+
/* be lazy and defer change_to_root_user() */
}
@@ -1369,6 +1466,11 @@ static bool smbd_impersonate_root_before_use(struct tevent_context *wrap_ev,
struct tevent_context *main_ev,
const char *location)
{
+ DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
+ "uid[%ju] gid[%ju]\n",
+ __func__, wrap_ev, main_ev, location,
+ (uintmax_t)geteuid(), (uintmax_t)getegid()));
+
become_root();
return true;
}
@@ -1379,6 +1481,10 @@ static void smbd_impersonate_root_after_use(struct tevent_context *wrap_ev,
const char *location)
{
unbecome_root();
+
+ DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n",
+ __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ location));
}
static void smbd_impersonate_root_before_fd_handler(struct tevent_context *wrap_ev,
@@ -1389,6 +1495,9 @@ static void smbd_impersonate_root_before_fd_handler(struct tevent_context *wrap_
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
+ __func__, fde, (uintmax_t)flags, handler_name, location));
+
smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
}
@@ -1400,6 +1509,9 @@ static void smbd_impersonate_root_after_fd_handler(struct tevent_context *wrap_e
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
+ __func__, fde, handler_name, location));
+
smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1412,6 +1524,16 @@ static void smbd_impersonate_root_before_timer_handler(struct tevent_context *wr
const char *handler_name,
const char *location)
{
+ struct timeval_buf requested_buf;
+ struct timeval_buf trigger_buf;
+
+ DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
+ "handler_name[%s] location[%s]\n",
+ __func__, te,
+ timeval_str_buf(&requested_time, true, true, &requested_buf),
+ timeval_str_buf(&trigger_time, true, true, &trigger_buf),
+ handler_name, location));
+
smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
}
@@ -1424,6 +1546,9 @@ static void smbd_impersonate_root_after_timer_handler(struct tevent_context *wra
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
+ __func__, te, handler_name, location));
+
smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1434,6 +1559,9 @@ static void smbd_impersonate_root_before_immediate_handler(struct tevent_context
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
}
@@ -1444,6 +1572,9 @@ static void smbd_impersonate_root_after_immediate_handler(struct tevent_context
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1457,6 +1588,10 @@ static void smbd_impersonate_root_before_signal_handler(struct tevent_context *w
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
+ "handler_name[%s] location[%s]\n",
+ __func__, se, signum, count, siginfo, handler_name, location));
+
smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
}
@@ -1470,6 +1605,9 @@ static void smbd_impersonate_root_after_signal_handler(struct tevent_context *wr
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
+ __func__, se, handler_name, location));
+
smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1513,6 +1651,11 @@ static bool smbd_impersonate_guest_before_use(struct tevent_context *wrap_ev,
struct tevent_context *main_ev,
const char *location)
{
+ DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
+ "uid[%ju] gid[%ju]\n",
+ __func__, wrap_ev, main_ev, location,
+ (uintmax_t)geteuid(), (uintmax_t)getegid()));
+
return become_guest();
}
@@ -1522,6 +1665,10 @@ static void smbd_impersonate_guest_after_use(struct tevent_context *wrap_ev,
const char *location)
{
unbecome_guest();
+
+ DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n",
+ __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(),
+ location));
}
static void smbd_impersonate_guest_before_fd_handler(struct tevent_context *wrap_ev,
@@ -1534,6 +1681,9 @@ static void smbd_impersonate_guest_before_fd_handler(struct tevent_context *wrap
{
bool ok;
+ DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
+ __func__, fde, (uintmax_t)flags, handler_name, location));
+
ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1550,6 +1700,9 @@ static void smbd_impersonate_guest_after_fd_handler(struct tevent_context *wrap_
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
+ __func__, fde, handler_name, location));
+
smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1563,6 +1716,15 @@ static void smbd_impersonate_guest_before_timer_handler(struct tevent_context *w
const char *location)
{
bool ok;
+ struct timeval_buf requested_buf;
+ struct timeval_buf trigger_buf;
+
+ DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
+ "handler_name[%s] location[%s]\n",
+ __func__, te,
+ timeval_str_buf(&requested_time, true, true, &requested_buf),
+ timeval_str_buf(&trigger_time, true, true, &trigger_buf),
+ handler_name, location));
ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
main_ev, location);
@@ -1581,6 +1743,9 @@ static void smbd_impersonate_guest_after_timer_handler(struct tevent_context *wr
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
+ __func__, te, handler_name, location));
+
smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1593,6 +1758,9 @@ static void smbd_impersonate_guest_before_immediate_handler(struct tevent_contex
{
bool ok;
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1608,6 +1776,9 @@ static void smbd_impersonate_guest_after_immediate_handler(struct tevent_context
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
+ __func__, im, handler_name, location));
+
smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
}
@@ -1623,6 +1794,10 @@ static void smbd_impersonate_guest_before_signal_handler(struct tevent_context *
{
bool ok;
+ DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
+ "handler_name[%s] location[%s]\n",
+ __func__, se, signum, count, siginfo, handler_name, location));
+
ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
main_ev, location);
if (!ok) {
@@ -1641,6 +1816,9 @@ static void smbd_impersonate_guest_after_signal_handler(struct tevent_context *w
const char *handler_name,
const char *location)
{
+ DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
+ __func__, se, handler_name, location));
+
smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
}
--
2.17.1
From 44c3d12ec7ea76bbca99a632b27a2723bcd46b53 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 18 Apr 2018 14:29:52 +0200
Subject: [PATCH 36/37] smbd: remove unused change_to_root_user() from
smbd_sig_hup_handler()
This is handled by using the root_ev_ctx in order to register
the signal event.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/smbd/process.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index dc95af17393b..0a4106257f58 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -998,7 +998,6 @@ static void smbd_sig_hup_handler(struct tevent_context *ev,
talloc_get_type_abort(private_data,
struct smbd_server_connection);
- change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(sconn, conn_snum_used, false);
}
--
2.17.1
From f0a1a64ee1769f7c59369624ff33242fd39830ed Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow at samba.org>
Date: Wed, 23 May 2018 16:28:48 +0200
Subject: [PATCH 37/37] smbd: remove unused change_to_root_user() from
brl_timeout_fn()
This is handled by using the root_ev_ctx in order to register
the timer event.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
source3/smbd/blocking.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index c281aae619de..095c9edeacc0 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -47,9 +47,6 @@ void brl_timeout_fn(struct tevent_context *event_ctx,
TALLOC_FREE(sconn->smb1.locks.brl_timeout);
}
- change_to_root_user(); /* TODO: Possibly run all timed events as
- * root */
-
process_blocking_lock_queue(sconn);
}
--
2.17.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20180617/717ddd6c/signature-0001.sig>
More information about the samba-technical
mailing list