]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:g_lock: add callback function to g_lock_lock_send()
authorStefan Metzmacher <metze@samba.org>
Sun, 28 Aug 2022 10:38:24 +0000 (12:38 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 20 Sep 2022 00:34:35 +0000 (00:34 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
libcli/auth/netlogon_creds_cli.c
source3/include/g_lock.h
source3/lib/g_lock.c
source3/torture/test_g_lock.c

index 716a565128ddcdc815adc83f9697ac5acdb0aa26..fec192bdae2c8bbf8ef88e62589c7533e4a2371c 100644 (file)
@@ -813,7 +813,8 @@ struct tevent_req *netlogon_creds_cli_lock_send(TALLOC_CTX *mem_ctx,
        subreq = g_lock_lock_send(state, ev,
                                  context->db.g_ctx,
                                  string_term_tdb_data(context->db.key_name),
-                                 G_LOCK_WRITE);
+                                 G_LOCK_WRITE,
+                                 NULL, NULL);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -1027,7 +1028,8 @@ struct tevent_req *netlogon_creds_cli_lck_send(
        subreq = g_lock_lock_send(state, ev,
                                  context->db.g_ctx,
                                  string_term_tdb_data(context->db.key_name),
-                                 gtype);
+                                 gtype,
+                                 NULL, NULL);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
index e3dd1b5c076bbfa33a0b17f93df12386af6d6506..c96431346a6e60bab2532af595f17b3b189e2730 100644 (file)
@@ -74,7 +74,9 @@ struct tevent_req *g_lock_lock_send(TALLOC_CTX *mem_ctx,
                                    struct tevent_context *ev,
                                    struct g_lock_ctx *ctx,
                                    TDB_DATA key,
-                                   enum g_lock_type type);
+                                   enum g_lock_type type,
+                                   g_lock_lock_cb_fn_t cb_fn,
+                                   void *cb_private);
 NTSTATUS g_lock_lock_recv(struct tevent_req *req);
 NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
                     enum g_lock_type lock_type, struct timeval timeout);
index 7868a69a3371a3c5984dda0012991056b5bea30a..a22f9dcad0667338a91a14794b458dac75e1f9eb 100644 (file)
@@ -990,7 +990,9 @@ struct tevent_req *g_lock_lock_send(TALLOC_CTX *mem_ctx,
                                    struct tevent_context *ev,
                                    struct g_lock_ctx *ctx,
                                    TDB_DATA key,
-                                   enum g_lock_type type)
+                                   enum g_lock_type type,
+                                   g_lock_lock_cb_fn_t cb_fn,
+                                   void *cb_private)
 {
        struct tevent_req *req;
        struct g_lock_lock_state *state;
@@ -1008,11 +1010,24 @@ struct tevent_req *g_lock_lock_send(TALLOC_CTX *mem_ctx,
        state->ctx = ctx;
        state->key = key;
        state->type = type;
+       state->cb_fn = cb_fn;
+       state->cb_private = cb_private;
 
        fn_state = (struct g_lock_lock_fn_state) {
                .req_state = state,
        };
 
+       /*
+        * We allow a cn_fn only for G_LOCK_WRITE for now.
+        *
+        * It's all we currently need and it makes a few things
+        * easier to implement.
+        */
+       if (unlikely(cb_fn != NULL && type != G_LOCK_WRITE)) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_6);
+               return tevent_req_post(req, ev);
+       }
+
        status = dbwrap_do_locked(ctx->db, key, g_lock_lock_fn, &fn_state);
        if (tevent_req_nterror(req, status)) {
                DBG_DEBUG("dbwrap_do_locked failed: %s\n",
@@ -1113,6 +1128,9 @@ NTSTATUS g_lock_lock_recv(struct tevent_req *req)
        NTSTATUS status;
 
        if (tevent_req_is_nterror(req, &status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_WAS_UNLOCKED)) {
+                       return NT_STATUS_OK;
+               }
                return status;
        }
 
@@ -1278,7 +1296,7 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
        if (ev == NULL) {
                goto fail;
        }
-       req = g_lock_lock_send(frame, ev, ctx, key, type);
+       req = g_lock_lock_send(frame, ev, ctx, key, type, cb_fn, cb_private);
        if (req == NULL) {
                goto fail;
        }
index 5113339396091e9e67abcbb710a232171d225ac8..57899e9e33787e2599afe54e991264a3d952d6de 100644 (file)
@@ -526,7 +526,7 @@ bool run_g_lock4(int dummy)
                goto fail;
        }
 
-       req = g_lock_lock_send(ev, ev, ctx, key, G_LOCK_WRITE);
+       req = g_lock_lock_send(ev, ev, ctx, key, G_LOCK_WRITE, NULL, NULL);
        if (req == NULL) {
                fprintf(stderr, "g_lock_lock send failed\n");
                goto fail;
@@ -657,7 +657,7 @@ bool run_g_lock4a(int dummy)
                goto fail;
        }
 
-       req = g_lock_lock_send(ev, ev, ctx, key, G_LOCK_WRITE);
+       req = g_lock_lock_send(ev, ev, ctx, key, G_LOCK_WRITE, NULL, NULL);
        if (req == NULL) {
                fprintf(stderr, "g_lock_lock send failed\n");
                goto fail;
@@ -1135,7 +1135,8 @@ bool run_g_lock7(int dummy)
                        ev,
                        ctx,
                        key,
-                       G_LOCK_UPGRADE);
+                       G_LOCK_UPGRADE,
+                       NULL, NULL);
                if (req == NULL) {
                        fprintf(stderr, "g_lock_lock_send(UPGRADE) failed\n");
                        exit(1);