Hardlink chroot related files across all accounts to save disk space
This commit is contained in:
@ -941,17 +941,25 @@ function bytes_to_human_readable(int $bytes) : string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup_chroot(string $account){
|
function setup_chroot(string $account, string $last_account){
|
||||||
$system_account = sanitize_system_account($account);
|
$system_account = sanitize_system_account($account);
|
||||||
if($system_account === false){
|
if($system_account === false){
|
||||||
echo "ERROR: Account $account looks strange\n";
|
echo "ERROR: Account $account looks strange\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$last_account = sanitize_system_account($last_account);
|
||||||
$shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin';
|
$shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin';
|
||||||
$user = posix_getpwnam($system_account);
|
$user = posix_getpwnam($system_account);
|
||||||
$passwd_line = "$user[name]:$user[passwd]:$user[uid]:$user[gid]:$user[gecos]:/:$user[shell]";
|
$passwd_line = "$user[name]:$user[passwd]:$user[uid]:$user[gid]:$user[gecos]:/:$user[shell]";
|
||||||
exec('/var/www/setup_chroot.sh ' . escapeshellarg("/home/$system_account"));
|
exec('/var/www/setup_chroot.sh ' . escapeshellarg("/home/$system_account"));
|
||||||
file_put_contents("/home/$system_account/etc/passwd", $passwd_line, FILE_APPEND);
|
file_put_contents("/home/$system_account/etc/passwd", $passwd_line, FILE_APPEND);
|
||||||
|
if($last_account !== false){
|
||||||
|
exec('hardlink -c ' . escapeshellarg("/home/$system_account/bin") . ' ' . escapeshellarg("/home/$last_account/bin"));
|
||||||
|
exec('hardlink -c ' . escapeshellarg("/home/$system_account/etc") . ' ' . escapeshellarg("/home/$last_account/etc"));
|
||||||
|
exec('hardlink -c ' . escapeshellarg("/home/$system_account/lib") . ' ' . escapeshellarg("/home/$last_account/lib"));
|
||||||
|
exec('hardlink -c ' . escapeshellarg("/home/$system_account/lib64") . ' ' . escapeshellarg("/home/$last_account/lib64"));
|
||||||
|
exec('hardlink -c ' . escapeshellarg("/home/$system_account/usr") . ' ' . escapeshellarg("/home/$last_account/usr"));
|
||||||
|
}
|
||||||
foreach(['.cache', '.composer', '.config', '.gnupg', '.local', '.ssh', 'data', 'Maildir'] as $dir){
|
foreach(['.cache', '.composer', '.config', '.gnupg', '.local', '.ssh', 'data', 'Maildir'] as $dir){
|
||||||
if(!is_dir("/home/$system_account/$dir")){
|
if(!is_dir("/home/$system_account/$dir")){
|
||||||
mkdir("/home/$system_account/$dir", 0700);
|
mkdir("/home/$system_account/$dir", 0700);
|
||||||
@ -1010,7 +1018,7 @@ function update_system_user_password(string $user, string $password){
|
|||||||
function sanitize_system_account(string $system_account){
|
function sanitize_system_account(string $system_account){
|
||||||
$account = basename($system_account);
|
$account = basename($system_account);
|
||||||
$user = posix_getpwnam($account);
|
$user = posix_getpwnam($account);
|
||||||
if($account !== $system_account || $user === false || $user['gid'] !== 33 || $user['uid'] < 1000){
|
if(empty($system_account) || $account !== $system_account || $user === false || $user['gid'] !== 33 || $user['uid'] < 1000){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return $account;
|
return $account;
|
||||||
|
@ -11,9 +11,15 @@ while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
|||||||
$db->query('UPDATE service_instances SET reload=0 WHERE reload=1;');
|
$db->query('UPDATE service_instances SET reload=0 WHERE reload=1;');
|
||||||
|
|
||||||
//add new accounts
|
//add new accounts
|
||||||
|
$newest_account=$db->query('SELECT system_account FROM users WHERE id NOT IN (SELECT user_id FROM new_account) AND todelete!=1 ORDER BY id DESC LIMIT 1;');
|
||||||
|
$last_account = $newest_account->fetch(PDO::FETCH_NUM);
|
||||||
|
if(is_array($last_account)){
|
||||||
|
$last_account = $last_account[0];
|
||||||
|
}
|
||||||
$del=$db->prepare("DELETE FROM new_account WHERE user_id=?;");
|
$del=$db->prepare("DELETE FROM new_account WHERE user_id=?;");
|
||||||
$approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': '';
|
$approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': '';
|
||||||
$stmt=$db->query("SELECT users.system_account, new_account.password, users.id, users.instance FROM new_account INNER JOIN users ON (users.id=new_account.user_id) $approval LIMIT 100;");
|
$stmt=$db->query("SELECT users.system_account, new_account.password, users.id, users.instance FROM new_account INNER JOIN users ON (users.id=new_account.user_id) $approval LIMIT 100;");
|
||||||
|
|
||||||
while($account=$stmt->fetch(PDO::FETCH_ASSOC)){
|
while($account=$stmt->fetch(PDO::FETCH_ASSOC)){
|
||||||
$system_account = basename($account['system_account']);
|
$system_account = basename($account['system_account']);
|
||||||
if($system_account !== $account['system_account']){
|
if($system_account !== $account['system_account']){
|
||||||
@ -29,7 +35,8 @@ while($account=$stmt->fetch(PDO::FETCH_ASSOC)){
|
|||||||
$shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin';
|
$shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin';
|
||||||
exec('useradd -l -g www-data -k /var/www/skel -m -s ' . escapeshellarg($shell) . ' ' . escapeshellarg($system_account));
|
exec('useradd -l -g www-data -k /var/www/skel -m -s ' . escapeshellarg($shell) . ' ' . escapeshellarg($system_account));
|
||||||
update_system_user_password($system_account, $account['password']);
|
update_system_user_password($system_account, $account['password']);
|
||||||
setup_chroot($system_account);
|
setup_chroot($system_account, $last_account);
|
||||||
|
$last_account = $system_account;
|
||||||
//remove from to-add queue
|
//remove from to-add queue
|
||||||
$del->execute([$account['id']]);
|
$del->execute([$account['id']]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user