Просмотрев данную тему, т.к. необходимо осуществить сабж, столкнулся с некоторыми проблемами, но всё таки довел до ума!
Во-первых, проблема выше описанных процедур в том, что если их использовать (рабочие), то даже если у абона есть только одна айпишка, все равно нужно указывать логин с индексом (правда с любым числовым), а так не красиво.
Я выкладываю рабочие процедуры, в которых уже нет этой проблемы, то есть работают логины типа:
test абон получит 1ый ип
test+0 абон получит 1ый ип
test+1 абон получит 2ой ип если у него их 2, если только 1 то 1ий (и по аналогии 2,3,4 и т.д.)
test+N абон получит N-1 ип если у него их N
и так, процедуры:
DROP FUNCTION IF EXISTS `get_ip_by_num`;
DELIMITER $$
CREATE FUNCTION `get_ip_by_num` ( user_id INTEGER UNSIGNED, num INTEGER)
RETURNS VARCHAR(15) NO SQL
BEGIN
DECLARE user_ip VARCHAR(15);
DECLARE real_ip VARCHAR(15);
IF( num IS NULL ) THEN SET num=0; END IF;
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
WHERE uid = user_id AND type='static' ORDER BY ip LIMIT num, 1;
IF( user_ip IS NOT NULL ) THEN RETURN user_ip; END IF;
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
WHERE uid = user_id AND type='static' ORDER BY ip LIMIT 1;
IF( user_ip IS NOT NULL ) THEN RETURN user_ip; END IF;
SELECT 1 INTO real_ip FROM users_services WHERE uid = user_id AND tags LIKE '%,realip,%';
UPDATE ip_pool SET uid = user_id, `release` = UNIX_TIMESTAMP() + 300
WHERE (uid = 0 OR uid = user_id)
AND type = 'dynamic'
AND realip = IF(real_ip>0,1,0)
ORDER BY uid DESC, id ASC LIMIT 1;
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
WHERE uid = user_id LIMIT 1;
RETURN user_ip;
END$$
DELIMITER ;
Не забудьте в процедуре
radcheck изменить
hardpass на свой ключ шифрования паролей из файла
nodeny/sat.cfgDROP PROCEDURE IF EXISTS `radcheck`;
DELIMITER $$
CREATE PROCEDURE `radcheck` (IN login VARCHAR(64))
BEGIN
DECLARE real_login VARCHAR(64) DEFAULT NULL;
SELECT SUBSTRING_INDEX(login, '=2B', 1) INTO real_login;
SELECT id, name, 'Password' AS Attribute, AES_DECRYPT(passwd,'hardpass') AS Value,'=='
FROM users WHERE name=real_login;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64))
BEGIN
DECLARE usr_id INT;
DECLARE ip_index INT ;
DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
DECLARE real_login VARCHAR(64) DEFAULT NULL;
SELECT SUBSTRING_INDEX(login, '=2B', 1) INTO real_login;
IF login REGEXP '[=2B][0-9]+$' THEN
SELECT CAST(REPLACE(REPLACE(login, real_login, ''),'=2B','') AS UNSIGNED) INTO ip_index;
ELSE SET ip_index=0;END IF;
SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1;
SELECT get_ip_by_num(usr_id, ip_index) INTO usr_ip;
SELECT NULL,login,'Framed-IP-Address',usr_ip,'=';
SELECT NULL,login,'Framed-IP-Netmask','255.255.255.255','=';
SELECT NULL,login,'Framed-Protocol','PPP','=';
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate`(IN `login` VARCHAR(64), IN `ip` VARCHAR(16), IN `properties` VARCHAR(255))
BEGIN
DECLARE usr_id INT;
DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
DECLARE real_login VARCHAR(64) DEFAULT NULL;
DECLARE ip_index INT ;
SELECT SUBSTRING_INDEX(login, '=2B', 1) INTO real_login;
IF login REGEXP '[=2B][0-9]+$' THEN
SELECT CAST(REPLACE(REPLACE(login, real_login, ''),'=2B','') AS UNSIGNED) INTO ip_index;
ELSE SET ip_index=0;END IF;
SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1;
SELECT get_ip_by_num(usr_id, ip_index) INTO usr_ip;
CALL set_auth(usr_ip, CONCAT('mod=pppoe;',REPLACE(properties,':','')));
END$$
DELIMITER ;
кто подскажет, зачем нужен в процедуре
radupdate на входе вторым параметром
IN `ip` VARCHAR(16), он нигде в ней не используется
DROP PROCEDURE IF EXISTS `radstop`;
DELIMITER $$
CREATE PROCEDURE `radstop`(IN login VARCHAR(64))
BEGIN
DECLARE usr_id INT;
DECLARE ip_index INT ;
DECLARE real_login VARCHAR(64) DEFAULT NULL;
SELECT SUBSTRING_INDEX(login, '=2B', 1) INTO real_login;
IF login REGEXP '[=2B][0-9]+$' THEN
SELECT CAST(REPLACE(REPLACE(login, real_login, ''),'=2B','') AS UNSIGNED) INTO ip_index;
ELSE SET ip_index=0;END IF;
SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1;
DELETE FROM auth_now WHERE ip = get_ip_by_num(usr_id, ip_index) LIMIT 1;
END$$
DELIMITER ;
Предлагаю все эти процедуры добавить в коробку, так же процедура
get_ip_by_num может полностью заменить процедуру
get_ipпринимаю СПАСИБКИ в Кармуto be continued...