версии двига от 3.7 (более ранние не щупал) до последней
Актуально для тех кто использует:
"Группы нарушителей" (admincp/admininfraction.php?do=editgroup)
и/или
"Автоматические баны" (admincp/admininfraction.php?do=editbangroup)
и склонен к экспериментам с "Группами пользователей" (admincp/usergroup.php), в часности к их удалению.
Остальным полезно не будет.
Суть бага:
Видимо "Группы нарушителей" и "Автоматические баны" как и вся "система нарушений" по времени появились в вобле после "Групп пользователей", что логично.
А после их появления разрабы забыли добавить в admincp/usergroups.php при удалении "Группы пользователей" пару-тройку запросов.
1) Удалить из таблицы usergroupleader записи в которых поле usergroupid соответствует удаляемой группе.
Если все "лидеры" удаляемой группы не были сняты с должности до ее удаления, то в таблице usergroupleader навечно складируются бесполезные записи. Неичего страшного, просто не по феншую.
2) Удалить из таблицы infractiongroup записи в которых поле usergroupid или orusergroupid соответствует удаляемой группе.
Если все "Группы нарушителей" использующие удаляемую "Группу пользователей" не были удалены до ее удаления, то в таблице infractiongroup также складируются мертвые данные. Тоже не страшно.
3) Удалить из таблицы infractionban записи в которых поле usergroupid или banusergroupid соответствует удаляемой группе.
Если все "Автоматические баны" использующие удаляемую "Группу пользователей" не были удалены до ее удаления, то кроме того что мертвые данные будут висеть в бд, они еще и будут отображаться при выдаче юзеру красной карточки, причем отображаться будут только параметры бана ("Points,Infractions,Ban Period") названия фантомных "забаненных групп" будут пустыми. Не особо страшно, както неправильно просто.
4) Обнулить всем пользователям infractiongroupid у которых оно соответствует удаляемой группе и вырезать у всех пользователей из infractiongroupids удаляемую группу.
А вот это уже страшно.
Если все "Группы нарушителей" использующие удаляемую "Группу пользователей" не были удалены до ее удаления, то все пользователи числящиеся на момент удаления в потенциальноопасных "Группах нарушителей" будут мгновенно и навсегда забанены, внезависимости от прав которые они имели.
Это легко проверить если создать "Группу пользователей" абсолютно идентичную группе "Зарегистрированные", потом создать "Группу нарушителей" члены которой будут перемещаться из "Всех групп" в эту нашу вновьсозданную группу при количестве "штрафных" очков например больше 5.
Потом регнуть тестовую учетку. Вновь зайти админом и влепить этой учетке 10 кастомных "штрафных очков".
Зайти в админку и удалить "Группу пользователей" которую мы недавно создавали.
Выйти админом и зайти тестовым юзером. Оппа, мы в бане ни за что ни про что.
ВНИМАНИЕ: На живых форумах не проверять.
Причем этого не избежать если переписать код из функции print_no_permission()
PHP Code:
$infractiongroupids = explode(',', str_replace(' ', '', $vbulletin->userinfo['infractiongroupids']));
$bannedgroups = array();
foreach ($infractiongroupids AS $usergroupid)
{
if (!($vbulletin->usergroupcache["$usergroupid"]['genericoptions'] & $vbulletin->bf_ugp_genericoptions['isnotbannedgroup']))
{
$bannedgroups["$usergroupid"] = $usergroupid;
}
}
следующим образом:
PHP Code:
$infractiongroupids = explode(',', str_replace(' ', '', $vbulletin->userinfo['infractiongroupids']));
$bannedgroups = array();
foreach ($infractiongroupids AS $usergroupid)
{
if (isset($vbulletin->usergroupcache["$usergroupid"]) AND !($vbulletin->usergroupcache["$usergroupid"]['genericoptions'] & $vbulletin->bf_ugp_genericoptions['isnotbannedgroup']))
{
$bannedgroups["$usergroupid"] = $usergroupid;
}
}
Похерятся ВСЕ права, так как подобная проверка не предусмотрена еще во многих местах в движке.
Поэтому предлагаю такой фикс:
в файле admincp/usergroup.php ищем код: (в районе 575 строчки)
PHP Code:
build_ranks();
build_forum_permissions();
require_once(DIR . '/includes/adminfunctions_attachment.php');
build_attachment_permissions();
и вставляем перед ним следующее:
PHP Code:
$inf_groups = $db->query_read("
SELECT * FROM " . TABLE_PREFIX . "infractiongroup
WHERE orusergroupid = " . $vbulletin->GPC['usergroupid'] . "
");
if($db->num_rows($inf_groups))
{
require_once(DIR . '/includes/functions_infractions.php');
while($inf_group = $db->fetch_array($inf_groups))
{
check_infraction_group_change($inf_group['orusergroupid']);
}
}
$db->query_write("DELETE FROM " . TABLE_PREFIX . "usergroupleader WHERE usergroupid = " . $vbulletin->GPC['usergroupid']);
$db->query_write("DELETE FROM " . TABLE_PREFIX . "infractiongroup WHERE usergroupid = " . $vbulletin->GPC['usergroupid'] . " OR orusergroupid = " . $vbulletin->GPC['usergroupid']);
$db->query_write("DELETE FROM " . TABLE_PREFIX . "infractionban WHERE usergroupid = " . $vbulletin->GPC['usergroupid'] . " OR banusergroupid = " . $vbulletin->GPC['usergroupid']);
при желании можно запихнуть это в хук admin_usergroup_kill
//просьба модераторам. Замените все слова в кавычках на более подходящие. Я не использую пабличных переводов, следовательно не знаю как эти фразы принято называть в миру.