summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2021-03-23 15:13:55 +0100
committerJeremy Allison <jra@samba.org>2021-03-24 20:31:30 +0000
commit2e608468595d748f506a059811231c5572976157 (patch)
treee90433705392bf6b830fc757bdf3a024d0eb6909 /source3/winbindd
parent4288319770bc1bde28b1e9ac4bb287e29853378d (diff)
downloadsamba-2e608468595d748f506a059811231c5572976157.tar.gz
winbindd: Fix a startup race with allocate_gid
If you try to allocate a GID before winbind is fully set up, idmap_child_handle() is still NULL. Add the required wb_parent_idmap_setup_send()/recv() to allocate_gid(). Bug: https://bugzilla.samba.org/show_bug.cgi?id=14678 RN: Fix a crash in winbind when allocate-gid is called early Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/winbindd_allocate_gid.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/source3/winbindd/winbindd_allocate_gid.c b/source3/winbindd/winbindd_allocate_gid.c
index 85aa1369473..2841d96e5f9 100644
--- a/source3/winbindd/winbindd_allocate_gid.c
+++ b/source3/winbindd/winbindd_allocate_gid.c
@@ -22,9 +22,11 @@
#include "librpc/gen_ndr/ndr_winbind_c.h"
struct winbindd_allocate_gid_state {
+ struct tevent_context *ev;
uint64_t gid;
};
+static void winbindd_allocate_gid_initialized(struct tevent_req *subreq);
static void winbindd_allocate_gid_done(struct tevent_req *subreq);
struct tevent_req *winbindd_allocate_gid_send(TALLOC_CTX *mem_ctx,
@@ -34,25 +36,56 @@ struct tevent_req *winbindd_allocate_gid_send(TALLOC_CTX *mem_ctx,
{
struct tevent_req *req, *subreq;
struct winbindd_allocate_gid_state *state;
- struct dcerpc_binding_handle *child_binding_handle = NULL;
req = tevent_req_create(mem_ctx, &state,
struct winbindd_allocate_gid_state);
if (req == NULL) {
return NULL;
}
+ state->ev = ev;
DEBUG(3, ("allocate_gid\n"));
+ subreq = wb_parent_idmap_setup_send(state, ev);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(
+ subreq, winbindd_allocate_gid_initialized, req);
+ return req;
+}
+
+static void winbindd_allocate_gid_initialized(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct winbindd_allocate_gid_state *state = tevent_req_data(
+ req, struct winbindd_allocate_gid_state);
+ NTSTATUS status;
+ const struct wb_parent_idmap_config *cfg = NULL;
+ struct dcerpc_binding_handle *child_binding_handle = NULL;
+
+ status = wb_parent_idmap_setup_recv(subreq, &cfg);
+ TALLOC_FREE(subreq);
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+ if (cfg->num_doms == 0) {
+ /*
+ * idmap_tdb also returns UNSUCCESSFUL if a range is full
+ */
+ tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
+ return;
+ }
+
child_binding_handle = idmap_child_handle();
- subreq = dcerpc_wbint_AllocateGid_send(state, ev, child_binding_handle,
- &state->gid);
+ subreq = dcerpc_wbint_AllocateGid_send(
+ state, state->ev, child_binding_handle, &state->gid);
if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
+ return;
}
tevent_req_set_callback(subreq, winbindd_allocate_gid_done, req);
- return req;
}
static void winbindd_allocate_gid_done(struct tevent_req *subreq)