ctdb-daemon: Only consider client ID for local database attach
authorMartin Schwenke <martin@meltin.net>
Tue, 26 Jun 2018 10:12:23 +0000 (20:12 +1000)
committerMartin Schwenke <martins@samba.org>
Mon, 2 Jul 2018 06:51:22 +0000 (08:51 +0200)
The comment immediately above this code says "don't allow local
clients to attach" and then looks up the client ID regardless of
whether the request is local or remote.

This means that an intentional remote attach from a client will not
work correctly.  No real client should ever do that since clients
attach so they an access databases locally.  Perhaps some sanity
checks should be added.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13500

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/include/ctdb_private.h
ctdb/server/ctdb_control.c
ctdb/server/ctdb_ltdb_server.c

index 39e32540e00b0c99adbe1fe9c6e17b995c26f99e..b3d2e146dcf19490dbf4174d71ac93cf2c73df34 100644 (file)
@@ -725,9 +725,12 @@ int ctdb_set_db_readonly(struct ctdb_context *ctdb,
 
 int ctdb_process_deferred_attach(struct ctdb_context *ctdb);
 
 
 int ctdb_process_deferred_attach(struct ctdb_context *ctdb);
 
-int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
+int32_t ctdb_control_db_attach(struct ctdb_context *ctdb,
+                              TDB_DATA indata,
                               TDB_DATA *outdata,
                               TDB_DATA *outdata,
-                              uint8_t db_flags, uint32_t client_id,
+                              uint8_t db_flags,
+                              uint32_t srcnode,
+                              uint32_t client_id,
                               struct ctdb_req_control_old *c,
                               bool *async_reply);
 int32_t ctdb_control_db_detach(struct ctdb_context *ctdb, TDB_DATA indata,
                               struct ctdb_req_control_old *c,
                               bool *async_reply);
 int32_t ctdb_control_db_detach(struct ctdb_context *ctdb, TDB_DATA indata,
index b812980ddf9de27a207b0c4bde7df5970d756c6d..848010e231087c2c00ac27ab0956ca4030c64dad 100644 (file)
@@ -267,18 +267,34 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
        }
 
        case CTDB_CONTROL_DB_ATTACH:
        }
 
        case CTDB_CONTROL_DB_ATTACH:
-         return ctdb_control_db_attach(ctdb, indata, outdata, 0, client_id,
-                                       c, async_reply);
+         return ctdb_control_db_attach(ctdb,
+                                       indata,
+                                       outdata,
+                                       0,
+                                       srcnode,
+                                       client_id,
+                                       c,
+                                       async_reply);
 
        case CTDB_CONTROL_DB_ATTACH_PERSISTENT:
 
        case CTDB_CONTROL_DB_ATTACH_PERSISTENT:
-         return ctdb_control_db_attach(ctdb, indata, outdata,
-                                       CTDB_DB_FLAGS_PERSISTENT, client_id,
-                                       c, async_reply);
+         return ctdb_control_db_attach(ctdb,
+                                       indata,
+                                       outdata,
+                                       CTDB_DB_FLAGS_PERSISTENT,
+                                       srcnode,
+                                       client_id,
+                                       c,
+                                       async_reply);
 
        case CTDB_CONTROL_DB_ATTACH_REPLICATED:
 
        case CTDB_CONTROL_DB_ATTACH_REPLICATED:
-         return ctdb_control_db_attach(ctdb, indata, outdata,
-                                       CTDB_DB_FLAGS_REPLICATED, client_id,
-                                       c, async_reply);
+         return ctdb_control_db_attach(ctdb,
+                                       indata,
+                                       outdata,
+                                       CTDB_DB_FLAGS_REPLICATED,
+                                       srcnode,
+                                       client_id,
+                                       c,
+                                       async_reply);
 
        case CTDB_CONTROL_SET_CALL:
                return control_not_implemented("SET_CALL", NULL);
 
        case CTDB_CONTROL_SET_CALL:
                return control_not_implemented("SET_CALL", NULL);
index e5148c81d881e73d00adb4ca5a326108e7d8c97b..f3f7df97ac67a5aeb52ddf48998435c817df13f6 100644 (file)
@@ -1105,9 +1105,12 @@ int ctdb_process_deferred_attach(struct ctdb_context *ctdb)
 /*
   a client has asked to attach a new database
  */
 /*
   a client has asked to attach a new database
  */
-int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
+int32_t ctdb_control_db_attach(struct ctdb_context *ctdb,
+                              TDB_DATA indata,
                               TDB_DATA *outdata,
                               TDB_DATA *outdata,
-                              uint8_t db_flags, uint32_t client_id,
+                              uint8_t db_flags,
+                              uint32_t srcnode,
+                              uint32_t client_id,
                               struct ctdb_req_control_old *c,
                               bool *async_reply)
 {
                               struct ctdb_req_control_old *c,
                               bool *async_reply)
 {
@@ -1128,7 +1131,7 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
         * allow all attach from the network since these are always from remote
         * recovery daemons.
         */
         * allow all attach from the network since these are always from remote
         * recovery daemons.
         */
-       if (client_id != 0) {
+       if (srcnode == ctdb->pnn && client_id != 0) {
                client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
        }
        if (client != NULL) {
                client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
        }
        if (client != NULL) {