find_in_set и find_in_set неожиданный результат - PullRequest
1 голос
/ 05 октября 2019
USE mysql;
DROP PROCEDURE IF EXISTS ShowUsers;
DELIMITER $

CREATE PROCEDURE `ShowUsers`(IN KnownUsers varchar(500), IN KnownHosts varchar(500))
BEGIN
  SELECT
    user,host
  FROM
    user
  WHERE 
    NOT FIND_IN_SET(host, KnownHosts)
  AND
    NOT FIND_IN_SET(user, KnownUsers)
  ORDER BY user, host ASC;
END $
DELIMITER ;

Пример полных данных для работы:

+-------------+-------------+
| user        | host        |
+-------------+-------------+
| knownuser1  | 192.168.1.5 |
| knownuser2  | 192.168.1.5 |
| unknownuser | 192.168.1.5 | # I want this result to show
| someuser1   | 192.168.1.6 |
| someuser2   | 192.168.1.6 |
| someuser3   | 192.168.1.6 |
| root        | localhost   |
+-------------+-------------+

Я отметил результат, который я хотел бы показать при запуске процедуры, в основном два параметра IN - это известные пользователи и известные хосты, которыев этой базе данных должна быть запись пользователя.

Вызов функции, подобной этой

# users and hostnames(ips) to match for exclusion from results.
SET @Usernames = 'knownuser1,knownuser2';
SET @Hostnames = '192.168.1.5';

CALL ShowUsers(@Usernames, @Hostnames);

Ожидаемый результат:

+-------------+-------------+
| user        | host        |
+-------------+-------------+
| unknownuser | 192.168.1.5 | # I want this result to show
| someuser1   | 192.168.1.6 |
| someuser2   | 192.168.1.6 |
| someuser3   | 192.168.1.6 |
| root        | localhost   |
+-------------+-------------+

Фактический результат:

+-------------+-------------+
| user        | host        |
+-------------+-------------+
| someuser1   | 192.168.1.6 |
| someuser2   | 192.168.1.6 |
| someuser3   | 192.168.1.6 |
| root        | localhost   |
+-------------+-------------+

Объяснение (не по этой теме, но я думаю, что я должен уточнить) Причина, по которой я хочу, чтобы эта процедура работала, у меня есть главный сервер с несколькими удаленными ведомыми устройствами, ведомые устройства должны иметь доступ к базе данных ведущих устройств, что означает, что они такжедолжны иметь «root» доступ, они могут создавать / реконфигурировать свои собственные учетные данные доступа. Проблема в том, что если один из этих серверов когда-либо будет взломан, это оставит открытым возможность добавить нового пользователя с учетными данными практически ко всей базе данных. Широко открыт и свободен для взятия.

Я мог бы заблокировать ведомых после первоначальной конфигурации и вручную открыть дверь, запустить обновление и затем снова заблокировать его, что было бы довольно трудоемким для приложения и сделало бы приложение виртуальнымбесполезно.

Идея, с которой я сейчас работаю, состоит в том, чтобы запустить эту процедуру с помощью скрипта запуска cron и проверить наличие неизвестных пользователей / хостов и заблокировать этот подчиненный сервер из базы данных, пока я не приму или не отклоню пользователя. основное приложение.

1 Ответ

1 голос
/ 05 октября 2019

Условие в предложении WHERE:

NOT FIND_IN_SET(host, KnownHosts) AND NOT FIND_IN_SET(user, KnownUsers)

, что эквивалентно:

NOT (FIND_IN_SET(host, KnownHosts) OR FIND_IN_SET(user, KnownUsers))

, что означает, что вы хотите исключить ряды для которых:host включено в KnownHosts или user включено в KnownUsers.

Таким образом, для ваших образцов данных строка:

unknownuser | 192.168.1.5

не будет возвращена, поскольку host = '192.168.1.5' и включены в KnownHosts (= '192.168.1.5'). Возможно, измените логический оператор на OR, если вы хотите применить логику:

NOT FIND_IN_SET(host, KnownHosts) OR NOT FIND_IN_SET(user, KnownUsers)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...