ISP mail admin với nhiều admin

ispmailadmin là ứng dụng web quản lý ISP mailserver. Ưu điểm là mã nguồn mỡ, gọn nhẹ, đủ tính năng cơ bản. Với mailserver hỗ trợ nhiều domain, cần phân cấp quản lý cho từng domain, vì vậy phải sửa lại mã nguồn với mục đích:

  • Mỗi domain có admin riêng
  • Admin của domain này không nhìn thấy dữ liệu của domain khác
  • Superadmin quản lý tất cả domain
  • Các ứng dụng liên quan đều dùng cùng mã hóa mật khẩu (ARGON2ID)
  • Can thiệp vào mã nguồn ít nhất có thể

Chúng ta cần sửa 5 file như sau:

1. cfg/config.inc.php

Thêm vào các lựa chọn mã hóa

  • DEFAULT
  • BCRYPT
  • ARGON2I
  • ARGON2ID

Trong đó định nghĩa sẵn IMA_CFG_MULTI_ADM là một mãng json chuyển từ mãng PHP có dạng

  • sa => password
  • domain1 => password1
  • domain2 => password2

2. inc/defs.inc.php

Thêm kiểu IMA_LOGINTYPE_MULTI_ADM

3. inc/IspMailAdminApp.inc.php

Chỉnh sửa hàm mã hóa và cho phép đăng nhập nhiều admin

4. inc/Database_mysqli.inc.php

Chuyển truy cập các bảng sang các view. Mỗi domain khi được tạo sẽ có các view tương ứng để chỉ nhìn thấy dữ liệu của domain mình thôi

5. inc/EmailDomains.inc.php

  • Không cho phép admin từng domain có thể thêm hay xóa domain
  • Khi superadmin tạo/xóa domain thì tạo/xóa các view tương ứng

Script chỉnh sửa các file trên

F=$W/mailadmin/inc/defs.inc.php
[ -f "$F.org" ]&&cp -f "$F.org" "$F" || cp -f "$F" "$F.org"
sed -i "/ADMAUTO/ a\
define('IMA_LOGINTYPE_MULTI_ADM',4);
" $F

F=$W/mailadmin/cfg/config.inc.php
cp -f $W/mailadmin/cfg/config.sample.inc.php $F
sed -i "/\(IMA_CFG_ADM_USER\|IMA_CFG_ADM_PASS\)/s#\(.*\)#// \1#
s#^.*\(define.*IMA_CFG_DB_SOCKET'\).*#\1, '/run/mysqld/mysqld.sock');#
s/\(^.*'IMA_CFG_DB_USER'\).*/\1,'$RW_U');/
s/\(^.*'IMA_CFG_DB_PASSWORD'\).*/\1,'$RW_P');/
s/\(.*'IMA_CFG_DB_DATABASE'\).*/\1,'$DB');/
/IMA_LOGINTYPE_ACCOUNT/a\
define('IMA_CFG_LOGIN', IMA_LOGINTYPE_MULTI_ADM);\n\
define('IMA_CFG_MULTI_ADM','\{$cfg\}');
/IMA_CFG_USE_\(BCRYPT_HASHES\|SHA256_HASHES\|MD5_HASHES\)/d
/PASSWORD HASHES/{N;N;a\
define('CRYPT','PASSWORD_ARGON2ID');\n\
\/\/ CRYPT: DEFAULT, BCRYPT, ARGON2I, ARGON2ID\n\
ini_set('sendmail_path','/usr/sbin/sendmail -t -i');
}
" $F

F=$W/mailadmin/inc/IspMailAdminApp.inc.php
[ -f "$F.org" ]&&cp -f "$F.org" "$F"||cp -f "$F" "$F.org"
sed -i "s/(BLF-CRYPT|SHA256-CRYPT|PLAIN-MD5)/PASSWORD_\(DEFAULT|BCRYPT|ARGON2I|ARGON2ID\)/
/function makePwd_DbHash/{N;a\
return \"\{\".substr(CRYPT,9).\"\}\".password_hash(\$sPwdPlain, constant(CRYPT));
}
/\!defined('IMA_CFG_LOGIN'));/a\
elseif(IMA_CFG_LOGIN==IMA_LOGINTYPE_MULTI_ADM)\{\
foreach(json_decode(IMA_CFG_MULTI_ADM) as \$u=>\$p)\{\
if((\$this->aReqParam['sloginuser']==\$u)&&(\$this->aReqParam['sloginpass']==\$p))\{\
\$this->iIdUser=-1;\
\$this->sIdPage='page_welcome';\
\$_SESSION['domain']=\$u;\
\$bRetVal=true;\
break;\}\}\}
" $F

