s3:lib/ctdbd_conn: let release_ip_handler return bool
authorStefan Metzmacher <metze@samba.org>
Mon, 17 Feb 2014 10:57:52 +0000 (11:57 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 21 Feb 2014 11:48:31 +0000 (12:48 +0100)
If it returns true the passed ip address matched and we
let a nested ctdb operation fail with NT_STATUS_ADDRESS_CLOSED.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/include/ctdbd_conn.h
source3/lib/ctdbd_conn.c
source3/smbd/process.c

index ce5c8ba007a65e954aea620329debf37d4a79960..0f85229e9c44bbf721112c740e5c452a725bee75 100644 (file)
@@ -76,7 +76,7 @@ NTSTATUS ctdbd_traverse(uint32_t db_id,
 NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
                            const struct sockaddr_storage *server,
                            const struct sockaddr_storage *client,
-                           void (*release_ip_handler)(const char *ip_addr,
+                           bool (*release_ip_handler)(const char *ip_addr,
                                                       void *private_data),
                            void *private_data);
 
index 6ab4bbe70466e5e875fa18d8f27698fe51ec59a6..4d903248b99c4e60a8b0467223d58a58d56013a8 100644 (file)
@@ -59,7 +59,7 @@ struct ctdbd_connection {
        struct ctdb_packet_context *pkt;
        struct tevent_fd *fde;
 
-       void (*release_ip_handler)(const char *ip_addr, void *private_data);
+       bool (*release_ip_handler)(const char *ip_addr, void *private_data);
        void *release_ip_priv;
 };
 
@@ -428,10 +428,23 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
 
                if ((conn->release_ip_handler != NULL)
                    && (msg->srvid == CTDB_SRVID_RELEASE_IP)) {
+                       bool ret;
+
                        /* must be dispatched immediately */
                        DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n"));
-                       conn->release_ip_handler((const char *)msg->data,
-                                                conn->release_ip_priv);
+                       ret = conn->release_ip_handler((const char *)msg->data,
+                                                      conn->release_ip_priv);
+                       if (ret) {
+                               /*
+                                * We need to release the ip,
+                                * so return an error to the upper layers.
+                                *
+                                * We make sure we don't trigger this again.
+                                */
+                               conn->release_ip_handler = NULL;
+                               conn->release_ip_priv = NULL;
+                               return NT_STATUS_ADDRESS_CLOSED;
+                       }
                        TALLOC_FREE(hdr);
                        goto next_pkt;
                }
@@ -630,10 +643,21 @@ static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
 
        if ((conn->release_ip_handler != NULL)
            && (msg->srvid == CTDB_SRVID_RELEASE_IP)) {
+               bool ret;
+
                /* must be dispatched immediately */
                DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n"));
-               conn->release_ip_handler((const char *)msg->data,
-                                        conn->release_ip_priv);
+               ret = conn->release_ip_handler((const char *)msg->data,
+                                              conn->release_ip_priv);
+               if (ret) {
+                       /*
+                        * We need to release the ip.
+                        *
+                        * We make sure we don't trigger this again.
+                        */
+                       conn->release_ip_handler = NULL;
+                       conn->release_ip_priv = NULL;
+               }
                TALLOC_FREE(buf);
                return NT_STATUS_OK;
        }
@@ -1692,7 +1716,7 @@ static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in,
 NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
                            const struct sockaddr_storage *_server,
                            const struct sockaddr_storage *_client,
-                           void (*release_ip_handler)(const char *ip_addr,
+                           bool (*release_ip_handler)(const char *ip_addr,
                                                       void *private_data),
                            void *private_data)
 {
index 65d005df312926d64c3eae42d5b033922f8feb15..3dcc5d4e2718f0fe5b9c78f8dbc86e6f8431b373 100644 (file)
@@ -2509,7 +2509,7 @@ struct smbd_release_ip_state {
 /****************************************************************************
 received when we should release a specific IP
 ****************************************************************************/
-static void release_ip(const char *ip, void *priv)
+static bool release_ip(const char *ip, void *priv)
 {
        struct smbd_release_ip_state *state =
                talloc_get_type_abort(priv,
@@ -2546,8 +2546,10 @@ static void release_ip(const char *ip, void *priv)
                 */
                smbd_server_connection_terminate(state->sconn,
                                                 "CTDB_SRVID_RELEASE_IP");
-               return;
+               return true;
        }
+
+       return false;
 }
 
 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,