php IHDR w Q )Ba pHYs sRGB gAMA a IDATxMk\U s&uo,mD )Xw+e?tw.oWp;QHZnw`gaiJ9̟灙a=nl[ ʨ G;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ y H@E7j 1j+OFRg}ܫ;@Ea~ j`u'o> j- $_q?qS XzG'ay
files >> /usr/libexec/webmin/virtual-server/ |
files >> //usr/libexec/webmin/virtual-server/feature-dir.pl |
# Functions for managing a domain's home directory # setup_dir(&domain) # Creates the home directory sub setup_dir { local $tmpl = &get_template($_[0]->{'template'}); &require_useradmin(); local $qh = quotemeta($_[0]->{'home'}); &$first_print($text{'setup_home'}); # Get Unix user, either for this domain or its parent local $uinfo; if ($_[0]->{'unix'} || $_[0]->{'parent'}) { local @users = &list_all_users(); ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @users; } if ($_[0]->{'unix'} && !$uinfo) { # If we are going to have a Unix user but none has been created # yet, fake his details here for use in chowning and skel copying # This should never happen! $uinfo ||= { 'uid' => $_[0]->{'uid'}, 'gid' => $_[0]->{'ugid'}, 'shell' => '/bin/sh', 'group' => $_[0]->{'group'} || $_[0]->{'ugroup'} }; } # Create and populate home directory &create_domain_home_directory($_[0], $uinfo); # Populate home dir if ($tmpl->{'skel'} ne "none" && !$_[0]->{'nocopyskel'} && !$_[0]->{'alias'}) { # Don't die if this fails due to quota issues eval { local $main::error_must_die = 1; ©_skel_files(&substitute_domain_template($tmpl->{'skel'}, $_[0]), $uinfo, $_[0]->{'home'}, $_[0]->{'group'} || $_[0]->{'ugroup'}, $_[0]); }; } # If this is a sub-domain, move public_html from any skeleton to it's sub-dir # under the parent if ($_[0]->{'subdom'}) { local $phsrc = &public_html_dir($_[0], 0, 1); local $phdst = &public_html_dir($_[0], 0, 0); if (-d $phsrc && !-d $phdst) { &make_dir($phdst, 0755); &set_ownership_permissions($_[0]->{'uid'}, $_[0]->{'gid'}, undef, $phdst); ©_source_dest($phsrc, $phdst); &unlink_file($phsrc); } } # Setup sub-directories &create_standard_directories($_[0]); &$second_print($text{'setup_done'}); # Create mail file if (!$_[0]->{'parent'} && $uinfo) { &$first_print($text{'setup_usermail3'}); eval { local $main::error_must_die = 1; &create_mail_file($uinfo, $_[0]); # Set the user's Usermin IMAP password &set_usermin_imap_password($uinfo); }; if ($@) { &$second_print(&text('setup_eusermail3', "$@")); } else { &$second_print($text{'setup_done'}); } } return 1; } # create_domain_home_directory(&domain, &unix-user) # Create the home directory for a server or sub-server sub create_domain_home_directory { local ($d, $uinfo) = @_; local $perms = oct($uconfig{'homedir_perms'}); if (&has_domain_user($d) && $d->{'parent'}) { # Run as domain owner, as this is a sub-server &make_dir_as_domain_user($d, $d->{'home'}, $perms); &set_permissions_as_domain_user($d, $perms, $d->{'home'}); } else { # Run commands as root, as user is missing if (!-d $d->{'home'}) { &make_dir($d->{'home'}, $perms); } &set_ownership_permissions(undef, undef, $perms, $d->{'home'}); if ($uinfo) { &set_ownership_permissions($uinfo->{'uid'}, $uinfo->{'gid'}, undef, $d->{'home'}); } } } # create_standard_directories(&domain) # Create and set permissions on standard directories sub create_standard_directories { local ($d) = @_; foreach my $dir (&virtual_server_directories($d)) { local $path = "$d->{'home'}/$dir->[0]"; &lock_file($path); if (&has_domain_user($d)) { # Do creation as domain owner if (!-d $path) { &make_dir_as_domain_user($d, $path, oct($dir->[1]), 1); } &set_permissions_as_domain_user($d, oct($dir->[1]), $path); } else { # Need to run as root if (!-d $path) { &make_dir($path, oct($dir->[1]), 1); } &set_ownership_permissions(undef, undef, oct($dir->[1]), $path); if ($d->{'uid'} && ($d->{'unix'} || $d->{'parent'})) { &set_ownership_permissions($d->{'uid'}, $d->{'gid'}, undef, $path); } } &unlock_file($path); } } # modify_dir(&domain, &olddomain) # Rename home directory if needed sub modify_dir { # Special case .. converting alias to non-alias, so some directories need to # be created if ($_[1]->{'alias'} && !$_[0]->{'alias'}) { &$first_print($text{'save_dirunalias'}); local $tmpl = &get_template($_[0]->{'template'}); if ($tmpl->{'skel'} ne "none") { local $uinfo = &get_domain_owner($_[0], 1); ©_skel_files( &substitute_domain_template($tmpl->{'skel'}, $_[0]), $uinfo, $_[0]->{'home'}, $_[0]->{'group'} || $_[0]->{'ugroup'}, $_[0]); } &create_standard_directories($_[0]); &$second_print($text{'setup_done'}); } if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($_[1], 1); } if ($_[0]->{'home'} ne $_[1]->{'home'}) { # Move the home directory if changed, and if not already moved as # part of parent if (-d $_[1]->{'home'}) { &$first_print($text{'save_dirhome'}); if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($_[0], 1); } local $cmd = $config{'move_command'} || "mv"; $cmd .= " ".quotemeta($_[1]->{'home'}). " ".quotemeta($_[0]->{'home'}); $cmd .= " 2>&1 </dev/null"; &set_domain_envs($_[1], "MODIFY_DOMAIN", $_[0]); local $out = &backquote_logged($cmd); &reset_domain_envs($_[1]); if ($?) { &$second_print(&text('save_dirhomefailed', "<tt>$out</tt>")); } else { &$second_print($text{'setup_done'}); } if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($_[0], 0); } } } if ($_[0]->{'unix'} && !$_[1]->{'unix'} || $_[0]->{'uid'} ne $_[1]->{'uid'}) { # Unix user now exists or has changed! Set ownership of home dir &$first_print($text{'save_dirchown'}); &set_home_ownership($_[0]); &$second_print($text{'setup_done'}); } if (!$_[0]->{'subdom'} && $_[1]->{'subdom'}) { # No longer a sub-domain .. move the HTML dir local $phsrc = &public_html_dir($_[1]); local $phdst = &public_html_dir($_[0]); ©_source_dest($phsrc, $phdst); &unlink_file($phsrc); # And the CGI directory local $cgisrc = &cgi_bin_dir($_[1]); local $cgidst = &cgi_bin_dir($_[0]); ©_source_dest($cgisrc, $cgidst); &unlink_file($cgisrc); } if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($_[0], 0); } } # delete_dir(&domain) # Delete the home directory sub delete_dir { # Delete homedir if (-d $_[0]->{'home'} && $_[0]->{'home'} ne "/") { &$first_print($text{'delete_home'}); if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($_[0], 1); } local $err = &backquote_logged("rm -rf ".quotemeta($_[0]->{'home'}). " 2>&1"); if ($?) { # Try again after running chattr if (&has_command("chattr")) { &system_logged("chattr -i -R ". quotemeta($_[0]->{'home'})); $err = &backquote_logged( "rm -rf ".quotemeta($_[0]->{'home'})." 2>&1"); $err = undef if (!$?); } } else { $err = undef; } if ($err) { # Ignore an error deleting a mount point local @subs = &sub_mount_points($_[0]->{'home'}); if (@subs) { $err = undef; } } if ($err) { &$second_print(&text('delete_ehome', &html_escape($err))); } else { &$second_print($text{'setup_done'}); } } } # clone_dir(&domain, &src-domain) # Copy home directory contents to a new cloned domain sub clone_dir { local ($d, $oldd) = @_; &$first_print($text{'clone_dir'}); if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($d, 1); } # Exclude sub-server directories, logs, SSL certs and .zfs files local $xtemp = &transname(); &open_tempfile(XTEMP, ">$xtemp"); &print_tempfile(XTEMP, "domains\n"); &print_tempfile(XTEMP, "./domains\n"); &print_tempfile(XTEMP, "logs\n"); &print_tempfile(XTEMP, "./logs\n"); if ($gconfig{'os_type'} eq 'solaris') { open(FIND, "find ".quotemeta($d->{'home'})." -name .zfs |"); while(<FIND>) { s/\r|\n//g; s/^\Q$d->{'home'}\E\///; &print_tempfile(XTEMP, "$_\n"); &print_tempfile(XTEMP, "./$_\n"); } close(FIND); } foreach my $s ('ssl_cert', 'ssl_key', 'ssl_chain', 'ssl_csr', 'ssl_newkey') { my $p = $d->{$s}; if ($p) { $p =~ s/^\Q$d->{'home'}\E\///; &print_tempfile(XTEMP, "$p\n"); &print_tempfile(XTEMP, "./$p\n"); } } &close_tempfile(XTEMP); # Clear any in-memory caches of files under home dir if (defined(&list_domain_php_inis) && &foreign_check("phpini")) { my $mode = &get_domain_php_mode($d); $mode = "cgi" if ($mode eq "mod_php"); foreach my $ini (&list_domain_php_inis($d, $mode)) { delete($phpini::get_config_cache{$ini->[1]}); } } # Do the copy if (!$d->{'parent'}) { &disable_quotas($d); &disable_quotas($oldd); } local $err = &backquote_logged( "cd ".quotemeta($oldd->{'home'})." && ". "tar cfX - $xtemp . | ". "(cd ".quotemeta($d->{'home'})." && ". " tar xpf -) 2>&1"); &set_home_ownership($d); if (!$d->{'parent'}) { &enable_quotas($oldd); &enable_quotas($d); } if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($d, 0); } if ($err) { &$second_print(&text('clone_edir', &html_escape($err))); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } # validate_dir(&domain) # Returns an error message if the directory is missing, or has the wrong # ownership sub validate_dir { local ($d) = @_; if (!-d $d->{'home'}) { return &text('validate_edir', "<tt>$d->{'home'}</tt>"); } local @st = stat($d->{'home'}); if ($d->{'uid'} && $st[4] != $d->{'uid'}) { local $owner = getpwuid($st[4]); return &text('validate_ediruser', "<tt>$d->{'home'}</tt>", $owner, $d->{'user'}) } if ($d->{'gid'} && $st[5] != $d->{'gid'} && $st[5] != $d->{'ugid'}) { local $owner = getgrgid($st[5]); return &text('validate_edirgroup', "<tt>$d->{'home'}</tt>", $owner, $d->{'group'}) } if (!$d->{'alias'}) { foreach my $sd (&virtual_server_directories($d)) { if (!-d "$d->{'home'}/$sd->[0]") { # Dir is missing return &text('validate_esubdir', "<tt>$sd->[0]</tt>") } local @st = stat("$d->{'home'}/$sd->[0]"); if ($d->{'uid'} && $st[4] != $d->{'uid'}) { # UID is wrong local $owner = getpwuid($st[4]); return &text('validate_esubdiruser', "<tt>$sd->[0]</tt>", $owner, $d->{'user'}) } if ($d->{'gid'} && $st[5] != $d->{'gid'} && $st[5] != $d->{'ugid'}) { # GID is wrong local $owner = getgrgid($st[5]); return &text('validate_esubdirgroup', "<tt>$sd->[0]</tt>", $owner, $d->{'group'}) } } } return undef; } # check_dir_clash(&domain, [field]) sub check_dir_clash { # Does nothing ..? return 0; } # backup_dir(&domain, file, &options, home-format, incremental, [&as-domain], # &all-options, &key) # Backs up the server's home directory in tar format to the given file sub backup_dir { local ($d, $file, $opts, $homefmt, $increment, $asd, $allopts, $key) = @_; &$first_print($homefmt && $config{'compression'} == 3 ? $text{'backup_dirzip'} : $increment == 1 ? $text{'backup_dirtarinc'} : $text{'backup_dirtar'}); local $out; local $cmd; local $gzip = $homefmt && &has_command("gzip"); # Create exclude file local $xtemp = &transname(); local @xlist; push(@xlist, "domains"); if ($opts->{'dirnologs'}) { push(@xlist, "logs"); } if ($opts->{'dirnohomes'}) { push(@xlist, "homes"); } push(@xlist, "virtualmin-backup"); push(@xlist, &get_backup_excludes($d)); push(@xlist, split(/\t+/, $opts->{'exclude'})); push(@xlist, "backup.lock"); # Exclude all .zfs files, for Solaris if ($gconfig{'os_type'} eq 'solaris') { open(FIND, "find ".quotemeta($d->{'home'})." -name .zfs |"); while(<FIND>) { s/\r|\n//g; s/^\Q$d->{'home'}\E\///; push(@xlist, $_); } close(FIND); } &open_tempfile(XTEMP, ">$xtemp"); foreach my $x (@xlist) { if ($homefmt && $config{'compression'} == 3) { &print_tempfile(XTEMP, "$x\n"); } else { &print_tempfile(XTEMP, "./$x\n"); } } &close_tempfile(XTEMP); # Work out incremental flags local ($iargs, $iflag, $ifile, $ifilecopy); if (&has_incremental_tar() && $increment != 2) { if (!-d $incremental_backups_dir) { &make_dir($incremental_backups_dir, 0700); } $ifile = "$incremental_backups_dir/$d->{'id'}"; if (!$_[4]) { # Force full backup &unlink_file($ifile); } else { # Add a flag file indicating that this was an incremental, # and take a copy of the file so we can put it back as before # the backup (as tar modifies it) if (-r $ifile) { $iflag = "$d->{'home'}/.incremental"; &open_tempfile_as_domain_user( $d, IFLAG, ">$iflag", 0, 1); &close_tempfile_as_domain_user($d, IFLAG); $ifilecopy = &transname(); ©_source_dest($ifile, $ifilecopy); } } $iargs = "--listed-incremental=$ifile"; } # Create the dest file with strict permissions local $qf = quotemeta($file); local $toucher = "touch $qf && chmod 600 $qf"; if ($asd && $homefmt) { $toucher = &command_as_user($asd->{'user'}, 0, $toucher); } &execute_command($toucher); # Create the writer command. This will be run as the domain owner if this # is the final step of the backup process, and if the owner is doing the backup. local $writer = "cat >$qf"; if ($asd && $homefmt) { $writer = &command_as_user($asd->{'user'}, 0, $writer); } # If encrypting, add gpg to the pipeline - unless encryption is being done # at a higher level if ($key && $homefmt) { $writer = &backup_encryption_command($key)." | ".$writer; } # Do the backup if ($homefmt && $config{'compression'} == 0) { # With gzip $cmd = &make_tar_command("cfX", "-", $xtemp, $iargs, "."). " | gzip -c $config{'zip_args'}"; } elsif ($homefmt && $config{'compression'} == 1) { # With bzip $cmd = &make_tar_command("cfX", "-", $xtemp, $iargs, "."). " | ".&get_bzip2_command()." -c $config{'zip_args'}"; } elsif ($homefmt && $config{'compression'} == 3) { # ZIP archive $cmd = "zip -r -x\@$xtemp - ."; } else { # Plain tar $cmd = &make_tar_command("cfX", "-", $xtemp, $iargs, "."); } $cmd .= " | $writer"; local $ex = &execute_command("cd ".quotemeta($d->{'home'})." && $cmd", undef, \$out, \$out); &unlink_file($iflag) if ($iflag); ©_source_dest($ifilecopy, $ifile) if ($ifilecopy); if (-r $ifile) { # Make owned by domain owner, so tar can read in future &set_ownership_permissions($d->{'uid'}, $d->{'gid'}, 0700, $ifile); } if ($ex || !-s $file) { &$second_print(&text($cmd =~ /^\S*zip/ ? 'backup_dirzipfailed' : 'backup_dirtarfailed', "<pre>".&html_escape($out)."</pre>")); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } # show_backup_dir(&options) # Returns HTML for the backup logs option sub show_backup_dir { local ($opts) = @_; return &ui_checkbox("dir_logs", 1, $text{'backup_dirlogs'}, !$opts->{'dirnologs'})." ". &ui_checkbox("dir_homes", 1, $text{'backup_dirhomes'}, !$opts->{'dirnohomes'}); } # parse_backup_dir(&in) # Parses the inputs for directory backup options sub parse_backup_dir { local %in = %{$_[0]}; return { 'dirnologs' => $in{'dir_logs'} ? 0 : 1, 'dirnohomes' => $in{'dir_homes'} ? 0 : 1 }; } # show_restore_dir(&options, &domain) # Returns HTML for mail restore option inputs sub show_restore_dir { local ($opts) = @_; return &ui_checkbox("dir_homes", 1, $text{'restore_dirhomes'}, !$opts->{'dirnohomes'})."<br>\n". &ui_checkbox("dir_delete", 1, $text{'restore_dirdelete'}, $opts->{'delete'}); } # parse_restore_dir(&in, &domain) # Parses the inputs for mail backup options sub parse_restore_dir { local %in = %{$_[0]}; return { 'dirnohomes' => !$in{'dir_homes'}, 'delete' => $in{'dir_delete'} }; } # restore_dir(&domain, file, &options, &all-options, homeformat?, &oldd, # asowner, &key) # Extracts the given tar file into server's home directory sub restore_dir { local ($d, $file, $opts, $allopts, $homefmt, $oldd, $asd, $key) = @_; &$first_print($text{'restore_dirtar'}); # Check for free space, if possible my $osize = &get_compressed_file_size($file, $key); if ($osize && $config{'home_quotas'}) { &foreign_require("mount"); my @space = &mount::disk_space(undef, $config{'home_quotas'}); if (@space && $space[1]*1024 < $osize) { # Won't fit! &$first_print(&text('restore_edirspace', &nice_size($osize), &nice_size($space[1]*1024))); } } local $iflag = "$d->{'home'}/.incremental"; &unlink_file($iflag); if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($d, 1, 1); } # Create exclude file, to skip local system-specific files local $xtemp = &transname(); &open_tempfile(XTEMP, ">$xtemp"); my @exc = ( "cgi-bin/lang", # Used by AWstats, and created locally .. so "cgi-bin/lib", # no need to include in restore. "cgi-bin/plugins", "public_html/icon", "public_html/awstats-icon", ".backup"); if ($opts->{'dirnohomes'}) { push(@exc, "homes"); } foreach my $e (@exc) { &print_tempfile(XTEMP, $e,"\n"); &print_tempfile(XTEMP, "./",$e,"\n"); } &close_tempfile(XTEMP); # Check if Apache logs were links before the restore local $alog = "$d->{'home'}/logs/access_log"; local $elog = "$d->{'home'}/logs/error_log"; local ($aloglink, $eloglink); if ($d->{'web'}) { $aloglink = readlink($alog); $eloglink = readlink($elog); } # If home dir is missing (perhaps due to deletion of /home), re-create it if (!-e $d->{'home'}) { local $uinfo; if ($d->{'unix'} || $d->{'parent'}) { local @users = &list_all_users(); ($uinfo) = grep { $_->{'user'} eq $d->{'user'} } @users; } &create_domain_home_directory($d, $uinfo); } # Turn off quotas for the domain, to prevent the import failing &disable_quotas($d); local ($out, $err); local $cf = &compression_format($file, $key); local $q = quotemeta($file); local $qh = quotemeta($d->{'home'}); local $catter; if ($key && $homefmt) { $catter = &backup_decryption_command($key)." ".$q; } else { $catter = "cat $q"; } if ($cf == 4) { # Unzip command does un-compression and un-archiving # XXX ZIP doesn't support excludes of paths :-( &execute_command("cd $qh && unzip -o $q", undef, \$out, \$out); } else { local $comp = $cf == 1 ? "gunzip -c" : $cf == 2 ? "uncompress -c" : $cf == 3 ? &get_bunzip2_command()." -c" : "cat"; local $tarcmd = &make_tar_command("xvfX", "-", $xtemp); local $reader = $catter." | ".$comp; if ($asd) { # Run as domain owner - disabled, as this prevents some files # from being written to by tar $tarcmd = &command_as_user($d->{'user'}, 0, $tarcmd); } &execute_command("cd $qh && $reader | $tarcmd", undef, \$out, \$err); } local $ex = $?; &enable_quotas($d); if ($ex) { # Errors about utime in the tar extract are ignored when running # as the domain owner &$second_print(&text('backup_dirtarfailed', "<pre>".&html_escape($err)."</pre>")); return 0; } else { # Check for incremental restore of newly-created domain, which indicates # that is is not complete my $wasincr = -r $iflag; if ($d->{'wasmissing'} && $wasincr) { &$second_print($text{'restore_wasmissing'}); } else { &$second_print($text{'setup_done'}); } &unlink_file($iflag); if ($d->{'unix'} || $d->{'parent'} && &get_domain($d->{'parent'})->{'unix'}) { # Set ownership on extracted home directory, apart from # content of ~/homes - unless running as the domain owner, # in which case ~/homes is set too &$first_print($text{'restore_dirchowning'}); &set_home_ownership($d); if ($asd && !$opts->{'dirnohomes'}) { &set_mailbox_homes_ownership($d); } &$second_print($text{'setup_done'}); } if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($d, 0, 1); } # Incremental file is no longer valid, so clear it local $ifile = "$incremental_backups_dir/$d->{'id'}"; &unlink_file($ifile); # Check if logs are links now .. if not, we need to move the files local $new_aloglink = readlink($alog); local $new_eloglink = readlink($elog); if ($d->{'web'} && !$d->{'subdom'} && !$d->{'alias'}) { local $new_alog = &get_website_log($d, 0); local $new_elog = &get_website_log($d, 1); if ($aloglink && !$new_aloglink) { &system_logged("mv ".quotemeta($alog)." ". quotemeta($new_alog)); } if ($eloglink && !$new_eloglink) { &system_logged("mv ".quotemeta($elog)." ". quotemeta($new_elog)); } } # For a non-incremental restore, delete files that weren't in the backup # XXX make optional if (!$wasincr && $cf != 4 && $opts->{'delete'}) { # Parse tar output to find files that were restored my %restored; foreach my $l (split(/\r?\n/, $out)) { $l =~ s/^\.\///; $l =~ s/\/$//; $restored{$l} = 1; } # Find files that exist now my @existing; &open_execute_command(FIND, "cd ".quotemeta($d->{'home'})." && ". "find . -print", 1, 1); while(my $l = <FIND>) { $l =~ s/\r|\n//g; $l =~ s/^\.\///; push(@existing, $l); } # Add standard dirs to exclude list foreach my $dir (&virtual_server_directories($d)) { push(@exc, $dir->[0]); } push(@exc, ".backup.lock"); push(@exc, "virtualmin-backup"); push(@exc, "logs"); # Some backups don't include logs push(@exc, "homes"); # or homes dirs push(@exc, &get_backup_excludes($d)); # Delete those that weren't in tar, except for excluded dirs foreach my $f (@existing) { next if ($restored{$f}); next if ($f eq "." || $f eq ".." || $f =~ /\/\.$/ || $f =~ /\/\.\.$/); next if ($f =~ /\/\.zfs$/ || $f eq ".zfs"); # Check if on exclude list my $skip = 0; foreach my $e (@exc) { if ($f eq $e || $f =~ /^\Q$e\E\//) { $skip = 1; } } next if ($skip); # Can delete the file &unlink_logged("$d->{'home'}/$f"); } } return 1; } } # set_home_ownership(&domain) # Update the ownership of all files in a server's home directory, EXCEPT # the homes directory which is used by mail users sub set_home_ownership { local ($d) = @_; local $hd = $config{'homes_dir'}; $hd =~ s/^\.\///; local $gid = $d->{'gid'} || $d->{'ugid'}; foreach my $sd ($d, &get_domain_by("parent", $d->{'id'})) { if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($sd, 1); } } my @subhomes; if (!$d->{'parent'}) { foreach my $sd (&get_domain_by("parent", $d->{'id'})) { push(@subhomes, " | grep -v ".quotemeta("$sd->{'home'}/$hd/")); } } &system_logged("find ".quotemeta($d->{'home'})." ! -type l ". " | grep -v ".quotemeta("$d->{'home'}/$hd/"). " | grep -v .nodelete". join("", @subhomes). " | sed -e 's/^/\"/' | sed -e 's/\$/\"/' ". " | xargs chown $d->{'uid'}:$gid"); &system_logged("chown $d->{'uid'}:$gid ". quotemeta($d->{'home'})."/".$config{'homes_dir'}); foreach my $dir (&virtual_server_directories($d)) { &set_ownership_permissions(undef, undef, oct($dir->[1]), $d->{'home'}."/".$dir->[0]); } foreach my $user (&list_domain_users($d, 1, 1, 1, 1)) { next if ($user->{'webowner'}); next if (!$user->{'unix'}); next if ($user->{'nocreatehome'}); next if (!&is_under_directory("$d->{'home'}/$hd", $user->{'home'})); next if ("$d->{'home'}/$hd" eq $user->{'home'}); &system_logged("chown -R $user->{'uid'}:$user->{'gid'} ". quotemeta($user->{'home'})); } foreach my $sd ($d, &get_domain_by("parent", $d->{'id'})) { if (defined(&set_php_wrappers_writable)) { &set_php_wrappers_writable($sd, 0); } } return undef; } # set_mailbox_homes_ownership(&domain) # Set the owners of all directories under ~/homes to their mailbox users sub set_mailbox_homes_ownership { local ($d) = @_; local $hd = $config{'homes_dir'}; $hd =~ s/^\.\///; local $homes = "$d->{'home'}/$hd"; foreach my $user (&list_domain_users($d, 1, 1, 1, 1)) { if (&is_under_directory($homes, $user->{'home'}) && !$user->{'webowner'} && $user->{'home'}) { &system_logged("find ".quotemeta($user->{'home'}). " | sed -e 's/^/\"/' | sed -e 's/\$/\"/' ". " | xargs chown $user->{'uid'}:$user->{'gid'}"); } } } # virtual_server_directories(&dom) # Returns a list of sub-directories that need to be created for virtual servers sub virtual_server_directories { local ($d) = @_; local $tmpl = &get_template($d->{'template'}); local $perms = $tmpl->{'web_html_perms'}; return ( $d->{'subdom'} || $d->{'alias'} ? ( ) : ( [ &public_html_dir($d, 1), $perms ] ), $d->{'subdom'} || $d->{'alias'} ? ( ) : ( [ &cgi_bin_dir($d, 1), $perms ] ), [ 'logs', '750' ], [ $config{'homes_dir'}, '755' ] ); } # create_server_tmp(&domain) # Creates the temporary files directory for a domain, and returns the path sub create_server_tmp { local ($d) = @_; if ($d->{'dir'}) { local $tmp = "$d->{'home'}/tmp"; if (!-d $tmp) { &make_dir_as_domain_user($d, $tmp, 0750, 1); } return $tmp; } else { # For domains without a home return "/tmp"; } } # show_template_dir(&tmpl) # Outputs HTML for editing directory-related template options sub show_template_dir { local ($tmpl) = @_; # The skeleton files directory print &ui_table_row(&hlink($text{'tmpl_skel'}, "template_skel"), &none_def_input("skel", $tmpl->{'skel'}, $text{'tmpl_skeldir'}, 0, $tmpl->{'standard'} ? 1 : 0, undef, [ "skel", "skel_subs", "skel_nosubs", "skel_onlysubs" ])."\n". &ui_textbox("skel", $tmpl->{'skel'} eq "none" ? undef : $tmpl->{'skel'}, 40)); # Perform substitions on skel file contents print &ui_table_row(&hlink($text{'tmpl_skel_subs'}, "template_skel_subs"), &ui_yesno_radio("skel_subs", int($tmpl->{'skel_subs'}))); # File patterns to exclude print &ui_table_row(&hlink($text{'tmpl_skel_nosubs'}, "template_skel_nosubs"), &ui_textbox("skel_nosubs", $tmpl->{'skel_nosubs'}, 60)); # File patterns to include print &ui_table_row(&hlink($text{'tmpl_skel_onlysubs'}, "template_skel_onlysubs"), &ui_textbox("skel_onlysubs", $tmpl->{'skel_onlysubs'}, 60)); } # parse_template_dir(&tmpl) # Updates directory-related template options from %in sub parse_template_dir { local ($tmpl) = @_; # Save skeleton directory $tmpl->{'skel'} = &parse_none_def("skel"); if ($in{"skel_mode"} == 2) { -d $in{'skel'} || &error($text{'tmpl_eskel'}); $tmpl->{'skel_subs'} = $in{'skel_subs'}; $tmpl->{'skel_nosubs'} = $in{'skel_nosubs'}; $tmpl->{'skel_onlysubs'} = $in{'skel_onlysubs'}; } } # create_index_content(&domain, content) # Create an index.html file containing the given text sub create_index_content { local ($d, $content) = @_; local $dest = &public_html_dir($d); local @indexes = grep { -f $_ } glob("$dest/index.*"); if (@indexes) { &unlink_file(@indexes); } &open_tempfile_as_domain_user($d, DESTOUT, ">$dest/index.html"); &print_tempfile(DESTOUT, $content); &close_tempfile_as_domain_user($d, DESTOUT); } $done_feature_script{'dir'} = 1; 1;y~or5J={Eeu磝Qk ᯘG{?+]ן?wM3X^歌>{7پK>on\jy Rg/=fOroNVv~Y+ NGuÝHWyw[eQʨSb> >}Gmx[o[<{Ϯ_qFvM IENDB`