F=$W/mailadmin/inc/Database_mysqli.inc.php
[ -f "$F.org" ]&&cp -f "$F.org" "$F"||cp -f "$F" "$F.org"
sed -i "/function query\b/i\
private function dQuery(\$sQuery)\{return (\$_SESSION['domain']=='sa')?\$sQuery:preg_replace('\/\\\\bvirtual_\/',str_replace('.','_',\$_SESSION['domain']).'_virtual_',\$sQuery);\}
/\(function query\b\|function queryOneRow\b\)/{N;a\
\$sQuery=\$this->dQuery(\$sQuery);
}
" $F

F=$W/mailadmin/inc/EmailDomains.inc.php
[ -f "$F.org" ]&&cp -f "$F.org" "$F"||cp -f "$F" "$F.org"
sed -i "/'cmd_create':\|'cmd_delete':/a\
if(\$_SESSION['domain']!='sa')return false;
/create domain/{N;a\
elseif(0!=(\$iErr=\$this->createViews(\$sName)));
}
/No such Domain/{N;a\
elseif(0!=(\$iErr=\$this->dropViews(\$iId)));
}
\#METHOD PRIVATE#a\
private function dropViews(\$id)\{\
\$iErr=1;if(0!=\$this->App->DB->queryOneRow(\$r,\"SELECT name FROM virtual_domains WHERE id='\$id'\"));\
elseif(NULL===\$r);else\{\$name=\$r['name'];\$n=str_replace('.','_',\$name);\
if(0!=\$this->App->DB->state(\"DROP VIEW IF EXISTS \$\{n\}_virtual_domains,\$\{n\}_virtual_users,\$\{n\}_virtual_aliases\"));\
else\{\$a=json_decode(IMA_CFG_MULTI_ADM,true);unset(\$a[\$name]);\$F='cfg/config.inc.php';\
file_put_contents(\$F,preg_replace('/(\\\\'IMA_CFG_MULTI_ADM\\\\').+/',\"\$1,'\".json_encode(\$a).\"');\",file_get_contents(\$F)));\$iErr=0;\}\}\
unlink(\"INFO/\$name.README\");return (\$iErr);\}\n\
private function createViews(\$name)\{\
\$iErr=1;if(0!=\$this->App->DB->queryOneRow(\$r,\"SELECT id FROM virtual_domains WHERE name='\$name'\"));\
elseif(NULL===\$r);else\{\$id=\$r['id'];\$n=str_replace('.','_',\$name);\
if(0!=\$this->App->DB->state(\"CREATE OR REPLACE VIEW \$\{n\}_virtual_domains AS SELECT * FROM virtual_domains WHERE id=\$id\"));\
elseif(0!=\$this->App->DB->state(\"CREATE OR REPLACE VIEW \$\{n\}_virtual_users AS SELECT * FROM virtual_users WHERE domain_id='\$id'\"));\
elseif(0!=\$this->App->DB->state(\"CREATE OR REPLACE VIEW \$\{n\}_virtual_aliases AS SELECT * FROM virtual_aliases WHERE domain_id='\$id'\"));\
else\{\$p=uniqid();\n\
file_put_contents(\"INFO\/\$\{name\}.README\",str_replace(array('ydomain','ypassword'),array(\"\$name\",\"\$p\"),file_get_contents('INFO\/sample.README')));\
\$a=json_decode(IMA_CFG_MULTI_ADM,true);\$a[\$name]=\$p;\$F='cfg\/config.inc.php';\
\$p='\{'.substr(CRYPT,9).'\}'.password_hash(\$name,constant(CRYPT));\
if(false===file_put_contents(\$F,preg_replace('\/(\\\\'IMA_CFG_MULTI_ADM\\\\').+\/',\"\$1,'\".json_encode(\$a).\"');\",file_get_contents(\$F))));\
elseif(0!=\$this->App->DB->state(\"REPLACE INTO virtual_users (domain_id,email,password) VALUES ('\$id','postmaster@\$name','\$p')\"));\
elseif(false===mail(\"postmaster@\$name\",\"Informations of mailserver \$name\",file_get_contents(\"INFO\/\$\{name\}.README\"),\"From: postmater@\$D\"));\
else \$iErr=0;\}\}return(\$iErr);\}
" $F

Comments Off on ISP mail admin với nhiều admin

Filed under Software

Comments are closed.