mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-03-10 06:10:14 +01:00
Automate Dovecot master user setup for webmail SSO in install and upgrade
Adds master passdb config to dovecot.conf templates, setupWebmail() to the installer and upgrade paths to generate credentials and create /etc/dovecot/master-users and /etc/cyberpanel/webmail.conf automatically. The upgrade path is idempotent and patches existing dovecot.conf if needed.
This commit is contained in:
@@ -53,6 +53,15 @@ protocol imap {
|
||||
mail_plugins = $mail_plugins zlib imap_zlib
|
||||
}
|
||||
|
||||
auth_master_user_separator = *
|
||||
|
||||
passdb {
|
||||
driver = passwd-file
|
||||
master = yes
|
||||
args = /etc/dovecot/master-users
|
||||
result_success = continue
|
||||
}
|
||||
|
||||
passdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
|
||||
@@ -53,6 +53,15 @@ protocol imap {
|
||||
mail_plugins = $mail_plugins zlib imap_zlib
|
||||
}
|
||||
|
||||
auth_master_user_separator = *
|
||||
|
||||
passdb {
|
||||
driver = passwd-file
|
||||
master = yes
|
||||
args = /etc/dovecot/master-users
|
||||
result_success = continue
|
||||
}
|
||||
|
||||
passdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
|
||||
@@ -705,6 +705,50 @@ module cyberpanel_ols {
|
||||
logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [installSieve]")
|
||||
return 0
|
||||
|
||||
def setupWebmail(self):
|
||||
"""Set up Dovecot master user and webmail config for SSO"""
|
||||
try:
|
||||
InstallCyberPanel.stdOut("Setting up webmail master user for SSO...", 1)
|
||||
|
||||
from plogical.randomPassword import generate_pass
|
||||
|
||||
master_password = generate_pass(32)
|
||||
|
||||
# Hash the password using doveadm
|
||||
result = subprocess.run(
|
||||
['doveadm', 'pw', '-s', 'SHA512-CRYPT', '-p', master_password],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
logging.InstallLog.writeToFile('[ERROR] doveadm pw failed: ' + result.stderr + " [setupWebmail]")
|
||||
return 0
|
||||
|
||||
password_hash = result.stdout.strip()
|
||||
|
||||
# Write /etc/dovecot/master-users
|
||||
with open('/etc/dovecot/master-users', 'w') as f:
|
||||
f.write('cyberpanel_master:' + password_hash + '\n')
|
||||
os.chmod('/etc/dovecot/master-users', 0o600)
|
||||
subprocess.call(['chown', 'dovecot:dovecot', '/etc/dovecot/master-users'])
|
||||
|
||||
# Write /etc/cyberpanel/webmail.conf
|
||||
import json as json_module
|
||||
webmail_conf = {
|
||||
'master_user': 'cyberpanel_master',
|
||||
'master_password': master_password
|
||||
}
|
||||
with open('/etc/cyberpanel/webmail.conf', 'w') as f:
|
||||
json_module.dump(webmail_conf, f)
|
||||
os.chmod('/etc/cyberpanel/webmail.conf', 0o600)
|
||||
subprocess.call(['chown', 'nobody:nobody', '/etc/cyberpanel/webmail.conf'])
|
||||
|
||||
InstallCyberPanel.stdOut("Webmail master user setup complete!", 1)
|
||||
return 1
|
||||
|
||||
except BaseException as msg:
|
||||
logging.InstallLog.writeToFile('[ERROR] ' + str(msg) + " [setupWebmail]")
|
||||
return 0
|
||||
|
||||
def installMySQL(self, mysql):
|
||||
|
||||
############## Install mariadb ######################
|
||||
@@ -1320,6 +1364,9 @@ def Main(cwd, mysql, distro, ent, serial=None, port="8090", ftp=None, dns=None,
|
||||
logging.InstallLog.writeToFile('Installing Sieve for email filtering..,55')
|
||||
installer.installSieve()
|
||||
|
||||
logging.InstallLog.writeToFile('Setting up webmail master user..,57')
|
||||
installer.setupWebmail()
|
||||
|
||||
logging.InstallLog.writeToFile('Installing MySQL,60')
|
||||
installer.installMySQL(mysql)
|
||||
installer.changeMYSQLRootPassword()
|
||||
|
||||
@@ -2801,6 +2801,95 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
except:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def setupWebmail():
|
||||
"""Set up Dovecot master user and webmail config for SSO (idempotent)"""
|
||||
try:
|
||||
# Skip if already configured
|
||||
if os.path.exists('/etc/cyberpanel/webmail.conf'):
|
||||
Upgrade.stdOut("Webmail master user already configured, skipping.", 0)
|
||||
return
|
||||
|
||||
# Skip if no mail server installed
|
||||
if not os.path.exists('/etc/dovecot/dovecot.conf'):
|
||||
Upgrade.stdOut("Dovecot not installed, skipping webmail setup.", 0)
|
||||
return
|
||||
|
||||
Upgrade.stdOut("Setting up webmail master user for SSO...", 0)
|
||||
|
||||
from plogical.randomPassword import generate_pass
|
||||
|
||||
master_password = generate_pass(32)
|
||||
|
||||
# Hash the password using doveadm
|
||||
result = subprocess.run(
|
||||
['doveadm', 'pw', '-s', 'SHA512-CRYPT', '-p', master_password],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0:
|
||||
Upgrade.stdOut("doveadm pw failed: " + result.stderr, 0)
|
||||
return
|
||||
|
||||
password_hash = result.stdout.strip()
|
||||
|
||||
# Write /etc/dovecot/master-users
|
||||
with open('/etc/dovecot/master-users', 'w') as f:
|
||||
f.write('cyberpanel_master:' + password_hash + '\n')
|
||||
os.chmod('/etc/dovecot/master-users', 0o600)
|
||||
subprocess.call(['chown', 'dovecot:dovecot', '/etc/dovecot/master-users'])
|
||||
|
||||
# Write /etc/cyberpanel/webmail.conf
|
||||
webmail_conf = {
|
||||
'master_user': 'cyberpanel_master',
|
||||
'master_password': master_password
|
||||
}
|
||||
with open('/etc/cyberpanel/webmail.conf', 'w') as f:
|
||||
json.dump(webmail_conf, f)
|
||||
os.chmod('/etc/cyberpanel/webmail.conf', 0o600)
|
||||
subprocess.call(['chown', 'nobody:nobody', '/etc/cyberpanel/webmail.conf'])
|
||||
|
||||
# Patch dovecot.conf if master user config not present
|
||||
dovecot_conf_path = '/etc/dovecot/dovecot.conf'
|
||||
with open(dovecot_conf_path, 'r') as f:
|
||||
dovecot_content = f.read()
|
||||
|
||||
if 'auth_master_user_separator' not in dovecot_content:
|
||||
master_block = """auth_master_user_separator = *
|
||||
|
||||
passdb {
|
||||
driver = passwd-file
|
||||
master = yes
|
||||
args = /etc/dovecot/master-users
|
||||
result_success = continue
|
||||
}
|
||||
|
||||
"""
|
||||
dovecot_content = dovecot_content.replace(
|
||||
'passdb {',
|
||||
master_block + 'passdb {',
|
||||
1 # Only replace the first occurrence
|
||||
)
|
||||
with open(dovecot_conf_path, 'w') as f:
|
||||
f.write(dovecot_content)
|
||||
|
||||
# Run webmail migrations
|
||||
Upgrade.executioner(
|
||||
'python /usr/local/CyberCP/manage.py makemigrations webmail',
|
||||
'Webmail makemigrations', shell=True
|
||||
)
|
||||
Upgrade.executioner(
|
||||
'python /usr/local/CyberCP/manage.py migrate',
|
||||
'Webmail migrate', shell=True
|
||||
)
|
||||
|
||||
# Restart Dovecot
|
||||
subprocess.call(['systemctl', 'restart', 'dovecot'])
|
||||
|
||||
Upgrade.stdOut("Webmail master user setup complete!", 0)
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut("setupWebmail error: " + str(msg), 0)
|
||||
|
||||
@staticmethod
|
||||
def manageServiceMigrations():
|
||||
try:
|
||||
@@ -4725,6 +4814,7 @@ pm.max_spare_servers = 3
|
||||
Upgrade.s3BackupMigrations()
|
||||
Upgrade.containerMigrations()
|
||||
Upgrade.manageServiceMigrations()
|
||||
Upgrade.setupWebmail()
|
||||
Upgrade.enableServices()
|
||||
|
||||
Upgrade.installPHP73()
|
||||
|
||||
Reference in New Issue
Block a user