virtual-server/0040775000567100000120000000000010042202017013522 5ustar jcameronwheelvirtual-server/images/0040775000567100000120000000000010001720621014770 5ustar jcameronwheelvirtual-server/images/up.gif0100644000567100000120000000013407637257321016123 0ustar jcameronwheelGIF89a!,3tANfznTȁQi9j*: SXOS<$@;virtual-server/images/down.gif0100644000567100000120000000015307637257327016455 0ustar jcameronwheelGIF89a!,B˝aR h=zh5٘ӽRais2F{|kv WBU7c1H1 $i;virtual-server/images/icon.gif0100644000567100000120000000311707677547264016447 0ustar jcameronwheelGIF89a00Bzv"~RҢRvvvVVVnξvn޶"2~ƲfƆBnJNΎ2ʎzvz:nFjFf.RBBBfκ޶:ΒrB.֦~"Z~ƶBZRR.~⢦&ʊzzzŽBfƾ~."bfv6vrRNʎN:ޚ&BJrjbʾfffζnfRBVbVn&ʊʞ~Z*nB:"6斆*‚BNn2®2ƮVζBbv^vz▂bnڮ.f¶BrҚƂrz,00} H*\Ç#:dH੊N!"A ( uF=fzp$PAxeC_X$Tb iS^t&KC7-(їd,ʣ`2"HČu9BIX&cѓ { 2ѡL]ŸǎŢU0^-EDe a GP8|"ϋѨ*T@I+_vt+Z(ܫA5kUeb -v9 {\C~Z|1f-ɱ&va/1`ѭW!P(K,v-&XE)J-iDKF׍8xEa$FM"0VdFB6/55p$M:f^hIMRї&HBj>dF, 1B<'C kABB)@a„)D5*'fr0C!EG.BKFxaB\GqDI)CV| FŤ^|R/D @"$@CeK/^<#3CDG$&t1Rt s %bKb-dP!.dǾ`Ň+euh^bz}8vUOKE_Cd2Yqņ^1̶վc8\:^OmCXC*.(3jܨQǏ CI ;virtual-server/images/aliases.gif0100644000567100000120000000061507244714645017125 0ustar jcameronwheelGIF89a00fff!Made with GIMP!,00I8;`(d zl뾰N`DOB+ _pF4: R8tZ Щt@Ծ-/ɇ }wv^Μq8utmz|~iaFK{}\7bpaqVTT3˦ϝ)&')ߞha>ZđHR@+PcXeʑԐz0]εĂ5xIsP P:Hqc)* #HY|49J;z+bɁ%25ųgk@N;virtual-server/images/web.gif0100664000567100000120000000265007677514410016262 0ustar jcameronwheelGIF89a@0rvv悊򊒎v~zz~Ҿ~~¾ʢ斞Ɩºrzvz~~޺¾ƞʶκ⦪򲶲Ɗ梦vzzڎ֎,@0;J7JL/e]/imOEleQK-J"eU;;` ;B-21UƖBIVm8;7`"/ҊC@6VGFOoCLiQjbb!_ N-μByH0AI.P0ہJ\\9P"ACb!8n8֤xiXàHAL C"A P@!0^f1Eac !_\@Whȅ.K(0$7 hC A``Cr!]pW`; >w  $ hL!H*\PXpY`, Р`i0! U</T3S@!4Aķ);|q \5 ̸M0N<d:0j #4@oPH *Ba86 2D dwW@\Qx00ؔ 1:#@PGLAC!81*`h%Y@ C`8! K!$\N\] R. @TBmN< T Q@b䁈"Gt39H94 ?a:B / p l؁6!?\N-( v[ A!aT%Q #dnD`xF&hC2<QGy`㍓E |x#% Ol\0k"'BB m I(Ad Zs`%#>@m0&QvC"Ln%%@n@FQ渐 @#u,]pHCkDs2RmD"QPa \B c!\rK~8DVnQǒ @Wl Y}h0$=3Y \"kHl@Bp%^g)L1˛ CpQRh$YQAkّfGq i@"P0E$H`b"0=\` \ 2<<7D!{LFo <o;U0g"&Hೝ r Nr\`mЄ`t , Ȩw!:`7FEH.CAb=H9P)\;virtual-server/images/newuser.gif0100644000567100000120000000055710001705650017156 0ustar jcameronwheelGIF89a00fff!Made with GIMP!,00I8ͻ`(di@A.8][7ϭ+PĢhJ.ǏIevlz[IKV'zn't>euh^bz}8vUOKE_Cd2Yqņ^1̶վc8\:^OmCXC*.(3jܨQǏ CI ;virtual-server/images/newdom.gif0100644000567100000120000000311707740465504016773 0ustar jcameronwheelGIF89a00Bzv"~RҢRvvvVVVnξvn޶"2~ƲfƆBnJNΎ2ʎzvz:nFjFf.RBBBfκ޶:ΒrB.֦~"Z~ƶBZRR.~⢦&ʊzzzŽBfƾ~."bfv6vrRNʎN:ޚ&BJrjbʾfffζnfRBVbVn&ʊʞ~Z*nB:"6斆*‚BNn2®2ƮVζBbv^vz▂bnڮ.f¶BrҚƂrz,00} H*\Ç#:dH੊N!"A ( uF=fzp$PAxeC_X$Tb iS^t&KC7-(їd,ʣ`2"HČu9BIX&cѓ { 2ѡL]ŸǎŢU0^-EDe a GP8|"ϋѨ*T@I+_vt+Z(ܫA5kUeb -v9 {\C~Z|1f-ɱ&va/1`ѭW!P(K,v-&XE)J-iDKF׍8xEa$FM"0VdFB6/55p$M:f^hIMRї&HBj>dF, 1B<'C kABB)@a„)D5*'fr0C!EG.BKFxaB\GqDI)CV| FŤ^|R/D @"$@CeK/^<#3CDG$&t1Rt s %bKb-dP!.dǾ`Ň+"$n#ľ&s%c{ aȾgo$NZ&d0(69U5# ՊarW&OZ3ٚNS3E)P8m>  >tsJM :A&Q: cEۅ3,t䪋+{ 8vF8@#\`T-<0\)1ɕ[(9Ġg;virtual-server/images/newdns.gif0100644000567100000120000000373707742727140017007 0ustar jcameronwheelGIF89a00vDD/DxbbƄpәfdhb&TӢ""fF\j vvŹRRS43 rrq՘T62\ȂX"4\fff"< >><\ĨH4ƾܴȹi||W`\`͕ܶ ̕~o55,{ull8'~&[Ƅl*&@z2lZ|ڲvBlJJR>LB*6dNF\v¾trnrnDb^$bbTvlۮLΙ^ZtNJ  nBdZT\^޴̮̚rҞrn$$~:l}ff ĖѶ\vvt\m!Made with GIMP,00 H*\ȰÇ#JHR:pb1Lp`JQfyvAzg&0uaPܦ4fbx*(==2\)J > (GX>|P(. e-P3dS ym" yp.APJat\y(&H(A"Y.YZbtM!*1 BdF:g,*ќa" .o1{كG EΞ2yaG4\^\V)5ހ >h6>B25s(S?wA)^B2@=4䠇 ,ĸH75X{> t%Л=y@y" ?F7HnJgA (^ڀd=O2w*ASA@G>=б"C {JzIO®C7 S8rCPJ=j& 'A >G+bZ/I@F莱d˚[;virtual-server/lang/0040775000567100000120000000000010041665607014464 5ustar jcameronwheelvirtual-server/lang/de0100755000567100000120000005727310002735631015003 0ustar jcameronwheel# de-File for Virtualmin Virtuelle Server ###################################################################### # Last patched: 06.08.2003 Martin Mewes for WEBMIN - MM # Questions, comments, snide-remarks: webmin@webmin.mamemu.de ###################################################################### index_title=Virtualmin Virtuelle Server index_title2=Virtuelle eMail index_add=Lege einen neuen Virtuellen Server an. index_import=Übernehme eine existierende Domaine als Virtuellen Server. index_domain=Name der Domain index_user=Unix-Benutzername index_owner=Beschreibung index_web=Webseite? index_webalizer=Webalizer? index_dns=DNS? index_mysql=MySQL? index_postgres=PostgreSQL? index_mail=Mailboxes index_alias=Aliases index_none=Es wurden noch keine Virtuellen Server eingerichtet. index_return=Liste der Virtuellen Server index_list=auflisten.. ###################################################################### index_eapache=Der Apache-Webserver scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's Apache Webserver-Modul nicht richtig eingerichtet. Wenn Ihr System den Apache als Webserver nicht benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration deaktivieren. index_ebind=Der BIND-DNS-Server in der Version 8 oder 9 scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's BIND DNS Server-Modul nicht richtig eingerichtet. Wenn Ihr System den BIND als Webserver nicht benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration deaktivieren. index_email=Keiner der unterstützten Mail-Servers (Sendmail und Postfix) wurde auf Ihrem System erkannt. Vielleicht sind sie nicht installiert oder die zugehörigen Webmin-Module wurden nicht richtig eingerichtet. index_emysql=MySQL scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's MySQL Datenbank-Modul nicht richtig eingerichtet. Wenn Ihr System MySQL nicht benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration deaktivieren. index_epostgres=PostgreSQL scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's PostgreSQL-Datenbank-Modul nicht richtig eingerichtet. Wenn Ihr System PostgreSQL nicht benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration deaktivieren. index_ewebalizer=Webalizer scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's Webalizer-Logfile-Analyse-Modul nicht richtig eingerichtet. Wenn Ihr System WebAlizer nicht benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration deaktivieren. index_esendmail=Der Sendmail-Mail-Server scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's Sendmail-Konfiguration-Modul nicht richtig eingerichtet. Wenn Ihr System einen anderen Mail-Server benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration einrichten. index_epostfix=Der Postfix-Mail-Server scheint nicht auf Ihrem System installiert zu sein oder er wurde in Webmin's POstfix-Konfiguration-Modul nicht richtig eingerichtet. Wenn Ihr System einen anderen Mail-Server benutzt, so sollten Sie dies in Virtualmin's Modul-Konfiguration einrichten. index_eiface=Auf Ihrem System wurde kein Netzwerk-Interface erkannt. Bitte benutzen Sie die Modul-Konfiguration um ein Netzwerk-Interface manuell einzutragen. ###################################################################### index_astart=Starte Apache index_astartdesc=Der Apache-Webserver läuft momentan nicht. Das bedeutet, daß alle virtuellen Webserver zur Zeit nicht erreichbar sind. Klicken Sie auf diesen Button, um den Webserver zu starten. index_astop=Stoppe Apache index_astopdesc=Der Apache-Webserver läuft und liefert Webseiten aus. Klicken Sie auf den Button, um den Webserver zu stoppen. ###################################################################### index_bstart=Starte BIND index_bstartdesc=Der BIND-DNS-Server läuft momentan nicht. Das bedeutet, daß sämtliche DNS-Domainen, die auf diesem Server gehostet werden, nicht via DNS aufgelöst werden können. Klicken Sie auf diesen Button, um den DNS-Server zu starten. index_bstop=Stoppe BIND index_bstopdesc=Der BIND-DNS-Server läuft und bietet Namensauflösung fr alle Domainen an, die auf diesem Server gehostet werden. Klicken Sie auf den Button, um den DNS-Server zu stoppen. ###################################################################### index_mstart=Starte Mail-Server index_mstartdesc=Der konfigurierte Mail-Server läuft momentan nicht. Das bedeutet, daß dieser Server keine eMails für die Virtuellen Server annehmen kann. Klicken Sie auf diesen Button, um den Mail-Server zu starten index_mstop=Stoppe Mail-Server index_mstopdesc=Der konfigurierte Mail-Server läuft und nimmt eMails für Ihre Virtuellen Domainen an. Klicken Sie auf den Button, um den Mail-Server zu stoppen. ###################################################################### index_ehomemtab=Das Modul konnte keinen Mount-Point für Ihre Home-Verzeichnisse im Verzeichnis $1 finden. Das Editieren von Quota wird abgeschaltet. index_emailmtab=Das Modul konnte keinen Mount-Point für Ihre Mail-Verzeichnisse im Verzeichnis $1 finden. Das Editieren von Quota wird abgeschaltet. index_ediff=Ihre Home- und Mail-Verzeichnisse befinden sich auf verschiedenen Dateisystemen. ($1 für Home-Verzeichnisse unter $2, wogegen $3 für Mail-Verzeichnisse unter $4). Es wird lediglich das Editieren von Quota für die Home-Verzeichnisse möglich sein. index_equota=Quotas sind für das Dateisystem $1, welches Ihre Home-Verzeichnisse in $2 beinhaltet, nicht eingerichtet. Das Editieren von Quota wird abgeschaltet. index_quota=Komplette Quota index_squota=Total alloc index_uquota=Insgesamt benutzt index_header1=Lokale Mailboxen index_header2=Virtuelle Server index_nousers=Es wurden bisher noch keine lokalen Mailboxen eingerichtet. index_uadd=Eine neue lokale Mailbox einrichten index_toomany=Es gibt zu viele virtuelle Server auf Ihrem System. Eine Anzeige ist leider nicht möglich. index_search=Finde Server wo der index_search_dom=Domain-Name index_search_user=Unix-Benutzer index_search_ip=IP-Adresse index_contains=beinhaltet index_searchok=Jetzt suchen index_nomail=Abgeschaltet form_title=Einen neuen Virtuellen Server anlegen form_ecannot=Sie dürfen keine neuen Virtuellen Server anlegen. form_desc=XXX form_header=Eigenschaften des neuen Virtuellen Servers form_domain=Name der Domain form_owner=Beschreibung form_user=Unix-Benutzername form_auto=Automatisch form_mail=Mail-Server für diese Domain einrichten? form_web=Webserver für diese Domain einrichten? form_dns=Eine DNS-Zone einrichten? form_mysql=Eine MySQL-Datenbank erzeugen? form_postgres=Eine PostgresSQL-Datenbank erzeugen? form_webalizer=Webalizer für Web-Statistiken einrichten? form_webmin=Einen Webmin-Benutzer anlegen? form_name=Details zum Webserver form_name1=Namen basierend form_name0=IP basierend form_ip=IP-Adresse für Webseite und Domaine form_pass=Passwort des Unix-Benutzers form_virt=Eine virtuelle IP-Adresse einrichten, wenn dies erforderlich ist? form_ok=Server einrichten form_quota=Komplette Quota für den gesamten Server form_uquota=Quota für den Unix-Benutzer form_b=Blöcke form_unavail=Nicht verfügbar setup_err=Beim Einrichten des Virtuellen Servers wurden ein oder mehrere Fehler gemeldet setup_edomain=Es wurde kein Name für die Domain angegeben. setup_edomain2=Diese Domain wird bereits auf Ihrem System gehostet (Meldung von Webmin). setup_eip=Fehlende oder ungültige IP-Adresse setup_eauto=Das automatische Einrichten eines Unix-Benutzers schlug fehl. Sowohl $1 als auch $2 existieren bereits auf dem System. setup_euser=Dieser Unix-Benutzer existiert bereits auf dem System. setup_euser2=Fehlender oder ungültiger Unix-Benutzername. setup_egroup=Eine Unix-Gruppe mit dem Namen $1 existiert bereits auf dem System. setup_edns=Diese Domain wird bereits auf Ihrem System gehostet (Meldung des DNS). setup_ewebmin=Dieser Webmin-Benutzer existiert bereits auf dem System. setup_eweb=Diese Domain wird bereits auf Ihrem System gehostet (Meldung des Webservers). setup_emysql=Eine MySQL-Datenbank mit dem Namen $1 existiert bereits auf dem System. setup_epostgres=Eine PostgreSQL-Datenbank mit dem Namen $1 existiert bereits auf dem System. setup_ehomebase=Das Home-Verzeichnis wurde nicht korrekt im Benutzer- und Gruppenmodul eingtragen. setup_equota=Fehlende oder ungültige Komplett-Quota für den Virtuellen Server. setup_euquota=Fehlende oder ungültige Unix-Benutzer-Quota. setup_eiface=Die Netzwerkschnittstelle $1, zu der eine virtuelle Adresse hinzugefügt wurden, existiert nicht auf dem System. setup_eiface2=Die Netzwerkschnittstelle $1, zu der eine virtuelle Adresse hinzugefügt wurden, hat keine feste IP-Adresse (Benutzen Sie eventuell DHCP für diese Netzwerkschnittstelle?) setup_ewebalizer=WebAlizer kann nicht konfiguriert werden, wenn Sie keine Webseite konfiguriert haben. setup_ecrgroup=Konnte Unix-Benutzergruppe nicht einrichten! setup_ecruser=Konnte Unix-Benutzer nicht einrichten! setup_title=Richte Virtuellen Server ein setup_group=... Erzeugen der Unix-Benutzergruppe setup_user=... Einrichten des Unix-Benutzers setup_home=... Erstelle Home-Verzeichnis setup_web=... Webseite wird eingerichtet setup_webpid=... Webserver wird neu gestartet setup_bind=... Richte DNS-Zone ein setup_bindpid=... DNS-Server wird neu gestartet setup_mysql=... Richte MySQL-Datenbank ein setup_postgres=... Richte PostgresSQL-Datenbank ein setup_webmin=... Richte Webmin-Benutzer ein setup_webminpid=... Webmin wird neu gestartet setup_doms=... eMail wird eingerichtet setup_save=... Speichere Daten des Virtuellen Servers setup_virt=... Richte virtuelle IP-Adresse ein setup_done=... Fertig! setup_notrun=... Fehler: (Meldung von Webmin: not running!" setup_quota=... Setze die Quota für den Unix-Benutzer setup_webalizer=... Periodische Webstatistiken werden eingerichtet. indom=Virtueller Server: $1 users_ecannot=Sie dürfen keine die Benutzer in dieser Domaine nicht bearbeiten. users_ecannot2=Sie dürfen lokale Benutzer nicht bearbeiten. users_title=Benutzer-Mailboxes users_name=Unix-Benutzer users_domain=Domaine users_real=Name users_pop3=POP3/FTP login users_user=Unix-Benutzer users_alias=Alias users_add=Einen Benutzer zu dieser Domain hinzufügen users_none=Bisher wurden keine Mailboxen für diese Domain eingerichtet. users_return=Benutzerliste users_size=Größe der Mailbox users_empty=Leer users_quota=Festplatten-Quota users_ftp=FTP-Zugang aktiv? users_shell=Login-Shell: $1 user_create=Mailbox einrichten user_edit=Mailbox bearbeiten user_header=Details des Benutzers user_lheader=Details des Benutzers user_user=Unix-Benutzername user_pop3=(POP3/FTP login $1) user_domain=Domaine user_real=Benutzername user_pass=Passwort user_passdef=Unverändert lassen user_passset=Ändern in .. user_err=Fehler beim Speichern der Einstellungen user_eclash=Eine Mailbox oder ein Mail-Alias mit dem gleichem Namen und gleicher Domaine exitsiert bereits. user_euser=Fehlender oder ungültiger Unix-Benutzername user_ereal=Ungültiger Benutzername user_quota=Festplatten-Quote user_used=($1 benutzt) user_equota=Fehlende oder ungültige Festplatten-Quota-Größe user_mail=Haupt-Mail-Datei user_read=(eMail lesen) user_ftp=FTP-Zugang aktivieren? user_shell=Login-Shell: $1 user_elong=Der Unix-Benutzername $1 ist länger als die maximale Länge, die von diesem System unterstützt wird ($2 Zeichen) aliases_ecannot=Sie dürfen keine Mail-Aliase bearbeiten. aliases_title=Mail-Aliase aliases_name=Weiterleitung von: aliases_domain=Domaine aliases_dest=Zielmailbox aliases_add=Einen Alias für diese Domain anlegen aliases_none=Bisher wurden keine Mail-Aliase für diese Domain eingerichtet aliases_return=Liste der Aliase alias_create=Einen Mail-Alias einrichten alias_edit=Mail-Alias bearbeiten alias_header=Mail-Alias Eigenschaften alias_name=Weiterleitung von alias_catchall=Allen Mailboxen alias_mailbox=Dieser Mailbox: alias_domain=Domaine alias_dest=an diese lokale Mailbox: alias_err=Alias konnte nicht gespeichert werden alias_ename=Fehlender oder ungültiger Mail-Alias (ein @ darf nicht eingegeben werden) alias_edest=Fehlende oder ungültige Ziel-Mailbox alias_eclash=Eine Mailbox oder ein Mail-Alias mit dem gleichem Namen und gleicher Domaine exitsiert bereits. stop_ecannot=Sie dürfen keine Server stoppen. start_ecannot=Sie dürfen keine Server starten. bstop_err=Konnte BIND nicht beenden. bstop_epid=Der Prozess läuft nicht mehr. mstop_err=Konnte den Mail-Server nicht beenden. mstart_err=Konnte den Mail-Server nicht starten. mstop_edown=Sendmail läuft nicht mehr. edit_title=Einen Virtuellen Server bearbeiten edit_ecannot=Sie dürfen diesen Virtuellen Server nicht bearbeiten. edit_header=Eigenschaften des Virtuellen Servers edit_domain=Name der Domain edit_user=Unix-Benutzername edit_owner=Beschreibung edit_passwd=Unix-Benutzer-Passwort edit_lv=Unverändert lassen edit_set=Ändern in .. edit_save=Speichern und Ausführen edit_quota=Komplete Quota des Virtuellen Servers edit_uquota=Quota des Unix-Benutzers edit_mail=Mail-Server für diese Domain einrichten? edit_web=Webserver für diese Domain einrichten? edit_dns=Eine DNS-Zone einrichten? edit_webalizer=Webalizer für Web-Statistiken einrichten? edit_mysql=Eine MySQL-Datenbank erzeugen? edit_postgres=Eine PostgresSQL-Datenbank erzeugen? edit_webmin=Einen Webmin-Benutzer anlegen? edit_delete=Löschen und Ausführen edit_desc=Wenn Sie die Webserver- oder DNS-Server-Optionen auf NEIN setzen, dann werden die Einträge entsprechend aus den Konfigurationsdateien gelöscht.
Setzen Sie die Einstellungen fr MySQL oder PostgreSQL auf NEIN, dann werden die kompletten Datenbanken ohne Sicherung gelöscht. edit_ip=IP-Addresse edit_virt=Virtuelles Interface edit_none=Kein spezifisches ausgewählt delete_title=Einen Virtuellen Server löschen delete_rusure=Sind Sie sicher, daß Sie den Virtuellen Server $1 löschen wollen?
$3 Mail-Boxen, $4 Mail-Aliase und insgesamt $2 (Webseite und Benutzerdateien) und eventuell angelegte Datenbanken werden für immer gelöscht! delete_ok=Ja, löschen delete_domain=... Lösche Konfiguration des Virtuellen Servers delete_apache=... Lösche Webseite delete_bind=... Lösche DNS-Einträge delete_mysql=... Lösche MySQL-Datenbanken delete_webmin=... Lösche Webmin-Benutzer delete_users=... Lösche Mail-Boxen delete_aliases=... Lösche Mail-Aliases delete_doms=... Lösche Mail-Server-Einstellungen delete_virt=... Lösche virtuelle IP-Adressen delete_user=... Lösche Unix-Benutzer delete_group=... Lösche Unix-Benutzergruppe delete_home=... Lösche Home-Directory des Unix-Benutzers delete_webalizer=... Lösche Webalizer-Einstellungen save_err=Konnte die Einstellungen nicht ändern save_title=Einstellungen des Servers speichern save_equota=Fehlende oder ungültige Komplett-Quota save_euquota=Fehlende oder ungültige Beuntzer-Quota save_user=... Ändere Unix-Benutzer save_domain=... Eigenschaften des Servers speichern save_quota=... Ändere Unix-Quota save_mysqlpass=... Ändere MySQL-Passwort save_webmin=... Ändere Webmin-Benutzer luser_err=Konnta die lokale Mailbox nicht speichern luser_etaken=Ein Benutzer mit gleichem Namen existert bereits. acl_domains=Domainen, die dieser Benutzer bearbeiten kann acl_all=Alle Domainen acl_sel=Anhand dieser Auswahl .. acl_create=Darf neue Domainen erstellen? acl_import=Darf Domainen importieren? acl_edit=Darf existierende Domainen modifizieren? acl_local=Darf lokale Benutzer bearbeiten? acl_stop=Darf Server-Dienste starten und stoppen? other=Anders ... search_title=Such-Ergebnisse search_none=Keine Virtuellen Server mit $1 wurden gefunden. search_results=Gefunden wurden $2 virtuelle Server mit $1 .. import_title=Importieren eines Virtuellen Servers import_desc1=Dieses Formular bringt eine bereits existierende Domain unter die Kontrolle von Virtualmin. Mail-Boxen und Aliase für diese Domaine, jegliche virtuelle Webserver und DNS-Einträge werden automatisch erkannt. Sie können auch eine bereits bestehende Datenbank mit dem zu importierenden Server einbinden. import_desc2=Wenn Sie eine Domaine importieren, dann muß das Passwort des Unix-Benutzers korrekt angegeben werden. Dieses sollte wirklich das alte Passwort des Benutzers sein, damit es keine Umstellungsschwierigkeiten gibt. Ansonsten kann es hier geändert werden. Dieses Passwort ist auch das Zugangspasswort für eventuell einzubindende oder einzurichtende MySQL- oder PostgresSQL-Datenbanken. import_desc3=Wenn die Domaine eine private IP-Adresse hat, dann müssen Sie diese unten im Formular eintragen und sicherstellen, daß diese IP von dieser Domain exklusiv benutzt wird. Fr Namen basierendes Webhosting oder Domainen, die nur für eMail-Zwecke eingesetzt werden, reichen die Default-Einstellungen der Import-Einstellungen völlig aus. import_header=Importierte Details des neuen Virtuellen Servers import_dom=Name der Domain import_user=Unix-Benutzer, dem diese Domaine gehört: import_ucr=Automatisch erstellen: import_uex=Neuer oder existierender Benutzer: import_pass=Unix-Benutzer-Passwort: import_webmin=Einen Webmin-Benutzer anlegen, um diese Domain zu administrieren? import_db=MySQL- oder PostgreSQL-Datenbankname: import_ip=IP-Addresse, welche durch den Web- und DNS-Server benutzt wird: import_err=Import gescheitert. import_eexists=Die angegebene Domaine wird bereits von diesem Modul verwaltet. import_enoip=Die angegebene IP-Adresse ist nicht aktiv in Ihrem System import_eipsame=Sie haben angegeben, daß die IP-Adresse der Domaine exklusiv zugeordnet werden soll. Es handelt sich jedoch um die System-Adresse. import_rusure=Sind Sie sicher, daß sie mit dem Import beginnen (oben fett geschrieben) wollen? import_ok=Ja, importiere diese Domain ... import_web=Importieren des virtuellen Webservers $1 mit seinem Datenverzeichnis $2. import_noweb=Ich konnte keinen virtuellen Webserver finden, der auf $1 passt. import_dns=Importieren der DNS-Einträge der Domain $1. import_nodns=Ich konnte keine DNS-Einträge finden, die auf $1 passen. import_nodb=Es wurde keine Datenbank zum Importieren angegeben. import_mysql=Importieren der MySQL-Datenbank $1. import_nomysql=Ich konnte die MySQL-Datenbank mit dem Namen $1 nicht finden. import_postgres=Importieren der PostgreSQL-Datenbank $1. import_nopostgres=Ich konnte die PostgreSQL-Datenbank mit dem Namen $1 nicht finden. import_mail=Der Mail-Server nimmt eMail fr die Domain $1 entgegen. import_nomail=Der Mail-Server nimmt eMail fr die Domain $1 entgegen. # NEW 31.07.2003 import_eipclash=Die angegebene IP-Adresse wird bereits von der Domain $1 benutzt. import_egroup=Fehlender oder ungültiger Gruppen-Name import_idesc=Ermittele Parameter für den Import ... import_virt=Kann die virtuelle IP-Adresse an das Interface $1 binden. import_novirt=Dies ist keine exklusive virtuelle IP-Adresse für diese Domain. import_user1=Erstelle automatisch den Unix-Benutzer $1 für die Domain. import_user2=Kann den vorhandenen Unix-Benutzer $1 für die Domain importieren. import_user3=Erstelle neuen Unix-Benutzer $1 für die Domain. import_group1=Erstelle automatisch eine Unix-Benutzergruppe $1 für die Mailbox-User. import_group2=Kann die vorhandene Unix-Benutzergruppe $1 fr die Mailbox-User importieren. import_group3=Erstelle neue Unix-Benutzergruppe $1 fr die Mailbox-User. import_mailboxes=Kann $1 Mailbox-Benutzer mit der primären Gruppe $2 importieren. import_webmin1=Ändere existierenden WebMin-Benutzer $1, damit er diese Domain verwalten kann. import_webmin2=Erzeuge neuen WebMin-Benutzer $1, der diese Domain verwalten kann. import_nowebmin=Kein WebMin-Benutzer für diese Domain angegeben. import_webalizer=Kann Webalizer-Report für das Logfile $1 importieren. import_nowebalizer=Webalizer ist fr das Logfile $1 bisher nicht eingerichtet. import_dirs=Erzeuge Verzeichnisse im Home-Verzeichnis import_group=Gruppe für Mailbox-Benutzer import_gdf=Automatisch erzeugen (wie Benutzername) import_gex=Neue oder existierende Gruppe import_hasvirt=Ist die IP-Addresse exklusiv der Domaine zugeordnet? import_show=Testlauf - Was würde importiert werden ... # NEW 05.08.2003 acheck_edoc=Fehlende DocumentRoot-Direktive acheck_edom=Weder die ServerName- oder ServerAlias-Direktiven beinhalten $DOM acheck_ename=Fehlende ServerName-Direktive delete_noapache=... Kein Apache-VirtualHost gefunden! delete_only=Lediglich den Server der Kontrolle durch Virtualmin entziehen und ansonsten Webseite, Benutzer und Datenbank nicht anfassen? delete_postgres=... Lösche PostgreSQL-Datenbank disable_apache=... Ersetze Webseite mit Fehlerseite disable_bind=... DNS-Zone umbenennen und deaktivieren disable_ealready=Dieser Virtuelle Server wurde bereits deaktiviert disable_mysql=... Deaktiviere den MySQL-Benutzers disable_ok=Ja, jetzt deaktivieren disable_postgres=... Deaktiviere den PostgreSQL-Benutzer disable_rusure=Sind Sie sicher, daß Sie den Virtuellen Server $1 deaktivieren möchten? Die Webseite wird mit einer Fehlerseite ersetzt. Die DNS-Zonendatei wird umbenannt. Der Mail-Server nimmt keine eMails für diese Domain mehr an. Alle Datenbanken werden für den Zugriff gesperrt. disable_title=Virtuellen Server deaktivieren disable_undo=Alle obig aufgefhrten Aktionen sind ohne Datenverlust wiederherstellbar, wenn der Virtuelle Server reaktiviert wird. disable_unix=... Deaktiviere den Unix-Benutzer disable_webmin=... Deaktiviere den WebMin-Benutzer edit_aliases=Mailalias(e) bearbeiten edit_disable=Virtuellen Server deaktivieren edit_disabled=Sätliche Einstellungen eines Virtuellen Servers können nicht bearbeitet werden, wenn dieser deaktiviert ist. edit_enable=Virtuellen Server reaktivieren edit_return=Einstellungen des Virtuellen Servers edit_users=Mailbenutzer bearbeiten enable_apache=... Stelle Webseite wieder her enable_bind=... DNS-Zone wird umbenannt und reaktiviert enable_ealready=Dieser Virtuelle Server ist nicht deaktiviert enable_mysql=... Reaktiviere den MySQL-Benutzers enable_ok=Ja, jetzt reaktivieren enable_postgres=... Reaktiviere den PostgreSQL-Benutzer enable_rusure=Sind Sie sicher, daß Sie den Virtuellen Server $1 reaktivieren möchten? Die Webseite, DNS-Zonendatei, Mail-Server-Einstellungen und Datenbanken werden auf die Werte vor der Sperrung zurückgesetzt. enable_title=Virtuellen Server reaktivieren enable_unix=... Reaktiviere den Unix-Benutzer enable_webmin=... Reaktiviere den WebMin-Benutzer form_crgroup=Gleiche Gruppe wie die Mailbenutzer-Gruppe form_exgroup=Existierende Gruppe form_group=Gruppe für Unix-Benutzer import_ereal=Die angegebene IP-Adresse wird vom Interface $1 benutzt. Diese ist nicht virtuell. index_ehomebase=Sie haben kein "Root-Verzeichnis für Home-Verzeichnisse" in der Konfiguration des "Benutzer- und Gruppen-Moduls" hinterlegt. Dieses Modul braucht jedoch diese Angaben um Benutzer anzulegen und um festzustellen, ob Speicherplatzbegrenzungen(Quota) für diese eingerichtet wurde, oder nicht. index_return2=Modul-Index save_nobind=... Diese DNS-Zone existiert nicht! save_nomysql=... Dieser MySQL-Benutzer existiert nicht! save_postgrespass=... Ändere PostgreSQL-Passwort setup_edirectives=Die Apache-Direktiven für neue Webseiten in der Modul-Konfiguration sind ungültig: $1 setup_nolog=... Es wurde keine Logfile-Direktive in der Apache-Konfiguration gefunden!virtual-server/lang/en0100664000567100000120000013137610042051107015002 0ustar jcameronwheelindex_title=Virtualmin Virtual Servers index_title2=Virtual Email index_add=Add a new virtual server. index_import=Import an existing domain as a virtual server. index_domain=Domain name index_user=Username index_owner=Description index_web=Website? index_webalizer=Webalizer? index_dns=DNS? index_mysql=MySQL? index_postgres=PostgreSQL? index_ssl=SSL? index_mail=Mailboxes index_alias=Aliases index_none=No virtual servers have been created yet. index_return=virtual servers list index_return2=module index index_list=List.. index_enet=The Network Configuration module is not supported on your operating system. Virtualmin needs this module to manage virtual network interfaces. index_eapache=The Apache webserver does not appear to be installed on your system, or has not yet been set up properly in Webmin's Apache Webserver module. If your system does not use Apache, it should be disabled in Virtualmin's module configuration page. index_ebind=The BIND DNS server version 8 or 9 does not appear to be installed on your system, or has not yet been set up properly in Webmin's BIND DNS Server module. If your system does not use BIND, it should be disabled in Virtualmin's module configuration page. index_email=None of the supported mail servers (Sendmail and Postfix) were detected on your system. Maybe they are not installed, or their Webmin modules have not been set up properly. index_emysql=MySQL does not appear to be installed and running on your system, or has not yet been set up properly in Webmin's MySQL Database module. If your system does not use MySQL, it should be disabled in Virtualmin's module configuration page. index_epostgres=PostgreSQL does not appear to be installed and running on your system, or has not yet been set up properly in Webmin's PostgreSQL Database module. If your system does not use PostgreSQL, it should be disabled in Virtualmin's module configuration page. index_ewebalizer=Webalizer does not appear to be installed on your system, or has not yet been set up properly in Webmin's Webalizer Logfile Analysis module. If your system does not use Webalizer, it should be disabled in Virtualmin's module configuration page. index_eopenssl=The $1 command was not found on your system, and it is needed to set up SSL websites. If you do not plan to host SSL sites, this feature should be disabled in Virtualmin's module configuration page. index_emodssl=The Apache configuration on your system appears to be missing the module $1, which is needed to host SSL websites. If you do not plan to host SSL sites, this feature should be disabled in Virtualmin's module configuration page. index_emodssl2=The Apache configuration on your system does not appear to be listening on port $1, which is needed to host SSL websites. If you do not plan to host SSL sites, this feature should be disabled in Virtualmin's module configuration page. index_esendmail=The Sendmail mail server does not appear to be installed on your system, or has not yet been set up properly in Webmin's Sendmail Configuration module. If you are running a different mail server, select it on the module configuration page. index_epostfix=The Postfix server does not appear to be installed on your system, or has not yet been set up properly in Webmin's Postfix Configuration module. If you are running a different mail server, select it on the module configuration page. index_eqmail=The QMail server does not appear to be installed on your system, or has not yet been set up properly in Webmin's QMail Configuration module. If you are running a different mail server, select it on the module configuration page. index_eiface=No Ethernet interface could be automatically found on your system. Use the module configuration page to set the interface manually. index_astart=Start Apache index_astartdesc=The Apache webserver is currently down, meaning that all virtual server web pages are inaccessible. Click this button to start it. index_astop=Stop Apache index_astopdesc=The Apache webserver is currently active, and serving virtual server web pages. Click this button to shut it down. index_bstart=Start BIND index_bstartdesc=The BIND DNS server is currently down, meaning that DNS domains hosted by this server will be unresolvable. Click this button to start it. index_bstop=Stop BIND index_bstopdesc=The BIND DNS server is currently active, and hosting virtual server DNS domains. Click this button to shut it down. index_mstart=Start mail server index_mstartdesc=The configured mail server is currently down, meaning that no email can be received by virtual domain mailboxes. Click this button to start it. index_mstop=Stop mail server index_mstopdesc=The configured mail server is currently active, and accepting email for virtual domain mailboxes. Click this button to stop it. index_ehomebase=The automatic home directory base is not set in the configuration of the Users and Groups module or this module. This module needs to know the base in order to create users and work out if quotas are enabled or not. index_ehomemtab=The module could not find the mount point for your home directories filesystem $1. Quotas editing has been disabled. index_emailmtab=The module could not find the mount point for your mail filesystem $1. Quotas editing has been disabled. index_ediff=Home directories and mail files are on different filesystems ($1 for home directories under $2, versus $3 for mail under $4). Only home directory quotas can be edited. index_equota=Quotas are not enabled on the filesystem $1 which contains the home directory base $2. Quotas editing has been disabled. index_equota2=Quotas are not enabled on the filesystem $1 which contains home directories under $2 and email files under $3. Quota editing has been disabled. index_equota3=Quotas are not enabled on the filesystem $1 which contains home directories under $2. Quota editing for home directories has been disabled. index_equota4=Quotas are not enabled on the filesystem $1 which contains email files under $2. Quota editing for email has been disabled. index_quota=Total quota index_squota=Total alloc index_uquota=Total used index_header1=Local Mailboxes index_header2=Virtual Servers index_header3=Server and Email Templates index_nousers=No local mailboxes have been created yet. index_uadd=Add a new local mailbox index_toomany=There are too many virtual servers on your system to display on this page. index_search=Find servers where the index_search_dom=domain name index_search_user=Unix username index_search_ip=IP address index_contains=contains index_searchok=Search Now index_nomail=Disabled index_version=Virtualmin version $1 index_esaliases=No aliases file was found in your Sendmail configuration. Maybe Sendmail is not installed properly, or another mail server is in use. index_esvirts=No address mapping (virtusers) file was found in your Sendmail configuration. Your may need to add the appropriate feature your Sendmail M4 and re-build the configuration. index_esgens=No outgoing addresses (generics) file was found in your Sendmail configuration. Your may need to add the appropriate feature your Sendmail M4 and re-build the configuration, or disable this feature in Virtualmin's module config page. index_epaliases=No aliases file was found in your Postfix configuration. Maybe no aliases maps have been defined. index_epvirts=No virtual domains file was found in your Postfix configuration. Maybe no virtual domain map has been defined. index_epgens=No sender canonical map file for outgoing addresses was found in your Postfix configuration. You should either add the appropriate map to Postfix, or disable this feature in Virtualmin's module config page. index_elocal=The local users group $1 does not exist. Maybe the module configuration is incorrect. index_sheader=Virtualmin Feature Status index_sfeatures=Available features index_squotas=Disk quotas index_squotas1=Disabled in module configuration. index_squotas2=Not active on home directories filesystem. index_squotas3=Active on home directories filesystem $1, but not on email filesystem. index_squotas3g=Active for users and groups on home directories filesystem $1, but not on email filesystem. index_squotas4=Active for users only on home directories filesystem $1, and for users on email filesystem $2. index_squotas4g=Active for users and groups on home directories filesystem $1, and email filesystem $2. index_squotas5=Active for users only on home directories and email filesystem $1. index_squotas5g=Active for users and groups on home directories and email filesystem $1. index_srefresh=Re-check and refresh configuration index_smail=Mail server index_needcheck=Virtualmin's configuration has not been checked since it was last updated. Click the button below to verify it now. index_backup=Backup Virtual Servers index_backupdesc=Click this button to perform an immediate backup. A form for choosing which servers to backup, what features to save and where to backup to will be displayed. index_sched=Scheduled Backup index_scheddesc=Click this button to schedule a regular backup. A form for choosing which servers to backup on schedule, what features to save and where to backup to will be displayed. index_restore=Restore Backup index_restoredesc=Click the button to restore a previous backup. A form for choosing the backup file, servers to extract and features to restore will be displayed. form_title=Create Virtual Server form_ecannot=You are not allowed to create virtual servers form_desc=XXX form_header=New virtual server details form_domain=Domain name form_owner=Description form_email=Contact email address form_email_def=Unix user's mailbox form_email_set=Other address.. form_user=Unix username form_nwuser=Custom username form_auto=Automatic form_mgroup=Group for mailbox users form_nwgroup=Custom group name form_group=Group for Unix user form_crgroup=Same as group for mail users form_exgroup=Existing group form_mail=Accept mail for domain? form_web=Set up website for domain? form_ssl=Set up SSL website too? form_dns=Set up DNS zone? form_mysql=Create MySQL database? form_postgres=Create PostgresSQL database? form_webalizer=Set up Webalizer for web logs? form_webmin=Create Webmin login? form_name=Web server type form_name1=Name-based form_name0=IP-based form_ip=IP address for website and domain form_pass=Unix user's password form_virt=Add virtual IP address if needed? form_ok=Create Server form_quota=Total quota for entire server form_uquota=Quota for Unix user form_b=blocks form_k=kB form_unavail=Not available form_mailbox=Create email address for unix user? form_mailboxlimit=Maximum allowed mailboxes form_unlimit=Unlimited form_atmost=At most form_proxy=Proxy entire website to URL form_plocal=Serve locally form_purl=Web URL form_iface=Network interface form_shared=Shared, on IP $1 form_vip=Virtual interface with IP setup_err=Failed to create virtual server setup_edomain=Missing or invalid domain name setup_edomain2=You are already hosting this domain setup_eip=Missing or invalid IP address setup_eauto=A free automatically chosen Unix username could not be found (both $1 and $2 already exist) setup_euser=The specified Unix user already exists setup_euser2=Missing or invalid Unix username setup_egroup=A Unix group named $1 already exists setup_egroup2=Missing or invalid mailbox Unix group name setup_egroup3=The selected group for the Unix user must be different from the group $1 created for mailbox users setup_edns=The DNS domain $1 is already hosted by your DNS server setup_eunix=A unix user called $3 or group called $4 already exists setup_ewebmin=A webmin user called $3 already exists setup_eweb=The domain $1 is already hosted by your Apache webserver setup_emysql=A MySQL database called $2 already exists setup_epostgres=A PostgreSQL database called $2 already exists setup_ehomebase=Home directory base is not set in the configuration of the Users and Groups module or this module setup_equota=Missing or invalid total quota setup_euquota=Missing or invalid Unix user's quota setup_eiface=The network interface $1 to which virtual addresses are added does not exist on your system setup_eiface2=The network interface $1 to which virtual addresses are added does not have a fixed address on your system (perhaps because it uses DHCP) setup_edepwebalizer=Webalizer cannot be enabled unless a website is configured setup_edepssl=SSL cannot be enabled unless a website is configured, and a virtual IP address allocated setup_ecrgroup=Failed to create Unix group! setup_ecruser=Failed to create Unix user! setup_edirectives=The Apache directives for new websites set on the Module Config page are not valid : $1 setup_eemail=Missing contact email address setup_emaking=Before creation command failed : $1 setup_emailbox=An email address for the unix user cannot cannot be created unless email is enabled for the server setup_mailbox=Adding email address for Unix user .. setup_eproxy=Missing or invalid proxy URL setup_emailboxlimit=Missing or invalid mailboxes limit setup_epass=Missing password for Unix user setup_eusername=The username $1 is not valid : $2 setup_eusername2=The username $1 does not begin with a letter setup_evirtclash=The virtual interface IP address is already in use setup_evirtclash2=No interface for the IP address exists setup_title=Setting Up Virtual Server setup_group=Creating Unix group $1 .. setup_user=Creating Unix user $1 .. setup_home=Creating home directory .. setup_web=Adding new virtual website .. setup_openssl=Creating SSL certificate and private key .. setup_ssl=Adding new SSL virtual website .. setup_eopenssl=.. openssl failed! $1 setup_webpid=Applying web server configuration .. setup_webpid2=Stopping and re-starting web server .. setup_bind=Adding new DNS zone .. setup_bindslave=Added slave zone on $1 .. setup_eslave=.. failed! $1 setup_bindpid=Re-starting DNS server .. setup_bindslavepid=Re-starting slave DNS server on $1 .. setup_mysql=Creating MySQL database .. setup_postgres=Creating PostgreSQL database .. setup_webmin=Creating Webmin user .. setup_webminpid=Re-starting Webmin .. setup_doms=Adding to email domains list .. setup_save=Saving server details .. setup_virt=Adding virtual IP interface .. setup_virtdone=.. created interface $1 setup_done=.. done setup_notrun=.. not running! setup_quota=Setting user's quota .. setup_webalizer=Setting up scheduled Webalizer report .. setup_nolog=.. no logging directive found in Apache configuration! setup_email=Sending email notification to domain owner .. setup_emailok=.. $1 setup_emailfailed=.. failed to send email : $1 indom=In domain $1 users_ecannot=You are not allowed to edit users in this domain users_ecannot2=You are not allowed to edit local users users_emailbox=The domain owner's mailbox cannot be edited users_title=User Mailboxes users_name=Name users_domain=Domain users_real=Real name users_pop3=POP3/FTP login users_user=User users_alias=Alias users_add=Add a user to this domain users_none=No user mailboxes have been created in this domain yet. users_return=users list users_size=Mail file size users_empty=Empty users_quota=Disk quota users_ftp=FTP login? users_shell=Has shell $1 users_main=Yes (server owner) users_limit=This server is limited to $1 mailboxes, and $2 more can be added. users_nomore=This server has reached its limit of $1 mailboxes. user_create=Create Mailbox user_edit=Edit Mailbox user_header=Virtual domain user mailbox details user_lheader=Local user mailbox details user_mheader=Virtual server Unix user's mailbox details user_user=Username user_pop3=(POP3/FTP login $1) user_domain=In domain user_real=Real name user_pass=Password user_passdef=Leave unchanged user_passset=Set to .. user_err=Failed to save mailbox user_eclash=A mailbox or mail alias with the same name and domain already exists user_eclash2=A user with the same name already exists user_euser=Missing or invalid username user_ereal=Invalid real name user_uquota=Home directory quota user_mquota=Mail file quota user_umquota=Home and mail quota user_used=($1 used) user_equota=Missing or invalid quota size user_mail=Inbox mail file user_read=(Read email) user_ftp=FTP login enabled? user_mailbox=Primary email address enabled? user_shell=Has custom shell $1 user_elong=The username $1 is longer that the maximum allowed on this system ($2 characters) user_extra=Additional email addresses user_eextra1='$1' is not a valid additional email address user_eextra2=The additional email domain '$1' is not managed by Virtualmin user_eextra3=You are not allowed to manage the additional email domain '$1' user_eextra4=A mailbox or mail alias that clashes with the additional address '$1' already exists user_home=Home directory user_home1=Automatic user_home0=Specific directory $1 user_ehome=Missing or invalid home directory user_emkhome=Home directory $1 already exists user_edelete=You cannot delete the virtual server Unix user! user_aliases=Email forwarding destinations user_return=mailbox user_emailboxlimit=This server has reached its limit on allowed mailboxes user_delete=Delete Mailbox user_rusure=Are you sure you want to delete the mailbox $1? $2 of email and $3 of files in the home directory $4 will be deleted. user_deleteok=Delete Now aliases_ecannot=You are not allowed to edit aliases in this domain aliases_title=Mail Aliases aliases_name=Name aliases_domain=Domain aliases_dests=Alias destinations aliases_add=Add an alias to this domain aliases_none=No mail aliases have been created in this domain yet. aliases_return=aliases list aliases_type1=Address $1 aliases_type2=Addresses in file $1 aliases_type3=File $1 aliases_type4=Program $1 aliases_type5=Autoreply file $1 aliases_type6=Apply filter file $1 aliases_type7=User $1 aliases_dnone=None alias_create=Create Mail Alias alias_edit=Edit Mail Alias alias_header=Mail forwarding alias details alias_name=Name alias_catchall=All mailboxes alias_mailbox=Mailbox alias_domain=Domain alias_dests=Alias destinations alias_type0=None alias_type1=Email address .. alias_type2=Addresses in file .. alias_type3=Write to file .. alias_type4=Feed to program .. alias_type5=Autoreply from file .. alias_type6=Apply filter file .. alias_type7=Mailbox of user .. alias_err=Failed to save alias alias_ename=Missing or invalid alias name (no @ should be included) alias_edest=Missing alias destination alias_eclash=A mailbox or mail alias with the same name and domain already exists alias_etype1='$1' is not a valid email address alias_etype2=Addresses file '$1' is not valid or does not exist alias_etype3='$1' is not a valid filename alias_etype4='$1' is not a valid program or does not exist alias_etype5=Autoreply file '$1' is not valid alias_etype4none=No program given alias_etype6=Filter file '$1' is not valid alias_etype7=User '$1' does not exist alias_enone=No destinations entered alias_afile=Edit.. alias_return=alias alias_etype=You cannot create aliases of this type alias_eclash2=A mail alias called $1 already exists stop_ecannot=You are not allowed to stop servers start_ecannot=You are not allowed to start servers bstop_err=Failed to stop BIND bstop_epid=Process is no longer running mstop_err=Failed to stop mail server mstart_err=Failed to start mail server mstop_edown=Sendmail is no longer running edit_title=Edit Server edit_ecannot=You are not allowed to edit this virtual server edit_header=Virtual server details edit_domain=Domain name edit_user=Unix username edit_owner=Description edit_email=Contact email edit_email_def=Unix user's mailbox edit_passwd=Unix password edit_lv=Leave unchanged edit_set=Set to .. edit_save=Save Virtual Server edit_quota=Total server quota edit_uquota=Unix user's quota edit_mailquota=Space used by mail users edit_userquota=Space used by Unix user edit_mail=Mail for domain enabled? edit_web=Web virtual server enabled? edit_ssl=SSL website enabled? edit_dns=DNS domain enabled? edit_webalizer=Webalizer reporting enabled? edit_mysql=MySQL database enabled? edit_postgres=PostgreSQL database enabled? edit_webmin=Webmin login enabled? edit_delete=Delete Virtual Server edit_disable=Disable Virtual Server edit_enable=Enable Virtual Server edit_desc=Changing the web or DNS server options to No will delete their entries from the Apache or BIND configuration files. Similarly, changing the MySQL or PostgreSQL options to No will delete the contents of those databases. edit_disabled= Virtual server features such as the website and DNS domain cannot be added or removed while the server is disabled. edit_ip=IP address edit_virt=Virtual interface edit_virtnone=None edit_virtalloc=Use IP edit_return=virtual server details edit_users=Edit Mail Users edit_aliases=Edit Mail Aliases edit_qon=$1 on $2 delete_title=Delete Server delete_rusure2=Are you sure you want to delete the virtual server $1, which has $2 of files? The following features will be deleted : delete_mailboxes=Mailbox and aliases - $1 mailboxes and $2 mail aliases will be deleted, including all their mail files and home directories. delete_ok=Yes, Delete It delete_only=Only remove server from Virtualmin's control, and leave website, users and databases untouched delete_domain=Deleting server details .. delete_apache=Deleting virtual website .. delete_noapache=.. no Apache virtual host found! delete_bind=Deleting DNS zone .. delete_bindslave=Deleting slave DNS zone on $1 .. delete_mysql=Deleting MySQL database .. delete_postgres=Deleting PostgreSQL database .. delete_webmin=Deleting Webmin login .. delete_ssl=Deleting SSL virtual website .. delete_users=Deleting mailboxes .. delete_aliases=Deleting mail aliases .. delete_doms=Removing from email domains list .. delete_virt=Removing virtual IP interface .. delete_novirt=.. not removing interface $1 because it is not virtual delete_user=Deleting Unix user .. delete_group=Deleting Unix group .. delete_home=Delete home directory .. delete_webalizer=Deleting scheduled Webalizer report .. delete_emaking=Before deletion command failed : $1 save_err=Failed to modify server save_title=Save Server save_equota=Missing or invalid total quota save_euquota=Missing or invalid Unix user's quota save_user=Modifying Unix user .. save_domain=Saving server details .. save_quota=Changing Unix quota .. save_mysqlpass=Changing MySQL password .. save_postgrespass=Changing PostgreSQL password .. save_webmin=Updating Webmin user .. save_apache=Changing IP address of virtual website .. save_dns=Changing IP address in DNS domain .. save_nomysql=.. MySQL user does not exist! save_nobind=.. DNS zone does not exist! save_emaking=Before modification command failed : $1 save_rusure=Are you sure you want to save the domain $1? The following features have been selected for deletion : save_dok=Yes, Save Now luser_err=Failed to save local mailbox luser_etaken=A user with the same name already exists acl_domains=Domains this user can manage acl_all=All domains acl_sel=Selected below .. acl_create=Can create new domains? acl_import=Can import existing domains? acl_edit=Can edit existing domains? acl_local=Can edit local users? acl_stop=Can start and stop services? other=Other... search_title=Search Results search_none=No virtual servers containing $1 were found. search_results=Found $2 virtual servers matching $1 .. import_title=Import Virtual Server import_desc1=This form can be used to bring an existing domain on your system under the control of Virtualmin. Mailboxes and aliases for the domain name, any existing Apache virtual server and DNS domain will be automatically detected. You can also enter the name of a database to associate with the domain, if any exist. import_desc2=The password field should be filled in with the Unix user's current password, if you know it. Virtualmin needs to know each virtual server's password, for use when setting up MySQL or PostgreSQL databases in future. import_desc3=If the domain has a private IP address, you must enter it at the bottom of this form and indicate that the IP is used exclusively by this site. For name-based websites or domains that only host email, the default IP import settings will work fine. import_header=Imported virtual server details import_dom=Domain name import_user=Unix user who owns the domain import_ucr=Create automatically import_uex=New or existing specified user import_pass=Unix user's password import_group=Group for mailbox users import_gdf=Create automatically (same as username) import_gex=New or existing specified group import_webmin=Create Webmin login to manage server? import_db=MySQL or PostgreSQL database name import_ip=IP address used by Apache and DNS import_hasvirt=IP address is unique to domain? import_show=Show What Will Be Imported .. import_err=Import failed import_eexists=The specified domain is already been managed by Virtualmin import_enoip=The specified IP address is not active on your system. import_eipsame=You indicated that the IP is unique to this domain, but it is the systems default address. import_eipclash=The specified IP address is already used by domain $1. import_ereal=The specified IP address is used by the interface $1, which is not virtual import_egroup=Missing or invalid group name import_rusure=Are you sure you want to carry out the import actions listed above in bold? import_ok=Yes, Import Domain import_idesc=Working out what will be imported .. import_web=Can import Apache virtual host $1 with documents directory $2. import_noweb=No Apache virtual host matching $1 was found. import_dns=Can import BIND DNS domain $1. import_nodns=No BIND DNS domain named $1 was found. import_nodb=No database to import was specified. import_mysql=Can import MySQL database $1. import_nomysql=No MySQL database named $1 was found. import_postgres=Can import PostgreSQL database $1. import_nopostgres=No PostgreSQL database named $1 was found. import_mail=Server is accepting email for domain $1. import_nomail=Server is not accepting email for domain $1. import_virt=Can import virtual IP address on interface $1. import_novirt=No unique virtual IP address for this domain. import_user1=Will create new automatically named Unix user $1 for domain. import_user2=Can import existing Unix user $1 for domain. import_user3=Will create new Unix user $1 for domain. import_group1=Will create new automatically named Unix group $1 for mailbox users. import_group2=Can import existing Unix group $1 for mailbox users. import_group3=Will create new Unix group $1 for mailbox users. import_mailboxes=Can import $1 mailbox users who have the primary group $2. import_webmin1=Will modify existing Webmin user $1 to manage this domain. import_webmin2=Will create Webmin user $1 to manage this domain. import_nowebmin=No Webmin user for this domain. import_webalizer=Can import Webalizer reporting for log file $1. import_nowebalizer=Webalizer is not set up for reporting on log file $1. import_dirs=Creating directories under home directory acheck_ename=Missing a ServerName directive acheck_edom=None of the ServerName or ServerAlias directives contain $DOM acheck_edoc=Missing a DocumentRoot directive disable_title=Disable Server disable_rusure2=Are you sure you want to disable the virtual server $1? Its $2 will be disabled. disable_undo=All of the above actions will be reversed with no loss of data if and when the server is re-enabled. disable_ok=Yes, Disable It disable_unix=Locking Unix user's password .. disable_apache=Replacing website with error page .. disable_ssl=Replacing SSL website with error page .. disable_webmin=Locking Webmin user's password .. disable_mysqluser=Locking MySQL user's password .. disable_postgres=De-activating PostgreSQL user .. disable_bind=Renaming DNS zone to disable it .. disable_ealready=Virtual server is already disabled disable_emaking=Before disable command failed : $1 disable_funix=unix login disable_fmail=mail domain disable_fweb=virtual website disable_fssl=SSL website disable_fdns=DNS domain disable_fmysql=MySQL login disable_fpostgres=PostgreSQL login disable_and=$1 and $2 disable_nothing=This domain does not have any features which are configured to be disabled! enable_title=Enable Server enable_rusure2=Are you sure you want to re-enable the virtual server $1? Its $2 will be restored to their original enabled states. enable_ok=Yes, Enable It enable_unix=Restoring Unix user's password .. enable_webmin=Restoring Webmin user's password .. enable_apache=Removing error page from website .. enable_ssl=Removing error page from SSL website .. enable_mysql=Restoring MySQL user's password .. enable_postgres=Re-activating PostgreSQL user .. enable_bind=Renaming DNS zone to original name .. enable_ealready=Virtual server is not disabled enable_emaking=Before enable command failed : $1 mail_usubject=Mailbox created mail_dsubject=Virtual server created mail_file=failed to read template file $1 : $2 mail_system=email is not setup in Virtualmin mail_ok=email sent to $1 afile_ecannot=You are not allowed to edit alias include files afile_eread=Failed to read alias include file $1 as user $2 : $3 afile_title=Edit Address File afile_desc=Use the text area below to edit the addresses in the file $1. afile_undo=Undo Changes afile_ewrite=Failed to write to addresses file $1 as user $2 : $3 rfile_title=Edit Autoreply File rfile_ecannot=You are not allowed to edit autoreply files rfile_eread=Failed to read autoreply file $1 as user $2 : $3 rfile_desc=Use the text area below to edit the autoreply message in $1. The message may contain the macros $SUBJECT, $FROM, $TO, $DATE and $BODY which will be expanded when the autoreply is activated. rfile_desc2=You can also set mail headers that add to or replace the defaults used in the autoreply by putting lines like:
From: foo@bar.com
Subject: On holiday
at the top of the message, separated from the body by a single blank line. rfile_undo=Undo Changes rfile_replies=Track replies to prevent mail loops? rfile_none=No rfile_file=Yes, using log file rfile_period=Minimum interval between replies rfile_default=Default (1 hour) rfile_secs=seconds rfile_ereplies=Missing reply tracking log file rfile_eperiod=Missing or invalid number of seconds between replies rfile_ewrite=Failed to write to autoreply file $1 as user $2 : $3 ffile_title=Edit Filter File ffile_ecannot=You are not allowed to edit filter files ffile_eread=Failed to read filter file $1 as user $2 : $3 ffile_desc=Use the form below to setup filter rules in the file $1. ffile_line=If the $1 field $2 $3 then forward to $4 ffile_from=from ffile_to=to ffile_subject=subject ffile_cc=CC ffile_body=body ffile_what0=doesn't match ffile_what1=matches ffile_other=Otherwise forward to $1 ffile_err=Failed to save filter file ffile_ematch=Missing match ffile_eaction=Missing forwarding address ffile_ewrite=Failed to write to filter file $1 as user $2 : $3 newweb_title=Apache Website Template newweb_ecannot=You are not allowed to edit the website template newweb_desc=Use this form to edit the template Apache directives that will be used for websites created by Virtualmin. The following substitions will be done when the site is created from the template : newweb_undo=Undo newweb_err=Failed to save website template newweb_suexec=Automatically add appropriate SuExec directive? newweb_htmldir=Users' website subdirectory to create newweb_htmldir0=Directory under home newweb_htmldir0suf=(Must match DocumentRoot above) newweb_ehtml=Missing or invalid website subdirectory newweb_statsdir=Subdirectory for Webalizer statistics newweb_statsdir0=Directory under $1 newweb_estats=Missing or invalid statistics subdirectory newweb_port=Port number for virtual hosts newweb_sslport=Port number for SSL virtual hosts newweb_eport=Missing or invalid port number for virtual hosts newweb_esslport=Missing or invalid port number for SSL virtual hosts newweb_esslport2=SSL and normal virtual host port numbers cannot be the same newdns_title=BIND DNS Template newdns_ecannot=You are not allowed to edit the DNS template newdns_desc=Use this form to edit the template BIND directives that will be placed in DNS domains created by Virtualmin (when not in automatic mode). The following substitions will be done when the domain is created from the template : newdns_replace1=Use only the records below in new domains .. newdns_replace0=Just add records below to automatically generated records for new domains .. newdns_mx=Extra MX hosts for non-mail domains newdns_err=Failed to save DNS template newdns_esoa=Exactly one SOA record must exist in the template newdns_esoa2=No SOA record is needed in the template newdns_ens=An NS record for the domain must exist in the template newdns_edom=An A or MX record for the domain must exist in the template newdns_ewww=A www A record for the domain must exist in the template sub_DOM=The domain name, such as foo.com sub_HOME=The domain user's home directory, such as /home/foo sub_USER=The Unix user that owns the domain, such as foo sub_UID=The Unix user's UID, such as 1001 sub_IP=The IP address assigned to the virtual server, such as 192.168.1.1 sub_FTP=Set to 1 if FTP access is allowed for the new user sub_MAILBOX=The mailbox part of the user's email address, like fred sub_POP3=The user's full POP3 login name, like fred.foo sub_POP3HOME=The user's home directory, like /home/foo/users/fred sub_LOCALHOME=The user's home directory, like /home/fred sub_if=In addition, conditional blocks like ${IF-MAIL}...${ENDIF-MAIL} and ${IF-WEB}...${ELSE-WEB}...{$ENDIF-WEB} may be used. newuser_title=New Mailbox Email newuser_ecannot=You are not allowed to edit the new mailbox email template newuser_desc=Use this form to edit the template file $1 for the email message that will be sent to a new mailbox after it is created. The following substitions will be done to the text : newuser_descdis=Use this form to edit the template file $1 for the email message that would be sent to a new mailbox after it is created, if this feature was enabled on the Module Config page. The following substitions will be done to the text : newlocal_title=New Local Mailbox Email newlocal_ecannot=You are not allowed to edit the new local mailbox email template newlocal_desc=Use this form to edit the template file $1 for the email message that will be sent to a new local mailbox after it is created. The following substitions will be done to the text : newlocal_descdis=Use this form to edit the template file $1 for the email message that would be sent to a new local mailbox after it is created, if this feature was enabled on the Module Config page. The following substitions will be done to the text : newdom_title=New Virtual Server Email newdom_ecannot=You are not allowed to edit the new server email template newdom_desc=Use this form to edit the template file $1 for the email message that will be sent to a new virtual server owner after it is created. The following substitions will be done to the text : newdom_descdis=Use this form to edit the template file $1 for the email message that would be sent to a new virtual server owner after it is created, if this feature was enabled on the Module Config page. The following substitions will be done to the text : feature_web=Apache website feature_dns=BIND DNS domain feature_mysql=MySQL database feature_postgres=PostgreSQL database feature_webalizer=Webalizer reporting feature_mail=Mailboxes and aliases feature_unix=Unix user feature_ssl=SSL website feature_webmin=Webmin login losing_web=All Apache directives in the virtual host will be removed. losing_dns=All DNS records in the domain and any BIND options will be deleted. losing_mysql=The MySQL database, all tables and the server's MySQL login will be deleted. losing_postgres=The PostgresSQL database, all tables and the server's PostgresSQL login will be deleted. losing_webalizer=Scheduled generation of a report based on the website's logs will be turned off. losing_mail=The mail server will no longer accept email for this domain. losing_ssl=All Apache directives in the SSL virtual host will be removed. losing_unix=The Unix user for this virtual server will be deleted, along with all website and other files in his home directory. losing_webmin=The Webmin user for this virtual server will be deleted. check_title=Checking Configuration check_desc=The status of your system is being checked to ensure that all enabled features are available, that the mail server is properly configurated, and that quotas are active .. check_netok=Webmin's Network Configuration module is installed and supported. check_webok=Apache is installed. check_dnsok=BIND DNS server is installed. check_mysqlok=MySQL is installed and running. check_postgresok=PostgreSQL is installed and running. check_webalizerok=Webalizer is installed. check_ifaceok=Using network interface $1 for virtual IPs. check_sendmailok=Mail server Sendmail is installed and configured. check_postfixok=Mail server Postfix is installed and configured. check_qmailok=Mail server Qmail is installed and configured. check_done=.. your system is ready for use by Virtualmin. check_failed=.. your system is not ready for use by Virtualmin. check_nogroup=User quotas are enabled for home and email directories, but group quotas are not. Total virtual server quotas will not be enforced. check_group=Both user and group quotas are enabled for home and email directories. check_sslok=Apache is configured to host SSL websites. check_edepwebalizer=Webalizer cannot be enabled in Virtualmin's module configuration unless Apache is. check_edepssl=SSL cannot be enabled in Virtualmin's module configuration unless Apache is. check_eshell=Shell $1 for non-FTP users is included in $2, which may allow FTP access. check_eftpshell=Shell $1 for FTP users is not included in $2, which may prevent FTP access. check_allwebmin=Updating all Webmin users with new settings.. check_needupdate=Some of the module configuration settings that effect which modules Webmin users have access to have changed. Click the button below to update all users with the new permissions. check_updatenow=Update Webmin Users allwebmin_ecannot=You are not allowed to update all Webmin users allwebmin_title=Updating Webmin Users log_create_user=Created mailbox $1@$2 log_modify_user=Modified mailbox $1@$2 log_delete_user=Deleted mailbox $1@$2 log_create_alias=Created mail alias $1 log_modify_alias=Modified mail alias $1 log_delete_alias=Deleted mail alias $1 log_create_domain=Created virtual server $1 log_modify_domain=Modified virtual server $1 log_delete_domain=Deleted virtual server $1 log_disable_domain=Disabled virtual server $1 log_enable_domain=Enabled virtual server $1 log_import_domain=Imported virtual server $1 log_check=Re-checked configuration log_newweb=Updated new website template log_newuser=Updated new mailbox email template log_newlocal=Updated new local user email template log_newdns=Updated new DNS domain template log_newdom=Updated new server email template log_start_web=Started Apache webserver log_stop_web=Stopped Apache webserver log_start_dns=Started BIND DNS server log_stop_dns=Stopped BIND DNS server log_start_mail=Started mail server log_stop_mail=Stopped mail server log_sched_create=Enabled scheduled backups log_sched_delete=Disabled scheduled backups log_sched_modify=Modified scheduled backups log_sched_none=Did nothing to scheduled backups log_backup=Backed up $1 virtual servers log_backup_l=Backed up virtual servers $1 log_restore=Restored $1 virtual servers log_restore_l=Restored virtual servers $1 backup_title=Backup Virtual Servers backup_title2=Scheduled Backup backup_header=Options for immediate backup backup_header2=Options for scheduled backup backup_doms=Servers to save backup_features=Features to backup backup_all=All virtual servers backup_sel=Only selected .. backup_dest=Backup destination backup_fmt=Backup format backup_fmt0=Single archive file backup_fmt1=Directory of archive files, one per server backup_errors=Action on error backup_errors0=Halt the backup immediately backup_errors1=Continue with other features and servers backup_email=Email backup report to backup_strftime=Do strftime style time substitutions on file or directory name backup_now=Backup Now backup_save=Save and Apply backup_enabled=Scheduled backup enabled? backup_enabledyes=Yes, at times selected below .. backup_mode0=Local file backup_mode1=FTP server backup_path=file on server backup_login=Login as user backup_pass=with password backup_mailfiles2=Include mail files backup_feature_unix=Unix user's home directory, include web pages and logs backup_feature_web=Apache webserver configuration backup_feature_ssl=Apache SSL webserver configuration and certificate backup_feature_virtualmin=Virtual server password, description and other details backup_feature_mysql=Contents of server's MySQL database backup_feature_postgres=Contents of server's PostgreSQL database backup_feature_dns=Records in DNS domain, except SOA backup_feature_mail=Mailboxes and mail aliases backup_feature_webalizer=Webalizer configuration and schedule backup_err=Backup failed backup_err2=Failed to save scheduled backup backup_ecannot=You are not allowed to perform backups backup_edoms=No domains selected to backup backup_efeatures=No features selected to backup backup_edest=Missing or invalid absolute local file backup_eserver=Missing or invalid FTP server backup_epath=Missing or invalid absolute path on FTP server backup_doing=Starting backup of $1 domains to $2 .. backup_euser=Invalid characters in FTP server login backup_epass=Invalid characters in FTP server password backup_done=Backup is complete. Final size was $1. backup_failed=Backup failed! See the progress output above for the reason why. backup_upload=Uploading archive to FTP server .. backup_uploadfailed=.. upload failed! $1 backup_unixtar=Creating TAR file of home directory .. backup_unixtarfailed=.. TAR failed! $1 backup_virtualmincp=Copying virtual server configuration .. backup_apachecp=Copying Apache virtual host configuration .. backup_mysqldump=Dumping MySQL database .. backup_mysqldumpfailed=.. dump failed! $1 backup_fordomain=Creating backup for virtual server $1 .. backup_final=Creating final backup archive .. backup_final2=Creating final backup archives in directory .. backup_finalfailed=.. archive failed! $1 backup_sslcp=Copying SSL Apache virtual host configuration and certificate .. backup_postgresdump=Dumping PostgresSQL database .. backup_postgresdumpfailed=.. dump failed! $1 backup_dnscp=Copying records in DNS domain .. backup_dnsnozone=.. domain not found! backup_mailaliases=Saving mail aliases .. backup_mailusers=Saving mailbox users .. backup_mailfiles=Backing up all mail files .. backup_mailfilesfailed=.. tar failed! $1 backup_webalizercp=Copying Webalizer configuration files .. restore_title=Restore Virtual Servers restore_header=Options for restoring backup restore_src=Restore source restore_doms=Servers to restore restore_all=All in file restore_now=Show What Will Be Restored restore_features=Features to restore restore_mailfiles2=Restore mail files restore_ecannot=You are not allowed to restore backups restore_err=Restore failed restore_esrc=Missing or non-existant source file restore_edoms=No domains selected to restore restore_efeatures=No features selected to restore restore_efile=The specified source is not a Virtualmin backup : $1 restore_enone=The specified source does not contain any domains, or is not a Virtualmin backup restore_etar=Not a valid tar or tar.gz file restore_edup=Server $1 appears twice in backup directory restore_from=Are you sure you want to restore the selected domains and features from $1? Any existing data for the features in these domains will be over-written! restore_now2=Restore Now restore_nofeat=No selected features in backup restore_notany=None of the selected features are used by any of the servers in this backup, and thus the restore cannot proceed. restore_doing=Starting restore of $1 domains from $2 .. restore_failed=.. failed! See the progress output above for the reason why. restore_done=.. restore complete. restore_first=Extracting backup archive file .. restore_first2=Extracting backup archive files .. restore_firstfailed=.. extraction of $1 failed! $2 restore_fordomain=Restoring backup for virtual server $1 .. restore_download=Downloading archive from FTP server .. restore_downloadfailed=.. download failed! $1 restore_unixtar=Extracting TAR file of home directory, and updating Unix password .. restore_virtualmincp=Restoring virtual server password, quota and other details .. restore_mysqlload=Deleting, re-creating and re-loading MySQL database .. restore_mysqlloadfailed=.. load failed! $1 restore_apachecp=Restoring Apache virtual host configuration .. restore_sslcp=Restoring SSL Apache virtual host configuration and certificate .. restore_postgresload=Deleting, re-creating and re-loading PostgreSQL database .. restore_postgresloadfailed=.. load failed! $1 restore_dnscp=Re-creating records in DNS domain .. restore_mailaliases=Re-creating mail aliases .. restore_mailusers=Re-creating mailbox users .. restore_mailfiles=Restoring mail files .. restore_webalizercp=Restoring Webalizer configuration files and Cron job .. virtual-server/lang/fr0100644000567100000120000004411010002735635015005 0ustar jcameronwheelindex_title=Serveurs Virtuels Virtualmin index_title2=Mels virtuels index_add=Ajouter un nouveau serveur virtuel. index_import=Importer un domaine existant comme serveur virtuel. index_domain=Nom du domaine index_user=Utilisateur index_owner=Description index_web=Site web? index_webalizer=Webalizer? index_dns=DNS? index_mysql=MySQL? index_postgres=PostgreSQL? index_mail=Boîtes aux lettres index_alias=Aliases index_none=Aucun serveur virtuel n'a encore ete créé. index_return=liste des serveurs virtuels index_list=Liste.. index_eapache=Le serveur web Apache ne semble pas etre installé sur votre systeme, ou n'a pas été correctement configuré dans le module Webmin Serveur web Apache. Si votre systeme n'utilise pas Apache, il doit etre désactivé dans la page de configuration du module Virtualmin. index_ebind=Le serveur DNS BIND version 8 ou 9 ne semble pas etre installé sur votre systeme, ou n'a pas été correctement configuré dans le module Webmin Serveur DNS BIND. Si votre système n'utilise pas BIND, il doit être désactivé dans la page de configuration du module Virtualmin. index_email=Aucun des serveurs de messagerie supportés (Sendmail et Postfix) n'a été détecté sur votre système. Peut etre ne sont ils pas installés, ou leur modules Webmin n'ont pas été configurés correctement. index_emysql=MySQL ne semble pas etre installé et exécute sur votre système, ou n'a pas encore été correctement configuré dans le module Webmin Base de données MySQL. Si votre système n'utilise pas MySQL, il doit être désactivé dans la page de configuration du module Virtualmin. index_epostgres=PostgreSQL ne semble pas etre installé et exécuté sur votre système, ou n'a pas encore été correctement configuré dans le module Webmin Base de données PostgreSQL. Si votre système n'utilise pas PostgreSQL, il doit etre désactivé dans la page de configuration du module Virtualmin. index_ewebalizer=Webalizer ne semble pas etre installé et exécuté sur votre système, ou n'a pas encore été correctement configuré dans le module Webmin Analyse de logs Webalizer. Si votre système n'utilise pas Webalizer, il doit etre désactivé dans la page de configuration du module Virtualmin. index_esendmail=Le serveur de messagerie Sendmail ne semble pas etre installé et éxécute sur votre système, ou n'a pas encore été correctement configuré dans le module Webmin Sendmail. Si vous utilisez un serveur de messagerie différent, sélectionnez le dans la page de configuration du module Virtualmin. index_epostfix=Le serveur de messagerie Postfix ne semble pas etre installé et exécuté sur votre système, ou n'a pas encore été correctement configuré dans le module Webmin Serveur de messagerie Postfix. Si vous utilisez un serveur de messagerie différent, sélectionnez le dans la page de configuration du module Virtualmin. index_eiface=Aucune interface Ethernet ne peut etre détectée automatiquement sur votre systeme. Utilisez la page de configuration du module pour définir l'interface manuellement. index_astart=Démarrer Apache index_astartdesc=Le serveur web Apache n'est pas exécute actuellement, ce qui signifie que toutes les pages web des serveurs virtuels ne sont pas accessibles. Cliquez sur ce bouton pour le démarrer. index_astop=Arreter Apache index_astopdesc=Le serveur web Apache est actuellement éxecuté, et distribue les pages web des serveurs virtuels. Cliquez sur ce bouton pour l'arreter. index_bstart=Démarrer BIND index_bstartdesc=Le serveur DNS BIND n'est pas exécuté actuellement, ce qui signifie que les domaines DNS hébergés par ce serveur sont actuellement irrésolvables. Cliquez sur ce bouton pour le démarrer. index_bstop=Arreter BIND index_bstopdesc=Le serveur DNS BIND est actuellement exécuté, et héberge les domaines DNS des serveurs virtuels. Cliquez sur ce bouton pour l'arreter. index_mstart=Démarrer le serveur de messagerie index_mstartdesc=Le serveur de messagerie configuré n'est pas exécuté actuellement, ce qui signifie qu'aucun message ne peut etre reçu par les boites aux lettres des domaines virtuels. Cliquez sur ce bouton pour le démarrer. index_mstop=Arreter le serveur de messagerie index_mstopdesc=Le serveur de messagerie acuellement configuré est actuellement exécute, et accepte les messages pour les boites aux lettres des domaines virtuels. Cliquez sur ce bouton pour l'arreter. index_ehomemtab=Le module ne peut pas trouver le point de montage pour le système de fichiers contenant les repertoires utilisateurs $1. L'édition des quotas a été désactivée. index_emailmtab==Le module ne peut pas trouver le point de montage pour le système de fichiers contenant les boites aux lettres $1. L'édition des quotas a été désactivée. index_ediff=Les répertoires utilisateur et les boites aux lettres de messagerie se trouvent sur des systèmes de fichiers différents ($1, contenant les répertoires utilisateurs, monté sous $2, alors que $3, qui contient les boites aux lettres est monté sous $4). Seulement les quotas des répertoires utilisateur peuvent etre édités. index_equota=Les quotas ne sont pas activés sur le système de fichiers $1 qui contient les répertoires utilisateurs, monté sous $2. L'édition des quotas a été désactivée. index_quota=Quota total index_squota=Allocation totale index_uquota=Utilisation totale index_header1=Boites aux lettres locales index_header2=Serveurs virtuels index_nousers=Aucune boite aux lettres locale n'a encore ete créé. index_uadd=Ajouter une nouvelle boite aux lettre locale index_toomany=Il y a trop de serveurs virtuels sur votre système pour les afficher sur cette page. index_search=Rechercher les serveurs virtuels ou le (l') index_search_dom=nom de domaine index_search_user=nom d'utilisateur index_search_ip=adresse IP index_contains=contient index_searchok=Rechercher maintenant index_nomail=Désactivé form_title=Créer un serveur virtuel form_ecannot=Vous n'etes pas autorisé a créer un serveur virtuel form_desc=XXX form_header=Nouveau serveur virtuel - détails form_domain=Nom de domaine form_owner=Description form_user=Nom d'utilisateur Unix form_auto=Automatique form_mail=Accepter les messages pour le domaine? form_web=Créer un site web pour le domaine? form_dns=Créer une zone DNS? form_mysql=Créer une base de donnees MySQL? form_postgres=Créer une base de donnees PostgresSQL? form_webalizer=Configurer Webalizer pour les logs du serveur web? form_webmin=Créer un utilisateur Webmin? form_name=Type de serveur web form_name1=Base sur le nom form_name0=Base sur l'adresse IP form_ip=Adresse IP pour le site web et le domaine form_pass=Mot de passe Unix de l'utilisateur form_virt=Ajouter une adresse IP virtuelle si requis? form_ok=Créer le serveur form_quota=Quota total pour ce serveur form_uquota=Quota pour l'utilisateur Unix form_b=blocs form_unavail=Non disponible setup_err=La création du serveur virtuel a echouée setup_edomain=Nom de domaine manquant ou invalide setup_edomain2=vous hébergez deja ce domaine setup_eip=Adresse IP manquante ou invalide setup_eauto=Un nom d'utilisateur Unix disponible ne peut pas etre trouve ($1 et $2 existent deja) setup_euser=L'utilisateur Unix specifie existe deja setup_euser2=Nom d'utilisateur Unix manquant ou invalide setup_egroup=Un groupe Unix nomme $1 existe deja setup_edns=Le nom de domaine specifié est déja héberge par votre serveur DNS setup_ewebmin=Un utilisateur Webmin nomme $1 existe déja setup_eweb=Le nom de domaine speficie est déja hébergé par votre serveur web Apache setup_emysql=Une base de donnees MySQL nommée $1 existe deja setup_epostgres=Une base de donnees PostgreSQL nommée $1 existe deja setup_ehomebase=Le repertoire des utilisateurs n'a pas été défini dans le module Utilisateurs et Groupes setup_equota=Quota total manquant ou invalide setup_euquota=Quota utilisateur manquant ou invalide setup_eiface=L'interface réseau $1 sur laquelle les adresses virtuelles sont ajoutées n'existe pas sur votre système setup_eiface2=L'interface réseau $1 sur laquelle les adresse virtuelles sont ajoutées n'a pas d'adresse IP fixée (peut etre car DHCP est utilisé sur cette dernière) setup_ewebalizer=Webalizer ne peut pas etre activé sans site web setup_title=Configurer un serveur virtuel setup_group=Création d'un groupe Unix .. setup_user=Création d'un utilisateur Unix .. setup_home=Création d'un repertoire utilisateur .. setup_web=Ajout d'un nouveau site web virtuel .. setup_webpid=Re-démarrage du serveur web .. setup_bind=Ajout d'une nouvelle zone DNS .. setup_bindpid=Re-démarrage du serveur DNS .. setup_mysql=Création d'une base de donnees MySQL .. setup_postgres=Création d'une base de donnees PostgreSQL .. setup_webmin=Création d'un utilisateur Webmin .. setup_webminpid=Re-démarrage de Webmin .. setup_doms=Ajout a la liste des domaines de messagerie .. setup_save=Sauvegarde des details du serveur .. setup_virt=Ajout d'une adresse IP virtuelle sur l'interface reseau .. setup_done=.. fait! setup_notrun=.. n'est pas exécuté! setup_quota=Définition du quota utilisateur .. setup_webalizer=Définition du rapport Webalizer programmé .. indom=Dans le domaine $1 users_ecannot=Vous n'etes pas autorisé a éditer les utilisateur de ce domaine users_ecannot2=Vous n'etes pas autorisé a éditer les utilisaateurs locaux users_title=Boites aux lettres utilisateur users_name=Nom users_domain=Domaine users_real=Nom complet users_pop3=Connexion POP3/FTP users_user=Utilisateur users_alias=Alias users_add=Ajouter un utilisateur a ce domaine users_none=Aucune boite aux lettre n'a encore été crée pour ce domaine. users_return=liste des utilisateurs users_size=Taille de la boite aux lettres users_empty=Vide users_quota=Quota de disque users_ftp=Connexion FTP? users_shell=Dispose du shell $1 user_create=Créer une boite aux lettres user_edit=Editer une boite aux lettres user_header=Détails de la boite aux lettres de l'utilisateur du domaine virtuel user_lheader=Détails de la boite aux lettres de l'utilisateur local user_user=Nom d'utilisateur user_pop3=(Connexion POP3/FTP $1) user_domain=Dans le domaine user_real=Nom complet user_pass=Mot de passe user_passdef=Laisser inchange user_passset=Définir a .. user_err=La sauvegarde de la boite aux lettre a échoué user_eclash=Une boite aux lettres ou un alias de messagerie existe déja dans le meme domaine user_euser=Nom d'utilisateur manquant ou incorrect user_ereal=Nom complet invalide user_quota=Quota de disque user_used=($1 utilises) user_equota=Quota manquant ou invalide user_mail=Fichier de boite aux lettres principal user_read=(Adresse de messagerie reelle) user_ftp=Connexion FTP activée? user_shell=Dispose du shell personalise $1 user_elong=Le nom d'utilisateur $1 est plus long que le maximum autorise sur ce système ($2 caracteres) aliases_ecannot=Vous n'etes pas autorisé a éditer les alias de ce domaine aliases_title=Alias de messagerie aliases_name=Nom aliases_domain=Domaine aliases_dest=Destination de l'alias aliases_add=Ajouter un alias a ce domaine aliases_none=Aucun alias de messagerie n'a encore ete créé pour ce domaine. aliases_return=liste des alias alias_create=Créer un alias de messagerie alias_edit=Editer un alias de messagerie alias_header=Détails de l'alias de messagerie alias_name=Nom alias_domain=Domaine alias_dest=Adresse de destination alias_err=La sauvegarde de l'alias a echoué alias_ename=Nom d'alias manquant ou invalide (aucun @ ne doit etre inclus) alias_edest=Adresse de destination manquante alias_eclash=Une boite aux lettres ou un alias avec le meme nom existe déja dans ce domaine stop_ecannot=Vous n'etes pas autorisé a arreter les serveurs start_ecannot=Vous n'etes pas autorisé a demarrer les serveurs bstop_err=L'arret de BIND a echoue bstop_epid=Le processus n'est plus en cours d'execution mstop_err=L'arret du serveur de messagerie a échoué mstart_err=Le démarrage du serveur de messagerie a échoué mstop_edown=Sendmail n'est plus en cours d'exécution edit_title=Editer un serveur edit_ecannot=Vous n'etes pas autorise a editer ce serveur virtuel edit_header=Details du serveur virtuel edit_domain=Nom de domaine edit_user=Nom d'utilisateur Unix edit_owner=Nom du proprietaire edit_passwd=Mot de passe Unix edit_lv=Laisser inchangé edit_set=Defini a .. edit_save=Sauvegarder et appliquer edit_quota=Quota total pour ce serveur edit_uquota=Quota pour l'utilisateur Unix edit_mail=Messagerie pour ce domaine activée? edit_web=Serveur web activé? edit_dns=Serveur DNS activé? edit_webalizer=Rapports Webalizer activés? edit_mysql=Base de donnees MySQL activée? edit_postgres=Base de donnees PostgreSQL activée? edit_webmin=Connexion Webmin activée? edit_delete=Supprimer et appliquer edit_desc=Changer les options du serveur web ou DNS a Non ne vont pas supprimer les entrées dans les fichiers de configuration Apache ou BIND. De meme, changer les options MySQL ou PostgreSQL ne vont pas supprimer le contenu bases de données. edit_ip=Adresse IP edit_virt=Interface Virtuelle edit_none=Aucune spécifique au serveur delete_title=Suprimmer le serveur delete_rusure=Etes vous sur de vouloir supprimer le serveur virtuel $1 ? $3 boites aux lettres, $4 alias de messagerie et $2 de fichiers utilisateurs et de site web vont etre DEFINITIVEMENT supprimés. delete_ok=Oui, le supprimer delete_domain=Suppression des details du serveurs .. delete_apache=Suppression du site web virtuel .. delete_bind=Suppression de la zone DNS .. delete_mysql=Suppression de la base MySQL .. delete_webmin=Suppression de l'utilisateur Webmin .. delete_users=Suppression des boites aux lettres .. delete_aliases=Suppression des alias de messagerie .. delete_doms=Suppresion de la liste des domaines de messagerie .. delete_virt=Suppresion de l'adresse IP virtuelle .. delete_user=Suppression de l'utilisateur Unix .. delete_group=Suppression du groupe Unix .. delete_home=Suppression du repertoire utilisateur .. delete_webalizer=Suppresion des taches de rapport Webalizer .. save_err=La modification du serveur a echouée save_title=Sauvegarder le serveur save_equota=Quota total manquant ou invalide save_euquota=Quota d'utilisateur Unix manquant ou invalide save_user=Modification de l'utilisateur Unix .. save_domain=Sauvegarde des details du serveur .. save_quota=Changement du quota Unix .. save_mysqlpass=Changement du mot de passe MySQL .. save_webmin=Mise à jour de l'utilisateur Webmin .. luser_err=La sauvegarde de la boite aux lettres locale a echouée luser_etaken=Un utilisateur avec le meme nom existe déja acl_domains=Domaines que cet utilisateur peut gérer acl_all=Tous les domaines acl_sel=Les domaines selectionnes ci apres .. acl_create=Peut créer de nouveaux domaines? acl_edit=Peut éditer des domaines existants? acl_local=Peut éditer les utilisateurs locaux? acl_stop=Peut arreter et démarrer des services? other=Autre... search_title=Résultats de la recherche search_none=Aucun serveur virtuel contenant $1 n'a été trouvé. search_results=Trouvé $2 serveurs virtuels correspondant a $1 .. import_title=Importer un serveur virtuel import_desc1=Ce formulaire peut etre utilisé pour soumettre un domaine existant sur votre systeme au contrôle de Virtualmin. Les boites aux lettres et alias, tout serveur web virtuel Apache et domaine DNS vont etre détectés automatiquement. Vous pouvez également saisir le nom d'une base de données associée avec le domaine, s'il en existe une. import_desc2=Lors de l'import d'un domaine, un mot de passe pour son utilisateur Unix doit etre saisi. Cela peut etre le mot de passe de l'utilisateur courant, mais son mot de passe ne sera pas change quelque soit celui que vous entrerez. Virtualmin doit connaitre le mot de passe de chaque serveur virtuel, pour l'utiliser au moment de la définition de bases de donnees MySQL ou PostgreSQL. import_desc3=Si le domaine possède une adresse IP pricee, vous devez l'entrer au bas de ce formulaire et indiquer que cette adresse est utilisée exclusivement pour ce site. Pour les sites web bases sur le nom ou pour les domaines qui n'hébergent que de la messagerie, l'importation par defaut de l'adresse IP fonctionnera correctement. import_header=Détails du serveur virtuel importé import_dom=Nom de domaine import_user=Utilisateur Unix a qui appartient le domaine import_pass=Mot de passe de l'utilisateur Unix import_webmin=Créer un utilisateur Webmin pour gerer ce serveur? import_db=Nom de la base de données MySQL ou PostgreSQL import_ip=Adresse IP utilisée par Apache et DNS import_virt=Adresse IP unique à ce domaine? import_ok=Voir l'importation virtual-server/index.cgi0100775000567100000120000001647110036163736015347 0ustar jcameronwheel#!/usr/local/bin/perl # index.cgi # Display a list of domains managed by this module require './virtual-server-lib.pl'; if ($single_domain_mode) { # This user can edit just a single domain, so show only a menu of # icons for options he can use &header($text{'index_title2'}, "", undef, 1, 1); $d = &get_domain($access{'domains'}); &domain_title($d); print "
\n"; @links = ( "list_users.cgi?dom=$access{'domains'}", "list_aliases.cgi?dom=$access{'domains'}" ); @titles = ( $text{'users_title'}, $text{'aliases_title'} ); @icons = ( "images/users.gif", "images/aliases.gif" ); &icons_table(\@links, \@titles, \@icons); print "
\n"; &footer("/", $text{'index'}); exit; } &header($text{'index_title'}, "", "index", 1, 1, 0, undef, undef, undef, &text('index_version', $module_info{'version'})); print "
\n"; # Check if server configuration has been checked @cst = stat($module_config_file); if ($cst[9] > $config{'last_check'}) { # Not since last config change .. force it now print "
\n"; print "$text{'index_needcheck'}

\n"; print "

\n"; print "
\n"; &footer("/", $text{'index'}); exit; } # Setup the default templates &ensure_template("domain-template"); &ensure_template("user-template"); &ensure_template("local-template"); # Display local users if ($config{'localgroup'} && $access{'local'}) { print "

$text{'index_header1'}

\n"; @lusers = &list_domain_users(); if (@lusers) { print "", "$text{'index_uadd'}
\n"; &users_table(\@lusers); } else { print "$text{'index_nousers'}

\n"; } print "", "$text{'index_uadd'}

\n"; print "


\n"; } # Display domains print "

$text{'index_header2'}

\n"; @doms = grep { &can_edit_domain($_) } &list_domains(); if ($config{'display_max'} && @doms > $config{'display_max'}) { # Too many domains to display, so show a search form print "$text{'index_toomany'}

\n"; print "

\n"; print "$text{'index_search'}\n"; print " $text{'index_contains'}\n"; print "\n"; print "
\n"; } elsif (@doms) { # Show domains in a table &create_links(); print "
\n"; &domains_table(\@doms); } else { print "$text{'index_none'}

\n"; } &create_links(); print "

\n"; # Show icons for editing various templates if ($master_admin) { print "


\n"; print "

$text{'index_header3'}

\n"; @tmpls = ( $config{'web'} ? ( 'web' ) : ( ), $config{'dns'} ? ( 'dns' ) : ( ), 'dom', 'user', $config{'localgroup'} ? ( 'local' ) : ( ) ); @tlinks = map { "edit_new${_}.cgi" } @tmpls; @ttitles = map { $text{"new${_}_title"} } @tmpls; @ticons = map { "images/new${_}.gif" } @tmpls; &icons_table(\@tlinks, \@ttitles, \@ticons, scalar(@tlinks)); } # Show current status if ($master_admin) { print "
\n"; print "

$text{'index_sheader'}

\n"; print "\n"; print "\n"; print "\n"; if ($config{'mail'}) { print "\n"; } print "\n"; print "\n"; print "
$text{'index_sfeatures'} \n"; print join(", ", map { $text{"feature_".$_} } grep { $config{$_} } @features),"
$text{'index_squotas'} \n"; if (!$config{'quotas'}) { # Quotas manually disabled print "$text{'index_squotas1'}\n"; } elsif ($config{'home_quotas'} && $config{'home_quotas'} eq $config{'mail_quotas'}) { # Both quota filesystems are the same print &text($config{'group_quotas'} ? 'index_squotas5g' : 'index_squotas5', "$config{'home_quotas'}"),"\n"; } elsif ($config{'home_quotas'} && $config{'mail_quotas'}) { # Quota filesystems are different print &text($config{'group_quotas'} ? 'index_squotas4g' : 'index_squotas4', "$config{'home_quotas'}", "$config{'mail_quotas'}"),"\n"; } elsif ($config{'home_quotas'}) { # Only for home print &text($config{'group_quotas'} ? 'index_squotas3g' : 'index_squotas3', "$config{'home_quotas'}"),"\n"; } else { # Not active at all print "$text{'index_squotas2'}\n"; } print "
$text{'index_smail'} \n"; print $config{'mail_system'} == 0 ? "Postfix" : $config{'mail_system'} == 1 ? "Sendmail" : "Qmail"; print "
\n"; } # Show backup and restore buttons if ($master_admin) { print "
\n"; print "

$text{'index_sheader'}

\n"; print "\n"; # Button to backup now print "\n"; print "\n"; print "\n"; print "\n"; # Button to setup scheduled backup print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; # Button to restore print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'index_backupdesc'}
$text{'index_scheddesc'}
$text{'index_restoredesc'}
\n"; } # Show start/stop buttons if ($access{'stop'}) { print "
\n"; print "\n"; if ($config{'web'}) { $apid = &get_apache_pid(); if (!$apid || !kill(0, $apid)) { # Apache is down .. offer to start it &ss_form("start_apache.cgi", $text{'index_astart'}, $text{'index_astartdesc'}); } else { # Apache is up .. offer to stop it &ss_form("stop_apache.cgi", $text{'index_astop'}, $text{'index_astopdesc'}); } } if ($config{'dns'}) { $bpid = &get_bind_pid(); if (!$bpid || !kill(0, $bpid)) { # BIND is down .. offer to start it &ss_form("start_bind.cgi", $text{'index_bstart'}, $text{'index_bstartdesc'}); } else { # BIND is up .. offer to stop it &ss_form("stop_bind.cgi", $text{'index_bstop'}, $text{'index_bstopdesc'}); } } if ($config{'mail'}) { if (!&is_mail_running()) { # Mail server is down .. offer to start it &ss_form("start_mail.cgi", $text{'index_mstart'}, $text{'index_mstartdesc'}); } else { # Mail server is up .. offer to stop it &ss_form("stop_mail.cgi", $text{'index_mstop'}, $text{'index_mstopdesc'}); } } print "
\n"; } print "
\n"; &footer("/", $text{'index'}); sub ss_form { print "
\n"; if ($_[0] =~ /^start/) { print "\n"; } else { print "\n"; } print "\n"; print "$_[2]
\n"; } sub create_links { if ($access{'create'}) { print "$text{'index_add'} \n"; if ($access{'import'}) { print "$text{'index_import'}\n"; } } } virtual-server/config0100664000567100000120000000230010036162760014717 0ustar jcameronwheelmail_system=3 mail=1 web=1 dns=1 mysql=1 webalizer=1 iface= shell=/dev/null ftp_shell=/bin/false unix_shell=/bin/sh append=1 append_style=0 longname=0 virtual_skel=/etc/skel quotas=1 avail_file=1 avail_passwd=1 avail_proc=1 avail_cron=1 avail_at=1 avail_telnet=1 avail_custom=0 avail_updown=0 avail_mailboxes=1 avail_htaccess-htpasswd=1 display_max=100 postgres=0 avail_change-user=1 apache_config=ServerName ${DOM} ServerAlias www.${DOM} DocumentRoot ${HOME}/public_html ErrorLog ${HOME}/logs/error_log CustomLog ${HOME}/logs/access_log common ScriptAlias /cgi-bin/ ${HOME}/cgi-bin/ Options Indexes IncludesNOEXEC FollowSymLinks domain_template=none user_template=none local_template=none suexec=1 edit_afiles=1 edit_homes=0 alias_types=1,2,3,4,5,6,7 disable=unix,mail,web,dns,mysql,postgres delete_indom=0 webmin_theme=* leave_acl=1 hard_quotas=0 proxy_pass=0 show_features=0 webmin=1 ssl=0 edit_ftp=1 edit_quota=1 post_check=1 generics=0 all_namevirtual=0 backup_feature_virtualmin=1 backup_feature_unix=1 backup_feature_mail=1 backup_feature_web=1 backup_feature_webalizer=1 backup_feature_ssl=1 backup_feature_dns=1 backup_feature_mysql=1 backup_feature_postgres=1 virtual-server/virtual-server-lib.pl0100664000567100000120000015066110042052577017641 0ustar jcameronwheel# virtual-server-lib.pl # Common functions for Virtualmin # XXX qmail support # XXX importing # XXX stop/start server # XXX user aliases # XXX all use of mail_system # XXX test all the alias types # XXX qmail not accepting mail! (works for users, not aliases?) # XXX 'all mailboxes' support (use default) do '../web-lib.pl'; &init_config(); %access = &get_module_acl(); $master_admin = !$access{'noconfig'}; $single_domain_mode = $access{'domains'} =~ /^\d+$/ && !$access{'edit'} && !$access{'create'} && !$access{'stop'} && !$access{'local'}; if (!$master_admin) { # Allowed alias types are set by module config %can_alias_types = map { $_, 1 } split(/,/, $config{'alias_types'}); } else { # All types are allowed %can_alias_types = map { $_, 1 } (0 .. 7); } $first_print = \&first_html_print; $second_print = \&second_html_print; $indent_print = \&indent_html_print; $outdent_print = \&outdent_html_print; @opt_features = ( 'dns', 'mail', 'web', 'webalizer', 'ssl', 'mysql', 'postgres', 'webmin' ); @features = ( 'unix', @opt_features ); @backup_features = ( 'virtualmin', @features ); foreach $fname (@features) { require "$module_root_directory/feature-$fname.pl"; } $backup_cron_cmd = "$module_config_directory/backup.pl"; sub require_useradmin { return if ($require_useradmin++); &foreign_require("useradmin", "user-lib.pl"); %uconfig = &foreign_config("useradmin"); &foreign_require("quota", "quota-lib.pl"); $home_base = $config{'home_base'} || $uconfig{'home_base'}; } $domains_dir = "$module_config_directory/domains"; # list_domains() # Returns a list of structures containing information about hosted domains sub list_domains { local (@rv, $d); opendir(DIR, $domains_dir); foreach $d (readdir(DIR)) { if ($d !~ /^\./ && $d !~ /\.(lock|bak|rpmsave)$/i) { push(@rv, &get_domain($d)); } } closedir(DIR); return @rv; } # get_domain(id) sub get_domain { local %dom; &read_file("$domains_dir/$_[0]", \%dom) || return undef; $dom{'file'} = "$domains_dir/$_[0]"; $dom{'id'} = $_[0]; $dom{'mail'} = 1 if (!defined($dom{'mail'})); # compat - assume mail is on $dom{'ugid'} = $dom{'gid'} if (!defined($dom{'ugid'})); # compat - assume same if ($dom{'disabled'} eq '1') { # compat - assume everything was disabled $dom{'disabled'} = "unix,web,dns,mail,mysql,postgres"; } elsif ($dom{'disabled'}) { # compat - user disabled has changed to unix $dom{'disabled'} =~ s/user/unix/g; } if (!defined($dom{'created'})) { # compat - creation date can be inferred from ID $dom{'id'} =~ /^(\d{10})/; $dom{'created'} = $1; } if (!defined($dom{'gid'})) { # compat - get GID from group name $dom{'gid'} = getgrnam($dom{'group'}); } if (!defined($dom{'unix'})) { # compat - unix is always on $dom{'unix'} = 1; } if (!defined($dom{'virt'})) { # compat - assume virtual IP if interface assigned $dom{'virt'} = $dom{'iface'} ? 1 : 0; } if (!defined($dom{'web_port'}) && $dom{'web'}) { # compat - assume web port is current setting $dom{'web_port'} = $web_port; } if (!defined($dom{'web_sslport'}) && $dom{'ssl'}) { # compat - assume SSL port is current setting $dom{'web_sslport'} = $web_sslport; } return \%dom; } # get_domain_by(field, value) sub get_domain_by { local $d; foreach $d (&list_domains()) { if ($d->{$_[0]} eq $_[1]) { return $d; } } return undef; } # domain_id() # Returns a new unique domain ID sub domain_id { return time().$$; } # save_domain(&domain) sub save_domain { mkdir($domains_dir, 0700); &lock_file("$domains_dir/$_[0]->{'id'}"); $_[0]->{'id'} = &domain_id() if (!$_[0]->{'id'}); $_[0]->{'created'} = time() if (!$_[0]->{'created'}); &write_file("$domains_dir/$_[0]->{'id'}", $_[0]); &unlock_file("$domains_dir/$_[0]->{'id'}"); return 1; } # delete_domain(&domain) sub delete_domain { &lock_file("$domains_dir/$_[0]->{'id'}"); unlink("$domains_dir/$_[0]->{'id'}"); &unlock_file("$domains_dir/$_[0]->{'id'}"); } # list_domain_users([&domain], [skipunix]) # List all Unix users who are in the domain's primary group, except the owner. # If domain is omitted, returns local users. sub list_domain_users { # Get all aliases (and maybe generics) to look for those that match users local (%aliases, %generics); if ($config{'mail'}) { &require_mail(); if ($config{'mail_system'} == 1) { %aliases = map { $_->{'name'}, $_ } grep { $_->{'enabled'} } &sendmail::list_aliases($sendmail_afiles); if ($config{'generics'}) { %generics = map { $_->{'from'}, $_ } &sendmail::list_generics($sendmail_gfile); } } elsif ($config{'mail_system'} == 0) { %aliases = map { $_->{'name'}, $_ } &postfix::list_aliases($postfix_afiles); if ($config{'generics'}) { local $cans = &postfix::get_maps($canonical_type); %generics = map { $_->{'name'}, $_ } @$cans; } } } # Get all virtusers to look for those for users local @virts = &list_virtusers(); local @users = &list_all_users_quotas(); if ($_[0]) { # Limit to domain users @users = grep { $_->{'gid'} == $_[0]->{'gid'} || $_->{'user'} eq $_[0]->{'user'} } @users; @users = grep { $_->{'user'} ne $_[0]->{'user'} } @users if ($_[1]); } else { # Limit to local users local @lg = getgrnam($config{'localgroup'}); @users = grep { $_->{'gid'} == $lg[2] } @users; } foreach $u (@users) { if ($aliases{$u->{'user'}}) { $u->{'alias'} = $aliases{$u->{'user'}}; $u->{'to'} = $u->{'alias'}->{'values'}; } $u->{'generic'} = $generics{$u->{'user'}}; local $pop3 = $_[0] ? &remove_userdom($u->{'user'}, $_[0]) : $u->{'user'}; local $email = $_[0] ? "$pop3\@$_[0]->{'dom'}" : undef; foreach $v (@virts) { if (@{$v->{'to'}} == 1 && $v->{'to'}->[0] eq $u->{'user'}) { if ($v->{'from'} eq $email) { $u->{'email'} = $email; $u->{'virt'} = $v; } else { push(@{$u->{'extraemail'}}, $v->{'from'}); push(@{$u->{'extravirt'}}, $v); } } } } return @users; } # list_all_users_quotas() # Returns a list of all Unix users, with quota info sub list_all_users_quotas { # Get quotas for all users &require_useradmin(); local $qv = $config{'hard_quotas'} ? 'hblocks' : 'sblocks'; if (!defined(%home_quotas) && $config{'home_quotas'}) { local $n = "a::filesystem_users($config{'home_quotas'}); local $i; for($i=0; $i<$n; $i++) { $home_quota{$quota::user{$i,'user'}} = $quota::user{$i,$qv}; $used_home_quota{$quota::user{$i,'user'}} = $quota::user{$i,'ublocks'}; } } if (!defined(%mail_quotas) && $config{'mail_quotas'} && $config{'mail_quotas'} ne $config{'home_quotas'}) { local $n = "a::filesystem_users($config{'mail_quotas'}); local $i; for($i=0; $i<$n; $i++) { $mail_quota{$quota::user{$i,'user'}} = $quota::user{$i,$qv}; $used_mail_quota{$quota::user{$i,'user'}} = $quota::user{$i,'ublocks'}; } } # Get user list and add in quota info local @users = &useradmin::list_users(); local $u; foreach $u (@users) { $u->{'quota'} = $home_quota{$u->{'user'}}; $u->{'uquota'} = $used_home_quota{$u->{'user'}}; $u->{'mquota'} = $mail_quota{$u->{'user'}}; $u->{'umquota'} = $used_mail_quota{$u->{'user'}}; } return @users; } # create_user(&user, [&domain]) # Create a mailbox or local user, his virtuser and possibly his alias sub create_user { &require_useradmin(); &require_mail(); # Add the user &useradmin::set_user_envs($_[0], 'CREATE_USER', $_[0]->{'plainpass'}, [ ]); &useradmin::making_changes(); &useradmin::lock_user_files(); &useradmin::create_user($_[0]); &useradmin::unlock_user_files(); &useradmin::made_changes(); # Add his virtusers addresses local $firstemail; if ($_[0]->{'email'}) { local $virt = { 'from' => $_[0]->{'email'}, 'to' => [ $_[0]->{'user'} ] }; &create_virtuser($virt); $_[0]->{'virt'} = $virt; $firstemail ||= $_[0]->{'email'}; } local @extravirt; foreach $e (@{$_[0]->{'extraemail'}}) { local $virt = { 'from' => $e, 'to' => [ $_[0]->{'user'} ] }; &create_virtuser($virt); push(@extravirt, $virt); $firstemail ||= $e; } $_[0]->{'extravirt'} = \@extravirt; # Add his alias, if any if ($_[0]->{'to'}) { local $alias = { 'name' => $_[0]->{'user'}, 'enabled' => 1, 'values' => $_[0]->{'to'} }; &check_alias_clash($_[0]->{'user'}) && &error(&text('alias_eclash2', $_[0]->{'user'})); if ($config{'mail_system'} == 1) { &sendmail::lock_alias_files($sendmail_afiles); &sendmail::create_alias($alias, $sendmail_afiles); &sendmail::unlock_alias_files($sendmail_afiles); } elsif ($config{'mail_system'} == 0) { &postfix::lock_alias_files($postfix_afiles); &postfix::create_alias($alias, $postfix_afiles); &postfix::unlock_alias_files($postfix_afiles); &postfix::regenerate_aliases(); } elsif ($config{'mail_system'} == 2) { # Not done for qmail yet } $_[0]->{'alias'} = $alias; } if ($config{'generics'} && $firstemail) { # Add genericstable entry too if ($config{'mail_system'} == 1) { local $gen = { 'from' => $_[0]->{'user'}, 'to' => $firstemail }; &lock_file($sendmail_gfile); &sendmail::create_generic($gen, $sendmail_gfile, $sendmail_gdbm, $sendmail_gdbmtype); &unlock_file($sendmail_gfile); } elsif ($config{'mail_system'} == 0) { local $gen = { 'name' => $_[0]->{'user'}, 'value' => $firstemail }; &lock_file($canonical_map_files[0]); &postfix::create_mapping($canonical_type, $gen); &unlock_file($canonical_map_files[0]); } elsif ($config{'mail_system'} == 2) { # is this even possible for qmail? } } } # modify_user(&user, &old, &domain) sub modify_user { &require_useradmin(); &require_mail(); # Update the unix user &useradmin::set_user_envs($_[0], 'MODIFY_USER', $_[0]->{'plainpass'}); &useradmin::making_changes(); &useradmin::lock_user_files(); &useradmin::modify_user($_[1], $_[0]); &useradmin::unlock_user_files(); &useradmin::made_changes(); # Take away all virtusers and add new ones &delete_virtuser($_[1]->{'virt'}) if ($_[1]->{'virt'}); local $e; foreach $e (@{$_[1]->{'extravirt'}}) { &delete_virtuser($e); } local $firstemail; if ($_[0]->{'email'}) { local $virt = { 'from' => $_[0]->{'email'}, 'to' => [ $_[0]->{'user'} ] }; &create_virtuser($virt); $_[0]->{'virt'} = $virt; $firstemail ||= $_[0]->{'email'}; } local @extravirt; foreach $e (@{$_[0]->{'extraemail'}}) { local $virt = { 'from' => $e, 'to' => [ $_[0]->{'user'} ] }; &create_virtuser($virt); push(@extravirt, $virt); $firstemail ||= $e; } $_[0]->{'extravirt'} = \@extravirt; # Update, create or delete alias if ($_[0]->{'to'} && !$_[1]->{'to'}) { # Need to add alias local $alias = { 'name' => $_[0]->{'user'}, 'enabled' => 1, 'values' => $_[0]->{'to'} }; &check_alias_clash($_[0]->{'user'}) && &error(&text('alias_eclash2', $_[0]->{'user'})); if ($config{'mail_system'} == 1) { &sendmail::lock_alias_files($sendmail_afiles); &sendmail::create_alias($alias, $sendmail_afiles); &sendmail::unlock_alias_files($sendmail_afiles); } elsif ($config{'mail_system'} == 0) { &postfix::lock_alias_files($postfix_afiles); &postfix::create_alias($alias, $postfix_afiles); &postfix::unlock_alias_files($postfix_afiles); &postfix::regenerate_aliases(); } $_[0]->{'alias'} = $alias; } elsif (!$_[0]->{'to'} && $_[1]->{'to'}) { # Need to delete alias if ($config{'mail_system'} == 1) { &lock_file($_[0]->{'alias'}->{'file'}); &sendmail::delete_alias($_[0]->{'alias'}); &unlock_file($_[0]->{'alias'}->{'file'}); } elsif ($config{'mail_system'} == 0) { &lock_file($_[0]->{'alias'}->{'file'}); &postfix::delete_alias($_[0]->{'alias'}); &unlock_file($_[0]->{'alias'}->{'file'}); &postfix::regenerate_aliases(); } } elsif ($_[0]->{'to'} && $_[1]->{'to'}) { # Need to update the alias local $alias = { 'name' => $_[0]->{'user'}, 'enabled' => 1, 'values' => $_[0]->{'to'} }; if ($config{'mail_system'} == 1) { &lock_file($_[1]->{'alias'}->{'file'}); &sendmail::modify_alias($_[1]->{'alias'}, $alias); &unlock_file($_[1]->{'alias'}->{'file'}); } elsif ($config{'mail_system'} == 0) { &lock_file($_[1]->{'alias'}->{'file'}); &postfix::modify_alias($_[1]->{'alias'}, $alias); &unlock_file($_[1]->{'alias'}->{'file'}); &postfix::regenerate_aliases(); } $_[0]->{'alias'} = $alias; } if ($config{'generics'} && $_[0]->{'generic'}) { # Update genericstable entry too if ($config{'mail_system'} == 1) { &lock_file($sendmail_gfile); &sendmail::delete_generic($_[0]->{'generic'}, $sendmail_gfile, $sendmail_gdbm, $sendmail_gdbmtype); if ($firstemail) { local $gen = { 'from' => $_[0]->{'user'}, 'to' => $firstemail }; &sendmail::create_generic($gen, $sendmail_gfile, $sendmail_gdbm, $sendmail_gdbmtype) } &unlock_file($sendmail_gfile); } elsif ($config{'mail_system'} == 0) { &lock_file($canonical_map_files[0]); &postfix::delete_mapping($canonical_type, $_[0]->{'generic'}); if ($firstemail) { local $gen = { 'name' => $_[0]->{'user'}, 'value' => $firstemail }; &postfix::create_mapping($canonical_type, $gen); } &unlock_file($canonical_map_files[0]); } elsif ($config{'mail_system'} == 2) { # is this even possible for qmail? } } } # delete_user(&user, domain) # Delete a mailbox user and all associated virtusers and aliases sub delete_user { $_[0]->{'user'} eq 'root' && &error("Cannot delete root user!"); $_[0]->{'uid'} == 0 && &error("Cannot delete UID 0 user!"); &require_useradmin(); &require_mail(); # Delete the user &useradmin::set_user_envs($_[0], 'DELETE_USER') &useradmin::making_changes(); &useradmin::lock_user_files(); &useradmin::delete_user($_[0]); &useradmin::unlock_user_files(); &useradmin::made_changes(); # Delete any virtusers &delete_virtuser($_[0]->{'virt'}) if ($_[0]->{'virt'}); local $e; foreach $e (@{$_[0]->{'extravirt'}}) { &delete_virtuser($e); } # Delete his alias, if any if ($_[0]->{'alias'}) { if ($config{'mail_system'} == 1) { &lock_file($_[0]->{'alias'}->{'file'}); &sendmail::delete_alias($_[0]->{'alias'}); &unlock_file($_[0]->{'alias'}->{'file'}); } elsif ($config{'mail_system'} == 0) { &lock_file($_[0]->{'alias'}->{'file'}); &postfix::delete_alias($_[0]->{'alias'}); &unlock_file($_[0]->{'alias'}->{'file'}); &postfix::regenerate_aliases(); } } if ($config{'generics'} && $_[0]->{'generic'}) { # Delete genericstable entry too if ($config{'mail_system'} == 1) { &lock_file($sendmail_gfile); &sendmail::delete_generic($_[0]->{'generic'}, $sendmail_gfile, $sendmail_gdbm, $sendmail_gdbmtype); &unlock_file($sendmail_gfile); } elsif ($config{'mail_system'} == 0) { &lock_file($_[0]->{'generic'}->{'file'}); &postfix::delete_mapping($canonical_type, $_[0]->{'generic'}); &unlock_file($_[0]->{'generic'}->{'file'}); } } } # domain_title(&domain) sub domain_title { print "
",&text('indom', "$_[0]->{'dom'}"), "
\n"; } # check_clash(name, dom) # Returns the clash if a virtuser or user with the name already exists sub check_clash { local @virts = &list_virtusers(); local ($clash) = grep { $_->{'from'} eq $_[0]."\@".$_[1] } @virts; return $clash; } # copy_skel_files(basedir, &user, [group]) # Copy files to the home directory of some new user sub copy_skel_files { local $uf = $_[0]; return if (!$uf); &require_useradmin(); local $shell = $_[1]->{'shell'}; $shell =~ s/^(.*)\///g; local $group = $_[2]; $group = getgrgid($_[1]->{'gid'}) if (!$group); $uf =~ s/\$group/$group/g; $uf =~ s/\$gid/$_[1]->{'gid'}/g; $uf =~ s/\$shell/$shell/g; &useradmin::copy_skel_files($uf, $_[1]->{'home'}, $_[1]->{'uid'}, $_[1]->{'gid'}); } # can_edit_domain(&domain) # Returns 1 if the current user can edit some domain sub can_edit_domain { return 1 if ($access{'domains'} eq "*"); local $d; foreach $d (split(/\s+/, $access{'domains'})) { return 1 if ($d eq $_[0]->{'id'}); } return 0; } # domains_table(&domains) # Display a list of domains in a table, with links for editing sub domains_table { local @table_features = $config{'show_features'} ? (grep { $_ ne 'webmin' && $_ ne 'mail' && $_ ne 'unix' } @features) : ( ); print "\n"; print " ", " ", " "; local $f; foreach $f (@table_features) { print " " if ($config{$f}); } if ($config{'mail'}) { print " "; print " "; } if ($config{'home_quotas'}) { print " ". " "; } print "\n"; local $d; foreach $d (sort { $a->{'dom'} cmp $b->{'dom'} } @{$_[0]}) { print "\n"; local $dn = $d->{'disabled'} ? "$d->{'dom'}" : $d->{'dom'}; if ($access{'edit'}) { print "\n"; } else { print "\n"; } print "\n"; print "\n"; foreach $f (@table_features) { print "\n" if ($config{$f}); } local @users = &list_domain_users($d); local ($duser) = grep { $_->{'user'} eq $d->{'user'} } @users; if ($config{'mail'}) { if ($d->{'mail'}) { local @aliases = &list_domain_aliases($d); printf "\n", scalar(@users), $d->{'mailboxlimit'} ? " of $d->{'mailboxlimit'}" : ""; printf "\n", scalar(@aliases); } else { print "\n"; } } if ($config{'home_quotas'}) { print "\n"; local $ut = $duser->{'uquota'} + $duser->{'umquota'}; foreach $u (@users) { $ut += $u->{'uquota'} + $u->{'umquota'} if ($u->{'user'} ne $d->{'user'}); } print "\n"; } print "\n"; } print "
$text{'index_domain'}$text{'index_user'}$text{'index_owner'}",$text{'index_'.$f},"$text{'index_mail'}$text{'index_alias'}$text{'index_quota'}$text{'index_uquota'}
", "$dn$dn$d->{'user'}$d->{'owner'}",$d->{$f} ? $text{'yes'} : $text{'no'},"%d%s ($text{'index_list'})%d ($text{'index_list'})$text{'index_nomail'}",$d->{'quota'} ? "a_show($d->{'quota'}, $config{'home_quotas'}) : $text{'form_unlimit'},"","a_show($ut, $config{'home_quotas'}),"
\n"; } # userdom_name(name, &domain) # Returns a username with the domain group appended somehow sub userdom_name { if ($config{'append_style'} == 0) { return $_[0].".".$_[1]->{'group'}; } elsif ($config{'append_style'} == 1) { return $_[0]."-".$_[1]->{'group'}; } elsif ($config{'append_style'} == 2) { return $_[1]->{'group'}.".".$_[0]; } elsif ($config{'append_style'} == 3) { return $_[1]->{'group'}."-".$_[0]; } elsif ($config{'append_style'} == 4) { return $_[0]."_".$_[1]->{'group'}; } elsif ($config{'append_style'} == 5) { return $_[1]->{'group'}."_".$_[0]; } else { &error("Unknown append_style $config{'append_style'}!"); } } # remove_userdom(name, &domain) # Returns a username with the domain group stripped off sub remove_userdom { local $g = $_[1]->{'group'}; local $rv = $_[0]; ($rv =~ s/(\.|\-|_)\Q$g\E$//) || ($rv =~ s/^\Q$g\E(\.|\-|_)//); return $rv; } # too_long(name) # Returns an error message if a username is too long for this Unix variant sub too_long { &require_useradmin(); if ($uconfig{'max_length'} && length($_[0]) > $uconfig{'max_length'}) { return &text('user_elong', "$_[0]", $uconfig{'max_length'}); } else { return undef; } } # get_default_ip() # Returns this system's primary IP address sub get_default_ip { if ($config{'defip'}) { return $config{'defip'}; } else { &foreign_require("net", "net-lib.pl"); local ($iface) = grep { $_->{'fullname'} eq $config{'iface'} } &net::active_interfaces(); return $iface->{'address'}; } } # check_apache_directives() # Returns an error string if the default Apache directives don't look valid sub check_apache_directives { local ($d, $gotname, $gotdom, $gotdoc, $gotproxy); local @dirs = split(/\t+/, $config{'apache_config'}); foreach $d (@dirs) { $d =~ s/#.*$//; if ($d =~ /^\s*ServerName\s+(\S+)$/i) { $gotname++; $gotdom++ if ($1 eq '$DOM' || $1 eq '${DOM}'); } if ($d =~ /^\s*ServerAlias\s+(.*)$/) { $gotdom++ if (&indexof('$DOM', split(/\s+/, $1)) >= 0 || &indexof('${DOM}', split(/\s+/, $1)) >= 0); } $gotdoc++ if ($d =~ /^\s*DocumentRoot\s+(.*)$/); $gotproxy++ if ($d =~ /^\s*ProxyPass\s+(.*)$/); } $gotname || return $text{'acheck_ename'}; $gotdom || return $text{'acheck_edom'}; $gotdoc || $gotproxy || return $text{'acheck_edoc'}; return undef; } # Print functions for HTML output sub first_html_print { print @_,"
\n"; } sub second_html_print { print @_,"

\n"; } sub indent_html_print { print "

    \n"; } sub outdent_html_print { print "
\n"; } # Print functions for text output sub first_text_print { print $indent_text,@_,"\n"; } sub second_text_print { print $indent_text,@_,"\n\n"; } sub indent_text_print { $indent_text .= " "; } sub outdent_text_print { $indent_text = substr($indent_text, 4); } sub null_print { } # send_domain_email(&domain) # Sends email to a new domain owner. Returns a pair containing a number # (0=failed, 1=success) and an optional message. Also outputs status messages. sub send_domain_email { &ensure_template("domain-template"); return (1, undef) if ($config{'domain_template'} eq 'none'); &$first_print($text{'setup_email'}); local $tmpl = $config{'domain_template'} eq 'default' ? "$module_config_directory/domain-template" : $config{'domain_template'}; local @erv = &send_template_email($tmpl, $_[0]->{'email'} || $_[0]->{'user'}.'@'.&get_system_hostname(), $_[0], $text{'mail_dsubject'}); if ($erv[0]) { &$second_print(&text('setup_emailok', $erv[1])); } else { &$second_print(&text('setup_emailfailed', $erv[1])); } } # send_user_email([&domain], &user) # Sends email to a new mailbox user. Returns a pair containing a number # (0=failed, 1=success) and an optional message sub send_user_email { local $tmode = $_[0] ? "user" : "local"; &ensure_template($tmode."-template"); return (1, undef) if ($config{$tmode.'_template'} eq 'none'); local $tmpl = $config{$tmode.'_template'} eq 'default' ? "$module_config_directory/$tmode-template" : $config{$tmode.'_template'}; local %hash; local $email; if ($_[0]) { %hash = ( %{$_[0]}, %{$_[1]} ); $hash{'mailbox'} = &remove_userdom($_[1]->{'user'}, $_[0]); $email = $hash{'mailbox'}.'@'.$hash{'dom'}; } else { %hash = ( %{$_[1]} ); $hash{'mailbox'} = $hash{'user'}; $email = $hash{'user'}.'@'.&get_system_hostname(); } $hash{'ftp'} = $_[1]->{'shell'} eq $config{'ftp_shell'} ? 1 : 0; return &send_template_email($tmpl, $email, \%hash, $text{'mail_usubject'}); } # ensure_template(file) sub ensure_template { &system_logged("cp $module_root_directory/$_[0] $module_config_directory/$_[0]") if (!-r "$module_config_directory/$_[0]"); } # send_template_email(file, address, &substitions, subject) # Sends the given file to the specified address, with the substitions from # a hash reference. The actual subs in the file must be like $XXX for entries # in the hash like xxx - ie. $DOM is replaced by the domain name, and $HOME # by the home directory sub send_template_email { # Read the file local $tmpl; open(FILE, $_[0]) || return (0, &text('mail_file', "$_[0]", $!)); while() { $tmpl .= $_; } close(FILE); $tmpl = &substitute_template($tmpl, $_[2]); # Actually send using the configured mail module return (0, $text{'mail_system'}) if (!$config{'mail'} || $config{'mail_system'} == 3); &require_mail(); local $mail = { 'headers' => [ [ 'From', $config{'from_addr'} || "root\@".&get_system_hostname() ], [ 'To', $_[1] ], [ 'Subject', $_[3] ], [ 'Content-type', 'text/plain' ] ], 'body' => $tmpl }; &foreign_require("mailboxes", "mailboxes-lib.pl"); &foreign_call("mailboxes", "send_mail", $mail); return (1, &text('mail_ok', $_[1])); } # substitute_template(text, &hash) # Given some text and a hash reference, for each ocurrance of $FOO or ${FOO} in # the text replaces it with the value of the hash key foo sub substitute_template { # Add some extra fixed parameters to the hash local %hash = %{$_[1]}; $hash{'hostname'} = &get_system_hostname(); # Actually do the substition local $rv = $_[0]; local $s; foreach $s (keys %hash) { local $us = uc($s); local $sv = $hash{$s}; $rv =~ s/\$\{\Q$us\E\}/$sv/g; $rv =~ s/\$\Q$us\E/$sv/g; if ($sv) { $rv =~ s/\$\{IF-\Q$us\E\}(\n?)([\000-\377]*)\$\{ELSE-\Q$us\E\}(\n?)([\000-\377]*)\$\{ENDIF-\Q$us\E\}(\n?)/\2/g; $rv =~ s/\$\{IF-\Q$us\E\}(\n?)([\000-\377]*)\$\{ENDIF-\Q$us\E\}(\n?)/\2/g; $rv =~ s/\$IF-\Q$us\E(\n?)([\000-\377]*)\$ELSE-\Q$us\E(\n?)([\000-\377]*)\$ENDIF-\Q$us\E(\n?)/\2/g; $rv =~ s/\$IF-\Q$us\E(\n?)([\000-\377]*)\$ENDIF-\Q$us\E(\n?)/\2/g; } else { $rv =~ s/\$\{IF-\Q$us\E\}(\n?)([\000-\377]*)\$\{ELSE-\Q$us\E\}(\n?)([\000-\377]*)\$\{ENDIF-\Q$us\E\}(\n?)/\4/g; $rv =~ s/\$\{IF-\Q$us\E\}(\n?)([\000-\377]*)\$\{ENDIF-\Q$us\E\}(\n?)//g; $rv =~ s/\$IF-\Q$us\E(\n?)([\000-\377]*)\$ELSE-\Q$us\E(\n?)([\000-\377]*)\$ENDIF-\Q$us\E(\n?)/\4/g; $rv =~ s/\$IF-\Q$us\E(\n?)([\000-\377]*)\$ENDIF-\Q$us\E(\n?)//g; } } return $rv; } # alias_type(string) # Return the type and destination of some alias string sub alias_type { local @rv; if ($_[0] =~ /^\|$module_config_directory\/autoreply.pl\s+(\S+)/) { @rv = (5, $1); } elsif ($_[0] =~ /^\|$module_config_directory\/filter.pl\s+(\S+)/) { @rv = (6, $1); } elsif ($_[0] =~ /^\|(.*)$/) { @rv = (4, $1); } elsif ($_[0] =~ /^(\/.*)$/) { @rv = (3, $1); } elsif ($_[0] =~ /^:include:(.*)$/) { @rv = (2, $1); } elsif ($_[0] =~ /^\\(\S+)$/) { @rv = (7, $1); } else { @rv = (1, $_[0]); } return wantarray ? @rv : $rv[0]; } # set_domain_envs(&domain, action) # Sets up VIRTUALSERVER_ environment variables for a domain update or some kind, # prior to calling making_changes or made_changes. action must be one of # CREATE_DOMAIN, MODIFY_DOMAIN or DELETE_DOMAIN sub set_domain_envs { local $e; foreach $e (keys %ENVS) { delete($ENV{$e}) if ($e =~ /^VIRTUALSERVER_/); } $ENV{'VIRTUALSERVER_ACTION'} = $_[1]; foreach $e (keys %{$_[0]}) { $ENV{'VIRTUALSERVER_'.uc($e)} = $_[0]->{$e}; } } # making_changes() # Called before a domain is created, modified or deleted to run the # pre-change command sub making_changes { if ($config{'pre_command'} =~ /\S/) { local $out = &backquote_logged("($config{'pre_command'}) 2>&1 &1 {'ugid'}, "$_[0]->{'ugid'} ".join(" ", $_[0]->{'ugid'}, &other_groups($_[0]->{'user'})) ); ($<, $>) = ( $_[0]->{'uid'}, $_[0]->{'uid'} ); $ENV{'USER'} = $ENV{'LOGNAME'} = $_[0]->{'user'}; $ENV{'HOME'} = $_[0]->{'home'}; } # print_subs_table(sub, ..) sub print_subs_table { print "\n"; foreach $k (@_) { print "\n"; print "\n"; } print "
\${$k}",$text{"sub_".$k},"
\n"; print "$text{'sub_if'}

\n"; } # alias_form(&to, left, &domain, "user"|"alias", user|alias) sub alias_form { local @typenames = map { $text{"alias_type$_"} } (0 .. 7); $typenames[0] = "<$typenames[0]>"; local $left = $_[1]; local @values = @{$_[0]}; local $i; for($i=0; $i<=@values+2; $i++) { print " $left \n"; $left = ""; local ($type, $val) = $values[$i] ? &alias_type($values[$i]) : (0, ""); print "\n"; print "\n"; if ($config{'edit_afiles'} || $master_admin) { local $prog = $type == 2 ? "edit_afile.cgi" : $type == 5 ? "edit_rfile.cgi" : $type == 6 ? "edit_ffile.cgi" : undef; if ($prog && $_[2]) { local $di = $_[2] ? $_[2]->{'id'} : undef; print "$text{'alias_afile'}\n"; } } print " \n"; } } # parse_alias() # Returns a list of values for an alias, taken from the form generated by # &alias_form sub parse_alias { local (@values, $i, $t); for($i=0; defined($t = $in{"type_$i"}); $i++) { !$t || $can_alias_types{$t} || &error($text{'alias_etype'}); local $v = $in{"val_$i"}; $v =~ s/^\s+//; $v =~ s/\s+$//; if ($t == 1 && $v !~ /^(\S+)$/) { &error(&text('alias_etype1', $v)); } elsif ($t == 3 && $v !~ /^\/(\S+)$/) { &error(&text('alias_etype3', $v)); } elsif ($t == 4) { $v =~ /^(\S+)/ || &error($text{'alias_etype4none'}); (-x $1) && &check_aliasfile($1, 0) || &error(&text('asave_etype4', $1)); } elsif ($t == 7 && !defined(getpwnam($v))) { &error(&text('asave_etype7', $v)); } if ($t == 1 || $t == 3) { push(@values, $v); } elsif ($t == 2) { $v = "$d->{'home'}/$v" if ($v !~ /^\//); push(@values, ":include:$v"); } elsif ($t == 4) { $v = "$d->{'home'}/$v" if ($v !~ /^\//); push(@values, "|$v"); } elsif ($t == 5) { # Setup autoreply script $v = "$d->{'home'}/$v" if ($v !~ /^\//); push(@values, "|$module_config_directory/autoreply.pl ". "$v $name"); &system_logged("cp autoreply.pl $module_config_directory"); &system_logged("chmod 755 $module_config_directory/config"); if (-d $sendmail::config{'smrsh_dir'}) { &system_logged("ln -s $module_config_directory/autoreply.pl $sendmail::config{'smrsh_dir'}/autoreply.pl"); } } elsif ($t == 6) { # Setup filter script $v = "$d->{'home'}/$v" if ($v !~ /^\//); push(@values, "|$module_config_directory/filter.pl ". "$v $name"); &system_logged("cp filter.pl $module_config_directory"); &system_logged("chmod 755 $module_config_directory/config"); if (-d $sendmail::config{'smrsh_dir'}) { &system_logged("ln -s $module_config_directory/filter.pl $sendmail::config{'smrsh_dir'}/filter.pl"); } } elsif ($t == 7) { push(@values, "\\$v"); } } return @values; } # set_pass_change(&user) sub set_pass_change { &require_useradmin(); local $pft = &useradmin::passfiles_type(); if ($pft == 2 || $pft == 5) { $_[0]->{'change'} = int(time() / (60*60*24)); } elsif ($pft == 4) { $_[0]->{'change'} = time(); } } # build_taken(&uid-taken, &username-taken, [&users]) # Fills in the the given hashes with used usernames and UIDs sub build_taken { &require_useradmin(); local @users = $_[2] ? @{$_[2]} : &useradmin::list_users(); %{$_[0]} = map { $_->{'uid'}, 1 } @users; %{$_[1]} = map { $_->{'user'}, 1 } @users; } # build_group_taken(&gid-taken, &groupname-taken, [&groups]) # Fills in the the given hashes with used group names and GIDs sub build_group_taken { &require_useradmin(); local @groups = $_[2] ? @{$_[2]} : &useradmin::list_groups(); %{$_[0]} = map { $_->{'gid'}, 1 } @groups; %{$_[1]} = map { $_->{'group'}, 1 } @groups; } # allocate_uid(&uid-taken) sub allocate_uid { local $uid = $uconfig{'base_uid'}; while($_[0]->{$uid}) { $uid++; } return $uid; } # allocate_gid(&gid-taken) sub allocate_gid { local $gid = $uconfig{'base_gid'}; while($_[0]->{$gid}) { $gid++; } return $gid; } # server_home_directory(&domain) # Returns the home directory for a new virtual server user sub server_home_directory { if ($config{'home_format'}) { # Use the template from the module config local $home = "$home_base/$config{'home_format'}"; return &substitute_template($home, $_[0]); } else { # Just use the Users and Groups module settings return &useradmin::auto_home_dir($home_base, $_[0]->{'user'}, $_[0]->{'ugroup'}); } } # set_quota(user, filesystem, quota) sub set_quota { &require_useradmin(); if ($config{'hard_quotas'}) { "a::edit_user_quota($_[0], $_[1], int($_[2]), int($_[2]), 0, 0); } else { "a::edit_user_quota($_[0], $_[1], int($_[2]), 0, 0, 0); } } # set_server_quotas(&domain) # Set the user and possibly group quotas for a domain sub set_server_quotas { if ($config{'home_quotas'}) { &set_quota($_[0]->{'user'}, $config{'home_quotas'}, $_[0]->{'uquota'}); } if ($config{'mail_quotas'} && $config{'mail_quotas'} ne $config{'home_quotas'}) { &set_quota($_[0]->{'user'}, $config{'mail_quotas'}, $_[0]->{'uquota'}); } if ($config{'group_quotas'}) { &require_useradmin(); if ($config{'hard_quotas'}) { "a::edit_group_quota( $_[0]->{'group'}, $config{'home_quotas'}, int($_[0]->{'quota'}), int($_[0]->{'quota'}), 0, 0); } else { "a::edit_group_quota( $_[0]->{'group'}, $config{'home_quotas'}, int($_[0]->{'quota'}), 0, 0, 0); } } } # nice_size(bytes) sub nice_size { return $_[0] > 10*1024*1024 ? int($_[0]/1024/1024)." MB" : $_[0] > 10*1024 ? int($_[0]/1024)." kB" : $_[0]." b"; } # users_table(&users, &dom) # Output a table of mailbox users sub users_table { print "\n"; print " ", " ", " ", $config{'home_quotas'} || $config{'mail_quotas'} ? " " : "", " ", "\n"; local $u; local $did = $_[1] ? $_[1]->{'id'} : 0; foreach $u (@{$_[0]}) { local $pop3 = $_[1] ? &remove_userdom($u->{'user'}, $_[1]) : $u->{'user'}; local $domuser = $_[1] && $u->{'user'} eq $_[1]->{'user'}; print "\n"; print "\n"; print "\n"; print "\n"; local $quota; $quota += $u->{'quota'} if ($config{'home_quotas'}); $quota += $u->{'mquota'} if ($config{'mail_quotas'} && $config{'home_quotas'} ne $config{'mail_quotas'}); if (defined($quota)) { print "\n"; } local ($sz) = &mail_file_size($u); $sz = $sz ? &nice_size($sz) : $text{'users_empty'}; local $lnk = &read_mail_link($u); if ($lnk) { print "\n"; } else { print "\n"; } printf "\n", $domuser ? $text{'users_main'} : $u->{'shell'} eq $config{'ftp_shell'} ? $text{'yes'} : $u->{'shell'} eq $config{'shell'} ? $text{'no'} : &text('users_shell', "$u->{'shell'}"); print "\n"; } print "
$text{'users_name'}$text{'users_pop3'}$text{'users_real'}$text{'users_quota'}$text{'users_size'}$text{'users_ftp'}
", ($domuser ? "$pop3" : $pop3),"$u->{'user'}$u->{'real'}",$quota ? "a_show($quota,$config{'home_quotas'}) : $text{'form_unlimit'},"$sz$sz%s
\n"; } # quota_bsize(filesystem) sub quota_bsize { &require_useradmin(); if (defined("a::block_size)) { local $bsize; if (!exists($bsize_cache{$_[0]})) { $bsize_cache{$_[0]} = "a::block_size($_[0]); } return $bsize_cache{$_[0]}; } return undef; } # quota_show(number, filesystem) # Returns text for the quota on some filesystem, in a human-readable format sub quota_show { local $bsize = "a_bsize($_[1]); if ($bsize) { return int($_[0]*$bsize/1024)." ".$text{'form_k'}; } return $_[0]." ".$text{'form_b'}; } # quota_input(name, number, filesystem) # Returns HTML for an input for entering a quota, doing block->kb conversion sub quota_input { local $bsize = "a_bsize($_[2]); return sprintf " %s", $_[0], $_[1] eq '' ? '' : $bsize ? int($_[1]*$bsize/1024) : $_[1], $bsize ? $text{'form_k'} : $text{'form_b'}; } # quota_parse(name, filesystem) # Converts an entered quota into blocks sub quota_parse { local $bsize = "a_bsize($_[1]); return $bsize ? int($in{$_[0]}*1024/$bsize) : $in{$_[0]}; } # setup_virt(&domain) # Bring up an interface for a domain, if the IP isn't already enabled sub setup_virt { &foreign_require("net", "net-lib.pl"); local @boot = &net::active_interfaces(); &$first_print($text{'setup_virt'}); local ($iface) = grep { $_->{'fullname'} eq $config{'iface'} } @boot; local $b; local $vmax = 0; foreach $b (@boot) { $vmax = $b->{'virtual'} if ($b->{'name'} eq $iface->{'name'} && $b->{'virtual'} > $vmax); } local $virt = { 'address' => $_[0]->{'ip'}, 'netmask' => $net::virtual_netmask || $iface->{'netmask'}, 'broadcast' => $net::virtual_netmask eq "255.255.255.255" ? $_[0]->{'ip'} : $iface->{'broadcast'}, 'name' => $iface->{'name'}, 'virtual' => $vmax+1, 'up' => 1 }; $virt->{'fullname'} = $virt->{'name'}.":".$virt->{'virtual'}; &net::save_interface($virt); &net::activate_interface($virt); $_[0]->{'iface'} = $virt->{'fullname'}; &$second_print(&text('setup_virtdone', $_[0]->{'iface'})); } # delete_virt(&domain) # Take down the network interface for a domain sub delete_virt { &$first_print($text{'delete_virt'}); &foreign_require("net", "net-lib.pl"); local ($biface) = grep { $_->{'fullname'} eq $_[0]->{'iface'} } &net::boot_interfaces(); local ($aiface) = grep { $_->{'fullname'} eq $_[0]->{'iface'} } &net::active_interfaces(); if ($biface->{'virtual'} ne '') { &net::delete_interface($biface); &net::deactivate_interface($aiface) if($aiface); &$second_print($text{'setup_done'}); } else { &$second_print(&text('delete_novirt', $d->{'iface'})); } } # check_virt_clash(ip) # Returns the interface if some IP is already in use sub check_virt_clash { &foreign_require("net", "net-lib.pl"); local @boot = &net::boot_interfaces(); local ($boot) = grep { $_->{'address'} eq $_[0] } @boot; local @active = &net::active_interfaces(); local ($active) = grep { $_->{'address'} eq $_[0] } @active; return $active || $boot; } # backup_domains(file, &domains, &features, dir-format, skip-errors, &options) # Perform a backup of one or more domains into a single tar.gz file. Returns # undef on success, or an error message. sub backup_domains { # Create a temp dir for the backup, to be tarred up later local $backupdir = &tempname(); mkdir($backupdir, 0700); # Go through all the domains, and for each feature call the backup function # to add it to the backup directory local $d; local $ok = 1; local @donedoms; DOMAIN: foreach $d (@{$_[1]}) { &$first_print(&text('backup_fordomain', $d->{'dom'})); &$second_print(); &$indent_print(); local $f; foreach $f (@{$_[2]}) { local $bfunc = "backup_$f"; if (defined(&$bfunc) && ($d->{$f} || $f eq "virtualmin")) { local $ffile = "$backupdir/$d->{'dom'}_$f"; local $fok = &$bfunc($d, $ffile, $_[5]->{$f}); if (!$fok && !$_[4]) { $ok = 0; last DOMAIN; } push(@donedoms, $d); } } &$outdent_print(); } # Work out where to write the final tar files to local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[0]); local ($dest, @destfiles); if ($mode == 1) { # Write archive to temporary file/dir first, for later upload $dest = &tempname(); } else { $dest = $path; } if ($ok) { local $out; if ($_[3]) { # Create one tar file in the destination for each domain &$first_print($text{'backup_final2'}); mkdir($dest, 0755); foreach $d (&unique(@donedoms)) { if (&has_command("gzip")) { $out = `cd $backupdir ; (tar cf - $d->{'dom'}_* | gzip -c) 2>&1 >$dest/$d->{'dom'}.tar.gz`; push(@destfiles, "$d->{'dom'}.tar.gz"); } else { $out = `cd $backupdir ; tar cf $dest/$d->{'dom'}.tar $d->{'dom'}_* 2>&1`; push(@destfiles, "$d->{'dom'}.tar"); } if ($?) { &$second_print(&text('backup_finalfailed', "

$out
")); $ok = 0; last; } } &$second_print($text{'setup_done'}) if ($ok); } else { # Tar up the directory into the final file &$first_print($text{'backup_final'}); if (&has_command("gzip")) { $out = `cd $backupdir ; (tar cf - . | gzip -c) 2>&1 >$dest`; } else { $out = `cd $backupdir ; tar cf $dest . 2>&1`; } if ($?) { &$second_print(&text('backup_finalfailed', "
$out
")); $ok = 0; } else { &$second_print($text{'setup_done'}); } } } system("rm -rf ".quotemeta($backupdir)); local $sz = $_[3] ? &disk_usage_kb($dest)*1024 : (@st=stat($dest))[7]; if ($ok && $mode == 1) { # Upload file(s) to FTP server &$first_print($text{'backup_upload'}); local $err; if ($_[3]) { # Need to upload entire directory .. which has to be created local $mkdirerr; &ftp_onecommand($server, "MKD $path", \$mkdirerr, $user, $pass); foreach $df (@destfiles) { &ftp_upload($server, "$path/$df", "$dest/$df", \$err, undef, $user, $pass); if ($err) { &$second_print( &text('backup_uploadfailed', $err)); $ok = 0; last; } } } else { # Just a single file &ftp_upload($server, $path, $dest, \$err, undef, $user, $pass); if ($err) { &$second_print(&text('backup_uploadfailed', $err)); $ok = 0; } } &$second_print($text{'setup_done'}) if ($ok); } if ($mode == 1) { # Always delete the temporary destination system("rm -rf ".quotemeta($dest)); } return ($ok, $sz); } # backup_virtualmin(&domain, file) # Adds a domain's configuration file to the backup sub backup_virtualmin { &$first_print($text{'backup_virtualmincp'}); system("cp ".quotemeta($_[0]->{'file'})." ".$_[1]); &$second_print($text{'setup_done'}); return 1; } # restore_domains(file, &domains, &features, &options) # Restore multiple domains from the given file sub restore_domains { # Work out where the backup is located local $ok = 1; local $backup; local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[0]); if ($mode > 0) { # Need to download to temp file/directory first &$first_print($text{'restore_download'}); $backup = &tempname(); local $derr = &download_backup($_[0], $backup); if ($derr) { &$second_print(&text('restore_downloadfailed', $derr)); $ok = 0; } else { &$second_print($text{'setup_done'}); } } else { $backup = $_[0]; } local $restoredir; if ($ok) { # Create a temp dir for the backup archive contents $restoredir = &tempname(); mkdir($restoredir, 0700); local @files; if (-d $backup) { # Extracting a directory of backup files &$first_print($text{'restore_first2'}); opendir(DIR, $backup); @files = map { "$backup/$_" } grep { $_ ne "." && $_ ne ".." } readdir(DIR); closedir(DIR); } else { # Extracting one backup file &$first_print($text{'restore_first'}); @files = ( $backup ); } # Extract each of the files local $f; foreach $f (@files) { open(BACKUP, $f); local $two; read(BACKUP, $two, 2); close(BACKUP); local $out; local $q = quotemeta($f); if ($two eq "\037\213") { # Assume gzipped tar $out = `cd '$restoredir' ; (gunzip -c $q | tar xf -) 2>&1`; } else { # Assume normal tar $out = `cd '$restoredir' ; tar xf $q 2>&1`; } if ($?) { &$second_print(&text('restore_firstfailed', "$f", "
$out
")); $ok = 0; last; } } &$second_print($text{'setup_done'}) if ($ok); } if ($ok) { # Now restore each of the domain/feature files local $d; $no_restart_webmin = 1; DOMAIN: foreach $d (@{$_[1]}) { &$first_print(&text('restore_fordomain', $d->{'dom'})); #&$second_print(); &$indent_print(); local $f; foreach $f (@{$_[2]}) { # Restore features local $rfunc = "restore_$f"; if (defined(&$rfunc) && ($d->{$f} || $f eq "virtualmin")) { local $ffile = "$restoredir/$d->{'dom'}_$f"; if (-r $ffile) { local $fok = &$rfunc($d, $ffile, $_[3]->{$f}); if (!$fok) { $ok = 0; &$outdent_print(); last DOMAIN; } } } } # Re-setup Webmin user &modify_webmin($d, $d); &$outdent_print(); } $no_restart_webmin = 0; &restart_webmin(); } system("rm -rf ".quotemeta($restoredir)); if ($mode > 0) { # Clean up downloaded file system("rm -rf ".quotemeta($backup)); } return $ok; } # backup_contents(file) # Returns a hash ref of domains and features in a backup file, or an error # string if it is invalid sub backup_contents { local $backup; local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[0]); if ($mode > 0) { # Need to download to temp file first $backup = &tempname(); local $derr = &download_backup($_[0], $backup); return $derr if ($derr); } else { $backup = $_[0]; } if (-d $backup) { # A directory of backup files, one per domain opendir(DIR, $backup); local $f; local %rv; foreach $f (readdir(DIR)) { next if ($f eq "." || $f eq ".."); local $cont = &backup_contents("$backup/$f"); if (ref($cont)) { local $d; foreach $d (keys %$cont) { if ($rv{$d}) { &clean_contents_temp(); return &text('restore_edup', $d); } else { $rv{$d} = $cont->{$d}; } } } else { &clean_contents_temp(); return $backup."/".$f." : ".$cont; } } closedir(DIR); &clean_contents_temp(); return \%rv; } else { # A single file local $err; open(BACKUP, $backup); local $two; read(BACKUP, $two, 2); close(BACKUP); local $out; local $q = quotemeta($backup); if ($two eq "\037\213") { # Assume gzipped tar $out = `(gunzip -c $q | tar tf -) 2>&1`; } else { # Assume normal tar $out = `tar tf $q 2>&1`; } if ($?) { &clean_contents_temp(); return $text{'restore_etar'}; } local ($l, %rv, %done); foreach $l (split(/\n/, $out)) { if ($l =~ /^(.\/)?([^_]+)_([a-z0-9]+)$/) { push(@{$rv{$2}}, $3) if (!$done{$2,$3}++); } } &clean_contents_temp(); return \%rv; } sub clean_contents_temp { system("rm -rf ".quotemeta($backup)) if ($mode > 0); } } # download_backup(url, tempfile) # Downloads a backup file or directory to a local temp file or directory. # Returns undef on success, or an error message. sub download_backup { local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[0]); local $cwderr; local $isdir = &ftp_onecommand($server, "CWD $path", \$cwderr, $user, $pass); local $err; if ($isdir) { # Need to download entire directory mkdir($_[1], 0700); local $list = &ftp_listdir($server, $path, \$err, $user, $pass); return $err if (!$list); foreach $f (@$list) { $f =~ s/^$path[\\\/]//; &ftp_download($server, "$path/$f", "$_[1]/$f", \$err, undef, $user, $pass); return $err if ($err); } return undef; } else { # Can just download a single file &ftp_download($server, $path, $_[1], \$err, undef, $user, $pass); return $err; } } # restore_virtualmin(&domain, file) # Restore the settings for a domain, such as quota, password and so on sub restore_virtualmin { &$first_print($text{'restore_virtualmincp'}); local %oldd; &read_file($_[1], \%oldd); $_[0]->{'quota'} = $oldd{'quota'}; $_[0]->{'uquota'} = $oldd{'uquota'}; $_[0]->{'pass'} = $oldd{'pass'}; $_[0]->{'email'} = $oldd{'email'}; $_[0]->{'mailboxlimit'} = $oldd{'mailboxlimit'}; $_[0]->{'owner'} = $oldd{'owner'}; &save_domain($_[0]); &$second_print($text{'setup_done'}); return 1; } # backup_strftime(path) # Replaces stftime-style % codes in a path with the current time sub backup_strftime { eval "use POSIX"; eval "use posix" if ($@); local @tm = localtime(time()); return strftime($_[0], @tm); } sub parse_backup_url { if ($_[0] =~ /^ftp:\/\/([^:]*):([^\@]*)\@([^\/]+)(\/.*)$/) { return (1, $1, $2, $3, $4); } else { return (0, undef, undef, undef, $_[0]); } } # show_backup_destination(name, value) # Returns HTML for a field for selecting a local or FTP file sub show_backup_destination { local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[1]); local $rv; # Local file field $rv .= ""; $rv .= sprintf "\n", $mode == 0 ? "checked" : ""; $rv .= sprintf "\n", $text{'backup_mode0'}, $mode == 0 ? $path : "", &file_chooser_button("$_[0]_file"); # FTP file fields $rv .= sprintf "\n", $mode == 1 ? "checked" : ""; $rv .= sprintf "\n", $text{'backup_mode1'}, $server; $rv .= sprintf "\n", $text{'backup_path'}, $path; $rv .= "\n"; $rv .= sprintf "\n", $text{'backup_login'}, $user; $rv .= sprintf "\n", $text{'backup_pass'}, $pass; # SCP file fields # XXX $rv .= "
%s %s
%s %s
%s %s
\n"; return $rv; } # parse_backup_destination(name, &in) # Returns a backup destination string, or calls error sub parse_backup_destination { local %in = %{$_[1]}; if ($in{"$_[0]_mode"} == 0) { $in{"$_[0]_file"} =~ /^\/\S/ || &error($text{'backup_edest'}); return $in{"$_[0]_file"}; } elsif ($in{"$_[0]_mode"} == 1) { gethostbyname($in{"$_[0]_server"}) || &error($text{'backup_eserver'}); $in{"$_[0]_path"} =~ /^\/\S/ || &error($text{'backup_epath'}); $in{"$_[0]_user"} =~ /^[^:\@\/]*$/ || &error($text{'backup_euser'}); $in{"$_[0]_pass"} =~ /^[^:\@\/]*$/ || &error($text{'backup_epass'}); return "ftp://".$in{"$_[0]_user"}.":".$in{"$_[0]_pass"}."\@". $in{"$_[0]_server"}.$in{"$_[0]_path"}; } } # ftp_upload(host, file, srcfile, [&error], [&callback], [user, pass]) # Download data from a local file to an FTP site sub ftp_upload { local($buf, @n); local $cbfunc = $_[4]; $download_timed_out = undef; local $SIG{ALRM} = "download_timeout"; alarm(60); # connect to host and login &open_socket($_[0], 21, "SOCK", $_[3]) || return 0; alarm(0); if ($download_timed_out) { if ($_[3]) { ${$_[3]} = $download_timed_out; return 0; } else { &error($download_timed_out); } } &ftp_command("", 2, $_[3]) || return 0; if ($_[5]) { # Login as supplied user local @urv = &ftp_command("USER $_[5]", [ 2, 3 ], $_[3]); @urv || return 0; if (int($urv[1]/100) == 3) { &ftp_command("PASS $_[6]", 2, $_[3]) || return 0; } } else { # Login as anonymous local @urv = &ftp_command("USER anonymous", [ 2, 3 ], $_[3]); @urv || return 0; if (int($urv[1]/100) == 3) { &ftp_command("PASS root\@".&get_system_hostname(), 2, $_[3]) || return 0; } } &$cbfunc(1, 0) if ($cbfunc); &ftp_command("TYPE I", 2, $_[3]) || return 0; # get the file size and tell the callback local @st = stat($_[2]); if ($cbfunc) { &$cbfunc(2, $st[7]); } # send the file local $pasv = &ftp_command("PASV", 2, $_[3]); defined($pasv) || return 0; $pasv =~ /\(([0-9,]+)\)/; @n = split(/,/ , $1); &open_socket("$n[0].$n[1].$n[2].$n[3]", $n[4]*256 + $n[5], "CON", $_[3]) || return 0; &ftp_command("STOR $_[1]", 1, $_[3]) || return 0; # transfer data local $got; open(PFILE, $_[2]); while(read(PFILE, $buf, 1024) > 0) { print CON $buf; $got += length($buf); &$cbfunc(3, $got) if ($cbfunc); } close(PFILE); close(CON); if ($got != $st[7]) { if ($_[3]) { ${$_[3]} = "Upload incomplete"; return 0; } else { &error("Upload incomplete"); } } &$cbfunc(4) if ($cbfunc); # finish off.. &ftp_command("", 2, $_[3]) || return 0; &ftp_command("QUIT", 2, $_[3]) || return 0; close(SOCK); return 1; } # ftp_onecommand(host, command, [&error], [user, pass]) # Executes one command on an FTP server, after logging in, and returns its # exit status. sub ftp_onecommand { local($buf, @n); $download_timed_out = undef; local $SIG{ALRM} = "download_timeout"; alarm(60); # connect to host and login &open_socket($_[0], 21, "SOCK", $_[2]) || return 0; alarm(0); if ($download_timed_out) { if ($_[2]) { ${$_[2]} = $download_timed_out; return 0; } else { &error($download_timed_out); } } &ftp_command("", 2, $_[2]) || return 0; if ($_[3]) { # Login as supplied user local @urv = &ftp_command("USER $_[3]", [ 2, 3 ], $_[2]); @urv || return 0; if (int($urv[1]/100) == 3) { &ftp_command("PASS $_[4]", 2, $_[2]) || return 0; } } else { # Login as anonymous local @urv = &ftp_command("USER anonymous", [ 2, 3 ], $_[2]); @urv || return 0; if (int($urv[1]/100) == 3) { &ftp_command("PASS root\@".&get_system_hostname(), 2, $_[2]) || return 0; } } # make the directory local @rv = &ftp_command($_[1], 2, $_[2]); @rv || return 0; # finish off.. &ftp_command("QUIT", 2, $_[3]) || return 0; close(SOCK); return $rv[1]; } # ftp_listdir(host, dir, [&error], [user, pass]) # Returns a reference to a list of filenames in a directory sub ftp_listdir { local($buf, @n); $download_timed_out = undef; local $SIG{ALRM} = "download_timeout"; alarm(60); # connect to host and login &open_socket($_[0], 21, "SOCK", $_[2]) || return 0; alarm(0); if ($download_timed_out) { if ($_[2]) { ${$_[2]} = $download_timed_out; return 0; } else { &error($download_timed_out); } } &ftp_command("", 2, $_[2]) || return 0; if ($_[3]) { # Login as supplied user local @urv = &ftp_command("USER $_[3]", [ 2, 3 ], $_[2]); @urv || return 0; if (int($urv[1]/100) == 3) { &ftp_command("PASS $_[4]", 2, $_[2]) || return 0; } } else { # Login as anonymous local @urv = &ftp_command("USER anonymous", [ 2, 3 ], $_[2]); @urv || return 0; if (int($urv[1]/100) == 3) { &ftp_command("PASS root\@".&get_system_hostname(), 2, $_[2]) || return 0; } } # request the listing local $pasv = &ftp_command("PASV", 2, $_[2]); defined($pasv) || return 0; $pasv =~ /\(([0-9,]+)\)/; @n = split(/,/ , $1); &open_socket("$n[0].$n[1].$n[2].$n[3]", $n[4]*256 + $n[5], "CON", $_[2]) || return 0; &ftp_command("NLST $_[1]", 1, $_[2]) || return 0; # transfer listing local @list; while() { s/\r|\n//g; push(@list, $_); } close(CON); # finish off.. &ftp_command("", 2, $_[3]) || return 0; &ftp_command("QUIT", 2, $_[3]) || return 0; close(SOCK); return \@list; } 1; virtual-server/module.info0100664000567100000120000000033010042202051015653 0ustar jcameronwheelname=Virtualmin desc=Virtualmin Virtual Servers category=servers depends=net useradmin quota acl cron mailboxes 1.140 os_support=*-linux macos freebsd openbsd solaris version=1.91 desc_de=Virtualmin Virtuelle Server virtual-server/domain_setup.cgi0100775000567100000120000001327710025225460016717 0ustar jcameronwheel#!/usr/local/bin/perl # domain_setup.cgi # Create a new virtual domain require './virtual-server-lib.pl'; $access{'create'} || &error($text{'form_ecannot'}); &require_bind() if ($config{'dns'}); &require_useradmin(); &require_mail() if ($config{'mail'}); &require_mysql() if ($config{'mysql'}); &require_postgres() if ($config{'postgres'}); &require_acl(); &ReadParse(); &error_setup($text{'setup_err'}); # Validate inputs (check domain name to see if in use) $in{'dom'} =~ /^[A-Za-z0-9\.\-]+$/ || &error($text{'setup_edomain'}); $in{'dom'} = lc($in{'dom'}); foreach $d (&list_domains()) { &error($text{'setup_edomain2'}) if (lc($d->{'dom'}) eq lc($in{'dom'})); } $in{'email_def'} || $in{'email'} =~ /\S/ || &error($text{'setup_eemail'}); $in{'pass'} =~ /\S/ || &error($text{'setup_epass'}); if ($in{'user_def'}) { $in{'dom'} =~ /^([^\.]+)/; $try1 = $user = $1; if (defined(getpwnam($1)) || $config{'longname'}) { $user = $in{'dom'}; $try2 = $user; if (defined(getpwnam($user))) { &error(&text('setup_eauto', $try1, $try2)); } } } else { $in{'user'} = lc($in{'user'}); $user = $in{'user'}; $user =~ /^[^\t :]+$/ || &error($text{'setup_euser2'}); defined(getpwnam($user)) && &error($text{'setup_euser'}); } if ($in{'mgroup_def'}) { $group = $user; } else { $in{'mgroup'} = lc($in{'mgroup'}); $group = $in{'mgroup'}; $group =~ /^[^\t :]+$/ || &error($text{'setup_egroup2'}); } if (!$in{'group_def'}) { $in{'group'} = lc($in{'group'}); $in{'group'} eq $group && &error(&text('setup_egroup3', $group)); } $home_base || &error($text{'setup_ehomebase'}); if (defined(&useradmin::check_username_restrictions)) { $uerr = &useradmin::check_username_restrictions($user); if ($uerr) { &error(&text('setup_eusername', $user, $uerr)); } } $user =~ /^[a-zA-z]/ || &error(&text('setup_eusername2', $user)); if ($config{'home_quotas'}) { if ($in{'quota'} == -1) { $in{'quota'} = $in{'otherquota'} }; if ($in{'uquota'} == -1) { $in{'uquota'} = $in{'otheruquota'} }; $in{'quota'} =~ /^\d+$/ || &error($text{'setup_equota'}); $in{'uquota'} =~ /^\d+$/ || &error($text{'setup_euquota'}); } ($db = $group) =~ s/[\.\-]/_/g; $in{'mailbox'} && !$in{'mail'} && &error($text{'setup_emailbox'}); if ($config{'proxy_pass'} && $in{'web'} && !$in{'proxy_def'}) { ($proxy = $in{'proxy'}) =~ /^(http|https):\/\/\S+$/ || &error($text{'setup_eproxy'}); } $in{'mailboxlimit_def'} || $in{'mailboxlimit'} =~ /^[1-9]\d*$/ || &error($text{'setup_emailboxlimit'}); $in{'unix'} = 1; # always on # Check for various clashes my $f; foreach $f (@features) { if ($in{$f}) { local $cfunc = "check_${f}_clash"; if (&$cfunc($in{'dom'}, $db, $user, $group)) { &error(&text('setup_e'.$f, $in{'dom'}, $db, $user, $group)); } } } # Check for feature dependencies foreach $f (@features) { if ($in{$f}) { local $fd; foreach $fd (@{$feature_depends{$f}}) { &error(&text('setup_edep'.$f)) if (!$in{$fd}); } } } $defip = &get_default_ip(); if ($config{'all_namevirtual'}) { # Make sure the IP *is* assigned &check_ipaddress($in{'ip'}) || &error($text{'setup_eip'}); if (!&check_virt_clash($in{'ip'})) { &error(&text('setup_evirtclash2')); } } elsif ($in{'virt'}) { # Make sure the IP isn't assigned yet &check_ipaddress($in{'ip'}) || &error($text{'setup_eip'}); if (&check_virt_clash($in{'ip'})) { &error(&text('setup_evirtclash')); } } $| = 1; $theme_no_table++; &header($text{'setup_title'}, ""); print "
\n"; # Work out user and group IDs &build_group_taken(\%gtaken, \%ggtaken); $gid = &allocate_gid(\%gtaken); $ugid = $in{'group_def'} ? $gid : getgrnam($in{'group'}); $ugroup = $in{'group_def'} ? $group : $in{'group'}; &build_taken(\%taken, \%utaken); $uid = &allocate_uid(\%taken); # Build up domain object %dom = ( 'id', &domain_id(), 'dom', $in{'dom'}, 'user', $user, 'group', $group, 'ugroup', $ugroup, 'quota', "a_parse('quota', $config{'home_quotas'}), 'uquota', "a_parse('uquota', $config{'home_quotas'}), 'uid', $uid, 'gid', $gid, 'ugid', $ugid, 'owner', $in{'owner'}, 'email', !$in{'email_def'} ? $in{'email'} : $in{'mailbox'} ? $user."\@".$in{'dom'} : undef, 'name', $config{'all_namevirtual'} ? 1 : $in{'virt'} ? 0 : 1, 'ip', $config{'all_namevirtual'} ? $in{'ip'} : $in{'virt'} ? $in{'ip'} : $defip, 'virt', $config{'all_namevirtual'} ? 0 : $in{'virt'}, 'pass', $in{'pass'}, 'db', $db, 'source', 'domain_setup.cgi', 'proxy_pass', $proxy, 'mailboxlimit', $in{'mailboxlimit_def'} ? undef : $in{'mailboxlimit'} ); my $f; foreach $f (@features) { $dom{$f} = $in{$f}; } $dom{'home'} = &server_home_directory(\%dom); # Run the before command &set_domain_envs(\%dom, "CREATE_DOMAIN"); $merr = &making_changes(); &error(&text('setup_emaking', "$merr")) if (defined($merr)); # Set up all the selected features foreach $f (@features) { if ($dom{$f}) { local $sfunc = "setup_$f"; &$sfunc(\%dom); } } # Add virtual IP address, if needed if ($in{'virt'}) { &setup_virt(\%dom); } # Add a virtuser for the unix user, if requested if ($in{'mailbox'}) { print $text{'setup_mailbox'},"
\n"; local $virt = { 'from' => $user."\@".$in{'dom'}, 'to' => [ $user ] }; &create_virtuser($virt); print $text{'setup_done'},"

\n"; } # Save domain details print $text{'setup_save'},"
\n"; &save_domain(\%dom); print $text{'setup_done'},"

\n"; # Notify the owner via email &send_domain_email(\%dom); # Add to this user's list of domains if needed if (!&can_edit_domain(\%dom)) { $access{'domains'} = join(" ", split(/\s+/, $access{'domains'}), $dom{'id'}); &save_module_acl(\%access); } # Run the after creation command &made_changes(); &webmin_log("create", "domain", $dom{'dom'}, \%dom); print "


\n"; &footer("", $text{'index_return'}); virtual-server/domain_form.cgi0100775000567100000120000001253510025225430016513 0ustar jcameronwheel#!/usr/local/bin/perl # domain_form.cgi # Display a form for setting up a new virtual domain require './virtual-server-lib.pl'; $access{'create'} || &error($text{'form_ecannot'}); &header($text{'form_title'}, ""); print "
\n"; print <
$text{'form_header'}
EOF print ""; print "\n"; print ""; print "\n"; print ""; print "\n"; print ""; print "\n"; print ""; print "\n"; print ""; print "\n"; print ""; print "\n"; if ($config{'home_quotas'}) { print "\n"; @defquota = split (/ /,$config{'defquota'}); if ( !@defquota or $#defquota eq 0 ) { print "\n"; } else { print "\n"; } print "\n"; print "\n"; @defuquota = split (/ /,$config{'defuquota'}); if ( !@defuquota or $#defuquota eq 0 ) { print "\n"; } else { print "\n"; } print "\n"; } print "\n"; print "\n"; print "\n"; print "\n"; $i = 0; foreach $f (@opt_features) { print "\n" if ($i%2 == 0); print ""; if ($config{$f} || !defined($config{$f})) { print "\n"; } else { print "\n"; } print "\n" if ($i++%2 == 1); } if ($config{'proxy_pass'}) { print "\n"; print "\n"; } $defip = &get_default_ip(); print "\n"; if ($config{'all_namevirtual'}) { print "\n"; } else { print "\n"; } print "
", &hlink($text{'form_domain'}, "domainname"), "
", &hlink($text{'form_owner'}, "ownersname"), "
", &hlink($text{'form_email'}, "ownersemail"), " ", $text{'form_email_def'}; print " $text{'form_email_set'}\n"; print "
", &hlink($text{'form_user'}, "unixusername"), " ", "$text{'form_auto'}"; print " $text{'form_nwuser'} "; print "
", &hlink($text{'form_pass'}, "password"), "
",&hlink($text{'form_mgroup'}, "mailgroupname")," ", "$text{'form_auto'}"; print " $text{'form_nwgroup'} ", "
",&hlink($text{'form_group'}, "unixgroupname")," ", "$text{'form_crgroup'}"; print " $text{'form_exgroup'}"; print &unix_group_input("group"),"
", &hlink($text{'form_quota'}, "websitequota"), "","a_input("quota", $config{'defquota'}, $config{'home_quotas'}),"\n"; print "a_input("otherquota", "", $config{'home_quotas'}),"
", &hlink($text{'form_uquota'}, "unixuserquota"), "","a_input("uquota", $config{'defuquota'}, $config{'home_quotas'}),"\n"; print "a_input("otheruquota", "", $config{'home_quotas'}),"
",&hlink($text{'form_mailboxlimit'}, "mailboxlimit")," \n"; printf " %s\n", $config{'defmailboxlimit'} ? "" : "checked", $text{'form_unlimit'}; printf " %s\n", $config{'defmailboxlimit'} ? "checked" : "", $text{'form_atmost'}; print "
",&hlink($text{'form_mailbox'},"usermailbox")," $text{'yes'}\n"; print " $text{'no'}

",&hlink($text{'form_'.$f}, $f),"\n"; print " $text{'yes'}"; print " $text{'no'}$text{'form_unavail'}
",&hlink($text{'form_proxy'}, "proxypass"),""; print " ", "$text{'form_plocal'}\n"; print " ", "$text{'form_purl'}\n"; print "
",&hlink($text{'form_iface'},"iface"),"
\n"; print " ", &text('form_shared', $defip),"\n"; print " $text{'form_vip'}\n"; print "
\n"; print "\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/list_users.cgi0100775000567100000120000000232210007630566016420 0ustar jcameronwheel#!/usr/local/bin/perl # list_users.cgi # List mailbox users in some domain require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'users_ecannot'}); @users = &list_domain_users($d); &header($text{'users_title'}, ""); &domain_title($d); print "
\n"; local $mailboxesavail; local $show_users_add; $mailboxesavail = ($d->{'mailboxlimit'} - scalar(@users) >= 0) ? $d->{'mailboxlimit'} - scalar(@users) : '0'; $show_users_add = 1; if (@users) { if ($d->{'mailboxlimit'}) { $show_users_add = ($mailboxesavail > 0); print "

",&text( $show_users_add ? 'users_limit' : 'users_nomore', $d->{'mailboxlimit'}, $mailboxesavail),"

\n"; } if ($show_users_add) { print "", "$text{'users_add'}
\n"; } &users_table(\@users, $d); } else { print "$text{'users_none'}

\n"; } if ($show_users_add) { print "", "$text{'users_add'}

\n"; } print "


\n"; if ($single_domain_mode) { &footer("", $text{'index_return2'}); } else { &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); } virtual-server/config.info0100664000567100000120000001055010034725205015654 0ustar jcameronwheelline1=Server settings,11 dns=BIND setup and configuration enabled?,1,1-Yes,0-No mail=Mailbox and alias configuration enabled?,1,1-Yes,0-No web=Apache setup and configuration enabled?,1,1-Yes,0-No webalizer=Webalizer report generation enabled?,1,1-Yes,0-No ssl=SSL website setup enabled?,1,1-Yes,0-No mysql=MySQL setup and configuration enabled?,1,1-Yes,0-No postgres=PostgreSQL setup and configuration enabled?,1,1-Yes,0-No mail_system=Mail server to configure,1,1-Sendmail,0-Postfix,3-Detect automatically generics=Also update outgoing addresses for mailboxes?,1,1-Yes,0-No quotas=Quota setup for domain and mail users?,1,1-Yes (if enabled),0-No hard_quotas=Quota type to set,1,1-Hard (enforced),0-Soft (advisory only) iface=Network interface for virtual addresses,3,Detect automatically defip=Default virtual server IP address,3,From network interface display_max=Maximum number of domains to display,3,Unlimited disable=Features to deactivate when disabling,13,unix-Unix user (lock account),mail-Mail (stop accepting email for domain),web-Website (replace site with error page),dns-DNS (stop serving domain),mysql-MySQL (disallow login by MySQL user),postgres-PostgreSQL (disallow login by PostgreSQL user) delete_indom=Delete all Apache virtual hosts in domain when deleting?,1,1-Yes,0-No all_namevirtual=All Apache virtual servers are name-based?,1,1-Yes,0-No show_features=Show server features on main page?,1,1-Yes,0-No line1.5=Domain owner permissions,11 edit_afiles=Can edit alias include and reply files?,1,1-Yes,0-No edit_homes=Can select home directories for users?,1,1-Yes,0-No edit_ftp=Can create FTP users?,1,1-Yes,0-No edit_quota=Can set mailbox quotas?,1,1-Yes,0-No alias_types=Allowed alias types,13,1-Address,2-Addresses in file,3-File,4-Program,5-Autoreply,6-Filter,7-User mailbox post_check=Update all Webmin users after configuration changes?,1,1-Yes,0-No leave_acl=Always re-update Webmin module ACLs?,1,0-Yes,1-No line2=Defaults for new domains,11 home_base=Home directory base,3,From Users and Groups module home_format=Home subdirectory,10,-Automatic,From template (can use $USER and $DOM) shell=Shell for mailbox users,0 ftp_shell=Shell for FTP users,0 unix_shell=Shell for domain users,0 append=Include domain name in usernames?,1,1-Always,0-Only to avoid a clash append_style=Format for usernames that include domain,4,0-username.domain,2-domain.username,1-username-domain,3-domain-username,4-username_domain,5-domain_username longname=Domain name style in usernames,1,1-Full domain name,0-First part of domain localgroup=Primary group for local users,3,Don't display local users defquota=Default quota for new servers,0,8,,blocks defuquota=Default quota for new server Unix users,0,8,,blocks defmquota=Default quota for new mailboxes,0,8,,blocks defmailboxlimit=Default limit on number of mailboxes,0,4,,mailboxes virtual_skel=Initial files directory for virtual server users,3,None mail_skel=Initial files directory for mail users,3,None mysql_hosts=Allowed hosts for MySQL users,3,Just localhost webmin_theme=Theme for new Webmin users,10,*-Global default,-Old Webmin theme,Theme in directory proxy_pass=Allow create of proxy-only websites?,1,1-Yes,0-No line4=Actions upon domain and user creation,11 from_addr=From: address for email sent when a domain is created,3,Default (root@thishost) domain_template=Template file for email to new domain owners,10,none-None,default-Default user_template=Template file for email to new mailboxes,10,none-None,default-Default local_template=Template file for email to new local users,10,none-None,default-Default pre_command=Command to run before making changes to a domain,0 post_command=Command to run after making changes to a domain,0 line3=Extra modules available to domain owners,11 avail_file=File Manager (home directory only),1,1-Yes,0-No avail_passwd=Change Password,1,2-User and mailbox passwords,1-User password,0-No avail_proc=Running Processes (user's processes only),1,1-Yes,0-No avail_cron=Scheduled Cron Jobs (user's Cron jobs),1,1-Yes,0-No avail_at=Scheduled Commands (user's commands),1,1-Yes,0-No avail_telnet=SSH/Telnet Login,1,1-Yes,0-No avail_updown=Upload and Download (as user),1,1-Yes,0-No avail_change-user=Change Language and Theme,1,1-Yes,0-No avail_htaccess-htpasswd=Protected Web Directories (under home directory),1,1-Yes,0-No avail_mailboxes=Read User Mail (users' mailboxes),1,1-Yes,0-No avail_custom=Custom Commands,1,1-Yes,0-No virtual-server/edit_user.cgi0100775000567100000120000001626210015302372016205 0ustar jcameronwheel#!/usr/local/bin/perl # edit_user.cgi # Display a form for editing or adding a user. This can be a local user, # or a domain mailbox user require './virtual-server-lib.pl'; &ReadParse(); if ($in{'dom'}) { $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'users_ecannot'}); } else { $access{'local'} || &error($text{'users_ecannot2'}); } if ($in{'new'}) { &header($text{'user_create'}, ""); } else { &header($text{'user_edit'}, ""); @users = &list_domain_users($d); ($user) = grep { $_->{'user'} eq $in{'user'} } @users; $mailbox = $d && $d->{'user'} eq $user->{'user'}; } &domain_title($d) if ($d); print "
\n"; print &check_clicks_function(); print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
",$mailbox ? $text{'user_mheader'} : $d ? $text{'user_header'} : $text{'user_lheader'}, "
\n"; print "\n"; if ($mailbox) { print "\n"; $pop3 = $user->{'user'}; } else { $pop3 = $d ? &remove_userdom($user->{'user'}, $d) : $user->{'user'}; print "\n"; print "\n"; } print "\n"; if ($mailbox) { print "\n"; } else { print "\n"; } if (!$mailbox) { print "\n"; if ($in{'new'}) { print "\n"; } else { print "\n"; } } if (($master_admin || $config{'edit_homes'}) && $d && $d->{'home'} && !$mailbox) { # Show home directory editing field local $auto = $in{'new'} || $user->{'home'} eq "$d->{'home'}/homes/$pop3"; print "\n"; printf "\n", $auto ? "" : substr($user->{'home'}, length($d->{'home'})+1); } if (($master_admin || $config{'edit_ftp'}) && !$mailbox) { # Show FTP shell field print "\n"; $ftp = $user->{'shell'} eq $config{'ftp_shell'} ? 1 : $in{'new'} || $user->{'shell'} eq $config{'shell'} ? 0 : -1; if ($ftp < 0) { print "\n"; } else { printf "\n", $ftp ? "" : "checked", $text{'no'}; } print "\n"; } print "\n"; if ($d) { # Show primary email address field print "\n"; printf "\n", $user->{'email'} || $in{'new'} ? "" : "checked", $text{'no'}; } if (!$mailbox) { # Show quotas field(s) $qsame = $config{'home_quotas'} eq $config{'mail_quotas'}; if ($config{'home_quotas'}) { print "\n"; "a_field("quota", $user->{'quota'}, $user->{'uquota'}, $config{'home_quotas'}); } if ($config{'mail_quotas'} && !$qsame) { print "\n"; "a_field("mquota", $user->{'mquota'}, $user->{'umquota'}, $config{'mail_quotas'}); } } if (!$in{'new'}) { local ($sz, $umf) = &mail_file_size($user); print "\n"; local $link = &read_mail_link($user); print "\n"; } print "\n"; } print "\n"; print "\n"; # Show forwarding setup for this user print "\n"; &alias_form($user->{'to'}, &hlink("$text{'user_aliases'}", "userdest"), $d, "user", $in{'user'}); print "
",&hlink($text{'user_user'}, "username"),"$user->{'user'}
", $d ? "\@$d->{'dom'}\n" : "\n"; if ($pop3 ne $user->{'user'}) { print " ",&text('user_pop3', "$user->{'user'}"); } print "
",&hlink($text{'user_real'}, "realname"),"$user->{'real'}
",&hlink($text{'user_pass'}, "password"),"
", "$text{'user_passdef'}\n"; print " $text{'user_passset'}\n"; print "
", &hlink($text{'user_home'}, "userhome"), " %s\n", $auto ? "checked" : "", $text{'user_home1'}; printf " %s\n", $auto ? "" : "checked", &text('user_home0', "$d->{'home'}/"); printf "
", &hlink($text{'user_ftp'}, "ftp"), "",&text('user_shell', "$user->{'shell'}")," %s\n", $ftp ? "checked" : "", $text{'yes'}; printf " %s

", &hlink($text{'user_mailbox'}, "mailbox"), " %s\n", $user->{'email'} || $in{'new'} ? "checked" : "", $text{'yes'}; printf " %s
", &hlink($qsame ? $text{'user_umquota'} : $text{'user_uquota'}, "diskquota"), "
", &hlink($text{'user_mquota'}, "diskmquota"), "
", &hlink("$text{'user_mail'}", "mailfile"),"$umf\n"; if ($link) { print "$text{'user_read'}
", &hlink("$text{'user_extra'}", "extraemail"),"

\n"; print "\n"; if ($in{'new'}) { print "\n"; } else { print "\n"; print "\n" if (!$mailbox); } print "
\n"; print "
\n"; if ($d) { if ($single_domain_mode) { &footer("list_users.cgi?dom=$in{'dom'}", $text{'users_return'}, "", $text{'index_return2'}); } else { &footer("list_users.cgi?dom=$in{'dom'}", $text{'users_return'}, "edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); } } else { &footer("", $text{'index_return'}); } # quota_field(name, value, used, filesystem) sub quota_field { local @defmquota = split (/ /,$config{'defmquota'}); if ($master_admin || $config{'edit_quota'}) { # Show inputs for editing quotas printf " %s\n", $_[0], $_[1] || $in{'new'} ? "" : "checked", $text{'form_unlimit'}; printf "\n", $_[0], $_[1] || $in{'new'} ? "checked" : ""; if (!$in{'new'}) { print "a_input($_[0], $_[1] || "", $_[3]),"\n"; print &text('user_used', "a_show($_[2], $_[3])),"\n"; } else { if ( !@defmquota or $#defmquota eq 0 ) { print "a_input($_[0], $config{'defmquota'} || "", $_[3]),"\n"; } else { print "\n"; print " $text{'form_b'}\n"; } } print " \n"; } else { # Just show current settings, or default print ""; local $q = $in{'new'} ? $defmquota[0] : $_[1]; print ($q ? "a_show($q, $_[3]) : $text{'form_unlimit'}),"\n"; print &text('user_used', "a_show($_[2], $_[3])) if (!$in{'new'}); print " \n"; } } virtual-server/save_user.cgi0100775000567100000120000002101010020545410016177 0ustar jcameronwheel#!/usr/local/bin/perl # save_user.cgi # Create, update or delete a user require './virtual-server-lib.pl'; &ReadParse(); if ($in{'dom'}) { $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'users_ecannot'}); } else { $access{'local'} || &error($text{'users_ecannot2'}); } @users = &list_domain_users($d); if (!$in{'new'}) { # Lookup user details ($user) = grep { $_->{'user'} eq $in{'old'} } @users; $user || &error("User does not exist!"); %old = %$user; $mailbox = $d && $d->{'user'} eq $user->{'user'}; } &error_setup($text{'user_err'}); &build_taken(\%taken, \%utaken); if ($in{'delete'}) { if ($in{'confirm'}) { # Get rid of his mail file $mailbox && &error($text{'user_edelete'}); &delete_mail_file($user); # Delete the user, his virtusers and aliases &delete_user($user, $d); # Delete home dir &system_logged("rm -rf '$user->{'home'}'") if (-d $user->{'home'} && $user->{'home'} ne "/"); $user->{'dom'} = $d->{'dom'}; &webmin_log("delete", "user", &remove_userdom($user->{'user'}, $d), $user); } else { # Confirm deletion first &header($text{'user_delete'}, ""); &domain_title($d) if ($d); print "
\n"; print &check_clicks_function(); print "
\n"; print "\n"; print "\n"; print "\n"; local ($mailsz) = &mail_file_size($user); local ($homesz) = &disk_usage_kb($user->{'home'}); print "

",&text('user_rusure', "$in{'old'}", &nice_size($mailsz), &nice_size($homesz*1024), "$user->{'home'}"),"

\n"; print "

\n"; print "
\n"; print "
\n"; if ($d) { &footer("list_users.cgi?dom=$in{'dom'}", $text{'users_return'}); } else { &footer("", $text{'index_return'}); } exit; } } else { # Verify inputs if ($in{'new'} && $d && $d->{'mailboxlimit'}) { if (@users >= $d->{'mailboxlimit'}) { &error($text{'user_emailboxlimit'}); } } if (!$mailbox) { $in{'user'} = lc($in{'user'}); $in{'user'} =~ /^[^ \t:]+$/ || &error($text{'user_euser'}); $in{'real'} =~ /^[^:]*$/ || &error($text{'user_ereal'}); $user->{'real'} = $in{'real'}; if ($in{'pass_def'}) { $user->{'passmode'} = 4; } else { $user->{'pass'} = &useradmin::encrypt_password($in{'pass'}); $user->{'plainpass'} = $in{'pass'}; $user->{'passmode'} = 3; &set_pass_change($user); } $qsame = $config{'mail_quotas'} eq $config{'home_quotas'}; $qedit = $master_admin || $config{'edit_quota'}; if ($config{'home_quotas'} && $qedit) { if ( $in{'quota'} eq -1 ) { $in{'quota'} = $in{'otherquota'}; } $in{'quota_def'} || $in{'quota'} =~ /^\d+$/ || &error($text{'user_equota'}); } if ($config{'mail_quotas'} && !$qsame && $qedit) { if ( $in{'mquota'} eq -1 ) { $in{'mquota'} = $in{'othermquota'}; } $in{'mquota_def'} || $in{'mquota'} =~ /^\d+$/ || &error($text{'user_equota'}); } } @extra = split(/\s+/, $in{'extra'}); foreach $e (@extra) { $e = lc($e); if ($d && $e =~ /^([^\@ \t]+$)$/) { $e = "$e\@$d->{'dom'}"; } if ($e !~ /^(\S+)\@(\S+)$/) { &error(&text('user_eextra1', $e)); } local ($eu, $ed) = ($1, $2); local $edom = &get_domain_by("dom", $ed); $edom && $edom->{'mail'} || &error(&text('user_eextra2', $ed)); &can_edit_domain($edom) || &error(&text('user_eextra3', $ed)); } @values = &parse_alias(); $user->{'to'} = @values ? \@values : undef; $eu = $mailbox ? $d->{'user'} : $in{'user'}; if ($d) { $user->{'email'} = $in{'mailbox'} ? $eu."\@".$d->{'dom'} : undef; } $user->{'extraemail'} = \@extra; if (!$mailbox) { # Find home if (($master_admin || $config{'edit_homes'}) && $d && $d->{'home'} && !$in{'home_def'}) { $in{'home'} =~ /^\S+$/ && $in{'home'} !~ /\.\./ || &error($text{'user_ehome'}); # Custom home directory for mailbox user $home = "$d->{'home'}/$in{'home'}"; } elsif ($d) { # Auto home directory for mailbox user $home = "$d->{'home'}/homes/$in{'user'}"; } else { # Auto home directory for local user $home = &useradmin::auto_home_dir( $home_base, $in{'user'}, $config{'localgroup'}); } } # Create or update the user if ($in{'new'}) { # Set new user parameters $user->{'uid'} = &allocate_uid(\%taken); $user->{'gid'} = $d ? $d->{'gid'} : getgrnam($config{'localgroup'}); if ($master_admin || $config{'edit_ftp'}) { # Shell can be set based on FTP flag $user->{'shell'} = $in{'ftp'} ? $config{'ftp_shell'} : $config{'shell'}; } elsif ($in{'new'}) { # For new users, shell is always non-FTP $user->{'shell'} = $config{'shell'}; } $user->{'home'} = $home; if ($utaken{$in{'user'}} || ($d && $config{'append'})) { # Need to append domain name if ($d) { # Add group name $user->{'user'} = &userdom_name($in{'user'},$d); } else { # No domain to add, so give up! &error($text{'user_eclash2'}); } } else { $user->{'user'} = $in{'user'}; } $user->{'passmode'} = 3; $user->{'plainpass'} = $in{'pass'}; if ($d) { # Check for a clash in this domain if ($utaken{$user->{'user'}} || &check_clash($in{'user'}, $d->{'dom'})) { &error($text{'user_eclash'}); } } # Check if any extras clash foreach $e (@extra) { $e =~ /^(\S+)\@(\S+)$/; if (&check_clash($1, $2)) { &error(&text('user_eextra4', $e)); } } # Check if the name is too long if ($lerr = &too_long($user->{'user'})) { &error($lerr); } # Check if home directory already exists if (-e $home) { &error(&text('user_emkhome', $home)); } # Create the user and virtusers and alias &create_user($user, $d); # Create his homedir &system_logged("mkdir -p '$home'"); &system_logged("chown $user->{'uid'}:$user->{'gid'} '$home'"); &system_logged("chmod 755 '$home'"); # Copy files into homedir ©_skel_files($config{'mail_skel'}, $user); # Send an email upon creation @erv = &send_user_email($d, $user); } else { # Check if any extras clash %oldextra = map { $_, 1 } @{$old{'extraemail'}}; foreach $e (@extra) { $e =~ /^(\S+)\@(\S+)$/; if (!$oldextra{$e} && &check_clash($1, $2)) { &error(&text('user_eextra4', $e)); } } # For any user except the domain owner, update his home and shel if (!$mailbox) { # Check if new homedir exists if (-e $home && $user->{'home'} ne $home) { &error(&text('user_emkhome', $home)); } # Update user parameters (handle rename and .group) if ($in{'user'} ne $in{'oldpop3'}) { # Has been renamed .. check for a username clash if ($d && ($utaken{$in{'user'}} || $config{'append'})) { # New name has to include group $user->{'user'} = &userdom_name($in{'user'}, $d); } else { # Can rename without the dot $user->{'user'} = $in{'user'}; } # Check if the name is too long if ($lerr = &too_long($user->{'user'})) { &error($lerr); } # Check for a virtuser clash too if ($d && &check_clash($in{'user'}, $d->{'dom'})) { &error($text{'user_eclash'}); } # Rename his mail file &rename_mail_file($user, $in{'old'}); } # Rename homedir if ($user->{'home'} ne $home && -d $user->{'home'}) { &system_logged("mv '$user->{'home'}' '$home'"); $user->{'home'} = $home; } # Update shell if (defined($in{'ftp'})) { $user->{'shell'} = $in{'ftp'} ? $config{'ftp_shell'} : $config{'shell'}; } } # Update the user and any virtusers and aliases &modify_user($user, \%old, $d); } if (!$mailbox && ($qedit || $in{'new'})) { # Actually update quotas, if allowed @defmquota = split (/ /,$config{'defmquota'}); if ($config{'home_quotas'}) { # Set his home directory quota &set_quota($user->{'user'}, $config{'home_quotas'}, !$qedit ? $defmquota[0] : $in{'quota_def'} ? 0 : "a_parse('quota', $config{'home_quotas'})); } if ($config{'mail_quotas'} && !$qsame) { # Set his home directory quota &set_quota($user->{'user'}, $config{'mail_quotas'}, !$qedit ? $defmquota[0] : $in{'mquota_def'} ? 0 : "a_parse('mquota', $config{'mail_quotas'})); } } $user->{'dom'} = $d->{'dom'}; &webmin_log($in{'new'} ? "create" : "modify", "user", &remove_userdom($user->{'user'}, $d), $user); } &redirect($d ? "list_users.cgi?dom=$in{'dom'}" : "index.cgi"); virtual-server/list_aliases.cgi0100775000567100000120000000312210007630566016677 0ustar jcameronwheel#!/usr/local/bin/perl # list_aliases.cgi # Display users and aliases in a domain require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); @aliases = &list_domain_aliases($d); &header($text{'aliases_title'}, ""); &domain_title($d); print "
\n"; if (@aliases) { print "", "$text{'aliases_add'}
\n"; print "\n"; print " ", " ", "\n"; foreach $a (@aliases) { $name = $a->{'from'}; $name =~ s/\@\S+$//; $name = "$text{'alias_catchall'}" if ($name eq ""); print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } print "
$text{'aliases_name'}$text{'aliases_domain'}$text{'aliases_dests'}
{'from'}'>$name",$d->{'dom'},"\n"; foreach $v (@{$a->{'to'}}) { ($anum, $astr) = &alias_type($v); print &text("aliases_type$anum", "".&html_escape($astr).""),"
\n"; } if (!@{$a->{'to'}}) { print "$text{'aliases_dnone'}\n"; } print "
\n"; } else { print "$text{'aliases_none'}

\n"; } print "", "$text{'aliases_add'}

\n"; print "


\n"; if ($single_domain_mode) { &footer("", $text{'index_return2'}); } else { &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); } virtual-server/edit_alias.cgi0100775000567100000120000000404510007630566016326 0ustar jcameronwheel#!/usr/local/bin/perl # edit_alias.cgi # Display a form for editing or adding a mail alias require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); if ($in{'new'}) { &header($text{'alias_create'}, ""); } else { &header($text{'alias_edit'}, ""); @aliases = &list_domain_aliases($d); ($virt) = grep { $_->{'from'} eq $in{'alias'} } @aliases; } &domain_title($d); print "
\n"; print &check_clicks_function(); print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'alias_header'}
\n"; $name = $virt->{'from'}; $name =~ s/\@\S+$//; print "\n"; printf "\n"; &alias_form($virt->{'to'}, &hlink("$text{'alias_dests'}", "aliasdest"), $d, "alias", $in{'alias'}); print "
",&hlink("$text{'alias_name'}", "aliasname")," %s\n", $name eq "" && !$in{'new'} ? "checked" : "", $text{'alias_catchall'}; printf " %s\n", $name eq "" && !$in{'new'} ? "" : "checked", $text{'alias_mailbox'}; print "
\n"; print "\n"; if ($in{'new'}) { print "\n"; } else { print "\n"; print "\n"; } print "
\n"; print "
\n"; if ($single_domain_mode) { &footer("list_aliases.cgi?dom=$in{'dom'}", $text{'aliases_return'}, "", $text{'index_return2'}); } else { &footer("list_aliases.cgi?dom=$in{'dom'}", $text{'aliases_return'}, "edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); } virtual-server/save_alias.cgi0100775000567100000120000000270510017553137016337 0ustar jcameronwheel#!/usr/local/bin/perl # save_alias.cgi # Create, update or delete an alias require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); @aliases = &list_domain_aliases($d); if (!$in{'new'}) { ($virt) = grep { $_->{'from'} eq $in{'old'} } @aliases; %oldvirt = %$virt; } &error_setup($text{'alias_err'}); if ($in{'delete'}) { # Just delete the virtuser &delete_virtuser($virt); &webmin_log("delete", "alias", $virt->{'from'}, $virt); } else { # Verify inputs $in{'name_def'} || $in{'name'} =~ /^[A-Za-z0-9\.\-\_]+$/ || &error($text{'alias_ename'}); $name = $in{'name_def'} ? "" : $in{'name'}; $virt->{'from'} = $name."\@".$d->{'dom'}; @values = &parse_alias(); @values || &error($text{'alias_enone'}); $virt->{'to'} = \@values; if ($in{'new'}) { # Check for a clash if (&check_clash($name, $d->{'dom'})) { &error($text{'alias_eclash'}); } # Create the virtuser &create_virtuser($virt); &webmin_log("create", "alias", $virt->{'from'}, $virt); } else { if ($virt->{'from'} ne $in{'old'}) { # Has been renamed .. check for a clash if (&check_clash($name, $d->{'dom'})) { &error($text{'alias_eclash'}); } } # Modify virtuser &modify_virtuser(\%oldvirt, $virt); &webmin_log("modify", "alias", $virt->{'from'}, $virt); } } &redirect("list_aliases.cgi?dom=$in{'dom'}"); sub check_aliasfile { return 0 if (!-r $_[0] && !$_[1]); return 1; } virtual-server/start_apache.cgi0100755000567100000120000000405310017555117016662 0ustar jcameronwheel#!/usr/local/bin/perl # start_apache.cgi # Start apache with the server root from the config files require './virtual-server-lib.pl'; $access{'stop'} || &error($text{'start_ecannot'}); &require_apache(); &ReadParse(); &error_setup($apache::text{'start_err'}); &clean_environment(); if ($apache::config{'start_cmd'}) { # use the configured start command if ($apache::config{'stop_cmd'}) { # execute the stop command to clear lock files &system_logged("( $apache::config{'stop_cmd'} ) >/dev/null 2>&1"); } $out = &backquote_logged("( $apache::config{'start_cmd'} ) 2>&1"); &reset_environment(); if ($?) { &error("
$out
"); } } elsif (-x $apache::config{'apachectl_path'}) { # use the apachectl program $out = &backquote_logged("( $apache::config{'apachectl_path'} start ) 2>&1"); &reset_environment(); if ($out =~ /\S/ && $out !~ /httpd started/) { &error("
$out
"); } } else { # start manually $cmd = "$apache::config{'httpd_path'} -d $apache::config{'httpd_dir'}"; if ($apache::config{'httpd_conf'}) { $cmd .= " -f $apache::config{'httpd_conf'}"; } $temp = &tempname(); $rv = &system_logged("( $cmd ) >$temp 2>&1 $cmd :\n$out"); } } # check if startup was successful. Later apache version return no # error code, but instead fail to start and write the reason to # the error log file! sleep(3); $conf = &apache::get_config(); $pid = &get_apache_pid(); if (!$pid || !kill(0, $pid)) { # Not running.. find out why $errorlogstr = &apache::find_directive_struct("ErrorLog", $conf); $errorlog = $errorlogstr ? $errorlogstr->{'words'}->[0] : "logs/error_log"; if ($out =~ /\S/) { &error("
$out
"); } elsif ($errorlog eq 'syslog' || $errorlog =~ /^\|/) { &error($apache::text{'start_eunknown'}); } else { $errorlog = &apache::server_root($errorlog, $conf); $out = `tail -5 $errorlog`; &error("
$out
"); } } &webmin_log("start", "web"); &redirect(""); virtual-server/stop_apache.cgi0100775000567100000120000000160110017555164016512 0ustar jcameronwheel#!/usr/local/bin/perl # stop_apache.cgi # Shut down the Apache webserver require './virtual-server-lib.pl'; $access{'stop'} || &error($text{'stop_ecannot'}); &require_apache(); &error_setup($apache::text{'stop_err'}); if ($apache::config{'stop_cmd'}) { # use the configured stop command $out = &backquote_logged("( $apache::config{'stop_cmd'} ) 2>&1"); if ($?) { &error("
$out
"); } } elsif (-x $apache::config{'apachectl_path'}) { # use the apachectl program $out = &backquote_logged("$apache::config{'apachectl_path'} stop 2>&1"); if ($httpd_modules{'core'} >= 2 ? $? : $out !~ /httpd stopped/) { &error("
$out
"); } } else { # kill the process $pid = &get_apache_pid(); $pid || &error(&apache::text('stop_epid2', $pidfile)); &kill_logged('TERM', $pid) || &error(&apache::text('stop_esig', $pid)); } sleep(1); &webmin_log("stop", "web"); &redirect(""); virtual-server/start_bind.cgi0100755000567100000120000000225110017555126016353 0ustar jcameronwheel#!/usr/local/bin/perl # start_bind.cgi # Start bind 8 require './virtual-server-lib.pl'; $access{'stop'} || &error($text{'start_ecannot'}); &require_bind(); if ($bconfig{'named_user'}) { $user = "-u $bconfig{'named_user'}"; if ($config{'named_group'}) { $user .= " -g $bconfig{'named_group'}"; } else { local @u = getpwnam($bconfig{'named_user'}); local @g = getgrgid($u[3]); $user .= " -g $g[0]"; } } if ($bconfig{'start_cmd'}) { $cmd = $bconfig{'start_cmd'}; } elsif (!$bconfig{'chroot'}) { $cmd = "$bconfig{'named_path'} -c $bconfig{'named_conf'} $user &1"; } elsif (`$bconfig{'named_path'} -help 2>&1` =~ /\[-t/) { # use named's chroot option $cmd = "$bconfig{'named_path'} -c $bconfig{'named_conf'} -t $bconfig{'chroot'} $user &1"; } else { # use the chroot command $cmd = "chroot $bconfig{'chroot'} $bconfig{'named_path'} -c $bconfig{'named_conf'} $user &1"; } $temp = &tempname(); $rv = &system_logged("$cmd $temp 2>&1"); $out = `cat $temp`; unlink($temp); if ($rv || $out =~ /chroot.*not available/i) { &error(&bind8::text('start_error', "$out")); } &webmin_log("start", "dns"); &redirect(""); virtual-server/stop_bind.cgi0100775000567100000120000000101510017555255016205 0ustar jcameronwheel#!/usr/local/bin/perl # stop_bind.cgi # Stop bind 8 require './virtual-server-lib.pl'; $access{'stop'} || &error($text{'stop_ecannot'}); &require_bind(); &error_setup($text{'bstop_err'}); if ($bconfig{'stop_cmd'}) { # Just use a command $out = &backquote_logged("( $bconfig{'stop_cmd'} ) 2>&1"); if ($?) { &error("
$out
"); } } else { # Kill the process $pid = &get_bind_pid(); if (!$pid || !&kill_logged('TERM', $pid)) { &error($text{'bstop_epid'}); } } &webmin_log("stop", "dns"); &redirect(""); virtual-server/start_mail.cgi0100775000567100000120000000042310017555144016362 0ustar jcameronwheel#!/usr/local/bin/perl # start_mail.cgi # Start up the mail server require './virtual-server-lib.pl'; $access{'stop'} || &error($text{'start_ecannot'}); &require_mail(); &error_setup($text{'mstart_err'}); &startup_mail_server(); &webmin_log("start", "mail"); &redirect(""); virtual-server/stop_mail.cgi0100775000567100000120000000042110017555264016213 0ustar jcameronwheel#!/usr/local/bin/perl # stop_mail.cgi # Shut down the mail server require './virtual-server-lib.pl'; $access{'stop'} || &error($text{'stop_ecannot'}); &require_mail(); &error_setup($text{'mstop_err'}); &shutdown_mail_server(); &webmin_log("stop", "mail"); &redirect(""); virtual-server/edit_domain.cgi0100775000567100000120000001504510041656266016511 0ustar jcameronwheel#!/usr/local/bin/perl # edit_domain.cgi # Display details of a domain for editing require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); $access{'edit'} && &can_edit_domain($d) || &error($text{'edit_ecannot'}); &header($text{'edit_title'}, ""); #&domain_title($d); print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
$text{'edit_header'}
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($d->{'iface'}) { # Got a virtual IP print "\n"; print "\n"; } elsif ($config{'all_namevirtual'}) { # Always name-based, but IP can be changed print "\n"; } else { # Show option to add print "\n"; } print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($config{'home_quotas'}) { print "\n"; @users = &list_domain_users($d); ($duser) = grep { $_->{'user'} eq $d->{'user'} } @users; print "\n"; print "\n"; print "\n"; } # Show buttons for turning features on and off (if allowed) print "\n"; if ($d->{'disabled'}) { print "\n"; } else { $i = 0; foreach $f (@opt_features) { print "\n" if ($i%2 == 0); print "\n"; if ($config{$f} || !defined($config{$f})) { printf"\n", $d->{$f} ? "" : "checked", $text{'no'}; } else { print "\n"; } print "\n" if ($i++%2 == 1); } print "\n"; } print "
$text{'edit_domain'}$d->{'dom'}$text{'edit_user'}$d->{'user'}
$text{'edit_ip'}$d->{'ip'}$text{'edit_virt'}$d->{'iface'}
", "$text{'edit_virtnone'}\n"; print " ", "$text{'edit_virtalloc'}\n"; print "
$text{'edit_owner'}
$text{'edit_email'} \n"; printf " %s\n", $d->{'email'} ? "" : "checked", $text{'edit_email_def'}; printf "\n", $d->{'email'} ? "checked" : ""; print "
$text{'edit_passwd'} \n"; print " $text{'edit_lv'}\n"; print " $text{'edit_set'}\n"; print "
$text{'form_mailboxlimit'} \n"; printf " %s\n", $d->{'mailboxlimit'} ? "" : "checked", $text{'form_unlimit'}; printf " %s\n", $d->{'mailboxlimit'} ? "checked" : "", $text{'form_atmost'}; print "
$text{'edit_quota'} \n"; printf " %s\n", $d->{'quota'} ? "" : "checked", $text{'form_unlimit'}; printf "\n", $d->{'quota'} ? "checked" : ""; print "a_input("quota", $d->{'quota'}, $config{'home_quotas'}), "
$text{'edit_uquota'} \n"; printf " %s\n", $d->{'uquota'} ? "" : "checked", $text{'form_unlimit'}; printf "\n", $d->{'uquota'} ? "checked" : ""; print "a_input("uquota", $d->{'uquota'}, $config{'home_quotas'}), "
$text{'edit_mailquota'} \n"; local $mailquota = 0; local $homequota = 0; foreach $u (@users) { if ($u->{'user'} ne $d->{'user'}) { $homequota += $u->{'uquota'}; $mailquota += $u->{'umquota'}; } } print &text('edit_qon', "a_show($homequota, $config{'home_quotas'}), $config{'home_quotas'}),"\n"; local $mq = $config{'mail_quotas'} && $config{'mail_quotas'} ne $config{'home_quotas'}; if ($mq) { print " , ",&text('edit_qon', "a_show($mailquota, $config{'mail_quotas'}), $config{'mail_quotas'}),"\n"; } print "
$text{'edit_userquota'} \n"; print &text('edit_qon', "a_show($duser->{'uquota'}, $config{'home_quotas'}), $config{'home_quotas'}),"\n"; if ($mq) { print " , ",&text('edit_qon', "a_show($duser->{'umquota'}, $config{'mail_quotas'}), $config{'mail_quotas'}),"\n"; } print "

 
", "$text{'edit_disabled'}
 
",$text{'edit_'.$f}," %s\n", $d->{$f} ? "checked" : "", $text{'yes'}; printf" %s$text{'form_unavail'}
\n"; print "\n"; print "\n"; print "\n"; if ($d->{'disabled'}) { print "\n"; print "\n"; print "\n"; print "\n"; } else { print "\n"; print "\n"; print "\n"; print "\n"; } print "\n"; print "\n"; print "\n"; print "\n"; if ($d->{'mail'}) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } print "
\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/backup_form.cgi0100664000567100000120000001034610041652512016507 0ustar jcameronwheel#!/usr/local/bin/perl # Show a form for backing up a single virtual server, or a bunch # # XXX support use by domain owners? # XXX should restore actually create the virtual server? require './virtual-server-lib.pl'; &ReadParse(); $master_admin || &error($text{'backup_ecannot'}); if ($in{'sched'}) { &header($text{'backup_title2'}, ""); print "
\n"; print "
\n"; print "\n"; print "\n"; print "
$text{'backup_header2'}
\n"; } else { &header($text{'backup_title'}, ""); print "
\n"; print "\n"; print "
\n"; print "\n"; print "
$text{'backup_header'}
\n"; } # Show domain selection list @doms = &list_domains(); %bak = map { $_, 1 } split(/\s+/, $config{'backup_doms'}); print "\n"; # Show feature selection boxes print "\n"; # Show destination fields print "\n"; print "\n"; print "\n"; printf "\n", $config{'backup_strftime'} ? "checked" : "", $text{'backup_strftime'}; print "\n", $config{'backup_fmt'} == 1 ? "checked" : "", $text{'backup_fmt1'}; # Show error mode print "\n", $config{'backup_errors'} == 1 ? "checked" : "", $text{'backup_errors1'}; if ($in{'sched'}) { # Show schedule inputs &foreign_require("cron", "cron-lib.pl"); local @jobs = &cron::list_cron_jobs(); local ($job) = grep { $_->{'user'} eq 'root' && $_->{'command'} eq $backup_cron_cmd } @jobs; # Enabled/disabled input print "\n"; printf "\n", $job ? "checked" : "", $text{'backup_enabledyes'}; # Email input print "\n"; printf "\n", $config{'backup_email'}; # Times input print "\n"; print "
$text{'backup_doms'} \n"; printf " %s\n", $config{'backup_all'} ? "checked" : "", $text{'backup_all'}; printf " %s
\n", $config{'backup_all'} ? "" : "checked", $text{'backup_sel'}; $sz = scalar(@doms) > 10 ? 10 : scalar(@doms); print "
$text{'backup_features'} \n"; foreach $f (@backup_features) { local $bfunc = "backup_$f"; if (defined(&$bfunc) && ($config{$f} || $f eq "unix" || $f eq "virtualmin")) { printf " %s\n", $f, $config{'backup_feature_'.$f} ? "checked" : "", $text{'backup_feature_'.$f} || $text{'feature_'.$f}; local $ofunc = "show_backup_$f"; if (defined(&$ofunc)) { local %opts = map { split(/=/, $_) } split(/,/, $config{'backup_opts_'.$f}); local $ohtml = &$ofunc(\%opts); print $ohtml; } print "
\n"; } } print "
$text{'backup_dest'}",&show_backup_destination("dest", $config{'backup_dest'}), "
%s
$text{'backup_fmt'} \n"; printf " %s\n", $config{'backup_fmt'} == 0 ? "checked" : "", $text{'backup_fmt0'}; printf " %s
$text{'backup_errors'} \n"; printf " %s\n", $config{'backup_errors'} == 0 ? "checked" : "", $text{'backup_errors0'}; printf " %s
$text{'backup_enabled'} %s\n", $job ? "" : "checked", $text{'no'}; printf " %s
$text{'backup_email'}
\n"; $job ||= { 'special' => 'daily' }; &cron::show_times_input($job); print "
\n"; print "\n"; } else { print "
\n"; print "\n"; } print "
\n"; &footer("", $text{'index_return'}); virtual-server/save_domain.cgi0100775000567100000120000001173410036363520016513 0ustar jcameronwheel#!/usr/local/bin/perl # save_domain.cgi # Update or delete a domain require './virtual-server-lib.pl'; &require_bind() if ($config{'dns'}); &require_useradmin(); &require_mail() if ($config{'mail'}); &ReadParse(); $d = &get_domain($in{'dom'}); $access{'edit'} && &can_edit_domain($d) || &error($text{'edit_ecannot'}); $oldd = { %$d }; # Validate inputs &error_setup($text{'save_err'}); if ($config{'home_quotas'}) { if ($in{'quota'} eq -1) { $in{'quota'} = $in{'otherquota'} }; if ($in{'uquota'} eq -1) { $in{'uquota'} = $in{'otheruquota'} }; $in{'quota_def'} || $in{'quota'} =~ /^\d+$/ || &error($text{'save_equota'}); $in{'uquota_def'} || $in{'uquota'} =~ /^\d+$/ || &error($text{'save_euquota'}); } ($d->{'db'} = $d->{'user'}) =~ s/[\.\-]/_/g if (!$d->{'db'}); $in{'mailboxlimit_def'} || $in{'mailboxlimit'} =~ /^[1-9]\d*$/ || &error($text{'setup_emailboxlimit'}); # Check for various clashes my $f; foreach $f (@features) { if (!$d->{$f} && $in{$f}) { local $cfunc = "check_${f}_clash"; if (&$cfunc($d->{'dom'}, $d->{'db'}, $d->{'user'}, $d->{'group'})) { &error(&text('setup_e'.$f, $d->{'dom'}, $d->{'db'}, $d->{'user'}, $d->{'group'})); } } } # Check for feature dependencies foreach $f (@features) { if ($in{$f}) { local $fd; foreach $fd (@{$feature_depends{$f}}) { &error(&text('setup_edep'.$f)) if (!$in{$fd}); } } } if ($config{'all_namevirtual'}) { # Make sure any new IP *is* assigned &check_ipaddress($in{'ip'}) || &error($text{'setup_eip'}); if ($d->{'ip'} ne $in{'ip'} && !&check_virt_clash($in{'ip'})) { &error(&text('setup_evirtclash2')); } } elsif ($in{'virt'} && !$d->{'virt'}) { # Make sure the IP isn't assigned yet &check_ipaddress($in{'ip'}) || &error($text{'setup_eip'}); if (&check_virt_clash($in{'ip'})) { &error(&text('setup_evirtclash')); } } # Check if any features are being disabled, and if so ask the user if # he is sure if (!$in{'confirm'} && !$d->{'disabled'}) { local @losing; foreach $f (@features) { if ($config{$f} && $d->{$f} && !$in{$f}) { push(@losing, $f); } } if (@losing) { &header($text{'save_title'}, ""); print "
\n"; print "

",&text('save_rusure',"$d->{'dom'}"),"

\n"; print "

    \n"; foreach $f (@losing) { print "
  • ",$text{'feature_'.$f}," - ", $text{'losing_'.$f},"
    \n"; } print "
\n"; print &check_clicks_function(); print "
\n"; foreach $k (keys %in) { foreach $v (split(/\0/, $in{$k})) { print "\n"; } } print "\n"; print "
\n"; print "
\n"; &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); exit; } } # Make the changes $| = 1; $theme_no_table++; &header($text{'save_title'}, ""); print "
\n"; # Run the before command &set_domain_envs($d, "MODIFY_DOMAIN"); $merr = &making_changes(); &error(&text('save_emaking', "$merr")) if (defined($merr)); # Update description, password and quotas in domain object $d->{'owner'} = $in{'owner'}; if (!$in{'passwd_def'}) { if ($d->{'disabled'}) { # Clear any saved passwords, as they should # be reset at this point $d->{'disabled_mysqlpass'} = undef; $d->{'disabled_postgrespass'} = undef; } $d->{'pass'} = $in{'passwd'}; $d->{'pass_set'} = 1; # indicates that the password has been changed } else { $d->{'pass_set'} = 0; } if ($config{'home_quotas'}) { $d->{'uquota'} = $in{'uquota_def'} ? undef : "a_parse('uquota', $config{'home_quotas'}); $d->{'quota'} = $in{'quota_def'} ? undef : "a_parse('quota', $config{'home_quotas'}); } if ($config{'all_namevirtual'}) { # Need to change IP $d->{'ip'} = $in{'ip'}; } elsif ($in{'virt'} && !$d->{'virt'}) { # Need to bring up IP $d->{'ip'} = $in{'ip'}; $d->{'virt'} = 1; $d->{'name'} = 0; &setup_virt($d); } # XXX maybe change this? if (!$d->{'disabled'}) { # Enable or disable features my $f; $in{'unix'} = 1; # always enabled foreach $f (@features) { if ($config{$f} || $f eq 'unix') { local $sfunc = "setup_$f"; local $dfunc = "delete_$f"; local $mfunc = "modify_$f"; if ($in{$f} && !$d->{$f}) { &$sfunc($d); } elsif (!$in{$f} && $d->{$f}) { &$dfunc($d); } elsif ($in{$f}) { &$mfunc($d, $oldd); } $d->{$f} = $in{$f}; } } } else { # Only modify unix if disabled &modify_unix($d, $oldd); } # Save new domain details print $text{'save_domain'},"
\n"; $d->{'email'} = $in{'email_def'} ? undef : $in{'email'}; $d->{'mailboxlimit'} = $in{'mailboxlimit_def'} ? undef : $in{'mailboxlimit'}; &save_domain($d); print $text{'setup_done'},"

\n"; # Run the after command &set_domain_envs($d, "MODIFY_DOMAIN"); &made_changes(); &webmin_log("modify", "domain", $d->{'dom'}, $d); print "


\n"; &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); virtual-server/help/0040755000567100000120000000000010025226017014457 5ustar jcameronwheelvirtual-server/help/unixuserquota.html0100644000567100000120000000072007664244336020320 0ustar jcameronwheel
Quota for Unix user
The owner of a domain is just like a normal user account, in that it can receive email, and disk space usage quotas can be applied, as well. The files within the domain website will normally be owned by the user, so it may be useful to specify website size using this quota, while allowing the total quota for the entire server to limit the total used for mail and website data belonging to all users within the domain.
virtual-server/help/ownersname.html0100644000567100000120000000023607673260425017541 0ustar jcameronwheel
Description
In this field, enter a description for the domain such as the real name its owner (the person responsible for the domain).
virtual-server/help/webmin.html0100664000567100000120000000041607704711517016644 0ustar jcameronwheel
Create Webmin login?
If selected, a Webmin user with the same username and password as the Unix user who owns this domain will be created. This user will be able to use Webmin to manage the domain's website, DNS domain and databases, if enabled.
virtual-server/help/mailfile.html0100644000567100000120000000033107734767704017153 0ustar jcameronwheel
Primary mail file
This is the file path and name of the users email box. Clicking the Read Mail link will take you to the readers mailbox, where it is possible to delete or move emails.

virtual-server/help/mysql.html0100664000567100000120000000027707673254603016540 0ustar jcameronwheel

Create MySQL database?
If selected, a new empty MySQL database will be created for use by this domain. The database will be given the same name as the domain's user.
virtual-server/help/password.html0100644000567100000120000000022607664241613017222 0ustar jcameronwheel
Password
Here you may enter a password for the user. If a password already exists, it will be replaced with the new password.
virtual-server/help/index.html0100644000567100000120000000066107664010221016457 0ustar jcameronwheel
Virtual Server
The Webmin virtual servers module provides a means to create, modify, and delete user mailboxes and virtual server user accounts. With its domain management features you can quickly and easily create a new website with domain records, Apache VirtualHost configuration, a home directory, a user account to manage it, mail server configuration, disk usage quotas and email addresses and aliases.
virtual-server/help/realname.html0100644000567100000120000000021207664241621017136 0ustar jcameronwheel
Real Name
The users full name. This is a mostly free text field and may contain letters, numbers and white space.
virtual-server/help/username.html0100644000567100000120000000044307664241562017203 0ustar jcameronwheel
Username
The username is a unique (within the domain) name for a user. This will be the first part of the email address for the user. I.e., if the user is named joe, and the domain is swelltech.com, the email address is joe@swelltech.com.
virtual-server/help/domainname.html0100644000567100000120000000062607664244314017475 0ustar jcameronwheel
Domain Name
This is the name of the domain to be created, or being edited. A domain name must be composed of latters and numbers, with optional dashes, "-". Underscores, "_", and other special characters are not permitted in domain names.

Once a domain has been created its name cannot be changed, without deleting the domain and creating a new one with the new name.


virtual-server/help/unixusername.html0100644000567100000120000000106007664244333020102 0ustar jcameronwheel
Unix Username
The Unix Username is the username of the owner of the domain. This user will be permitted to edit the htaccess options for the domain website, as well as edit the website content. This user may be used to receive email, though it is traditionally named after the domain, and is not useful except as an optional catch-all email account (catch-all email addresses are not recommended anymore due to the spam scourge...perhaps some day, when spammers are imprisoned for their actions we can have catch-all addresses again).
virtual-server/help/websitequota.html0100644000567100000120000000041407664244362020077 0ustar jcameronwheel
Total quota for entire server
Each domain has its own quota for disk space usage. This quota is a limit that is imposed on the combined usage of the users within the domain. Each user within the domain may have his or her own quotas, as well.
virtual-server/help/webservertype.html0100644000567100000120000000050007664244440020262 0ustar jcameronwheel
Web server type
A virtual webserver can be name-based, or IP-based. In the vast majority of cases, a name-based virtual server is sufficient. Only when an SSL site is to be hosted, or an anonymous FTP directory must be provided for the domain, is it necessary to use an IP-based virtual server.
virtual-server/help/ipaddress.html0100644000567100000120000000043707664244451017345 0ustar jcameronwheel
IP address
This is the IP address for the virtual server. It will be configured in the name server records, and optionally in the Apache VirtualHost directive (Apache can also be configured to use the "*" IP, which matches all active IP addresses on the system).
virtual-server/help/diskquota.html0100644000567100000120000000024507664703572017374 0ustar jcameronwheel
Disk Quota
This is the space in blocks (one block equals one kilobyte) that will be available to the user for email and website data storage.
virtual-server/help/virtualinterface.html0100644000567100000120000000031407664244473020734 0ustar jcameronwheel
Virtual interface
If using IP-based virtual hosts (which are required for SSL websites, or anonymous FTP sites), the virtual interface on which the domain lives will be shown here.
virtual-server/help/createmailbox.html0100644000567100000120000000061207663412612020174 0ustar jcameronwheel
Create Mailbox
This page is for creating local mailboxes. These mailboxes will be for addresses in the default domain of the server, rather than a virtual domain hosted on the server. Mailboxes for virtual domains are created in the second section of the module index page.

When creating a new local mailbox only the username, real name, and password are required.


virtual-server/help/mail.html0100644000567100000120000000037007705710161016275 0ustar jcameronwheel
Accept mail for domain?
If enabled, the server will be configured to accept email addresses to mailboxes or aliases at the specified domain. The management of mailboxes and aliases within the domain will also be enabled.


virtual-server/help/web.html0100644000567100000120000000050407664244407016140 0ustar jcameronwheel
Set up website for domain?
The module can create any or all of the following services for a new domain: mail, name service, web service. If this option is set to Yes, a new VirtualHost configuration section will be added to the Apache configuration and a new website home directory will be created.
virtual-server/help/dns.html0100644000567100000120000000025007664244422016142 0ustar jcameronwheel
Set up DNS zone?
If selected, new name records for this domain, including mail records, and NS records, will be added to the BIND configuration.
virtual-server/help/postgres.html0100664000567100000120000000031107704711473017224 0ustar jcameronwheel
Create PostgreSQL database?
If selected, a new empty PostgreSQL database will be created for use by this domain. The database will be given the same name as the domain's user.
virtual-server/help/unixgroupname.html0100644000567100000120000000053607711155140020255 0ustar jcameronwheel
Group for Unix User
By default, the group for the Unix user who is created to own this domain's files will be the same as the group for its mail users. However, you can select an existing group on the server instead, which can be useful if you have some kind of group-based access restrictions in force (such as for FTP).


virtual-server/help/postgres.de.html0100644000567100000120000000041607726526344017624 0ustar jcameronwheel
Eine PostgreSQL-Datenbank anlegen?
Wenn dies ausgewählt ist, dann wird eine neue leere PostgreSQL-Datenbank für diesen Benutzer angelegt. Die Datenbank hat den gleichen Namen, wie der Benutzer.
virtual-server/help/virtualinterface.de.html0100644000567100000120000000052407726526344021325 0ustar jcameronwheel
Virtuelles Netzwerk-Interface
Wenn Sie IP-basierende Virtuelle Server einsetzen, welche für SSL-Webseiten und/oder Anonymes FTP absolut erforderlich sind, dann werden die entsprechenden virtuellen Netzwerk-Interfaces, die zu dieser Domain gehören, hier aufgelistet.
virtual-server/help/ownersname.de.html0100644000567100000120000000052607726526344020136 0ustar jcameronwheel
Beschreibung
In diesem Feld können Sie ein sinnvolle Beschreibung für die Domain eingeben. Normalerweise ist dies der Real-Name des Inhabers der Domain oder die Beschreibung des Sinns. Für webmin.mamemu.de zB habe ich "Mirror of www.webmin.com" eingegeben.
virtual-server/help/domainname.de.html0100644000567100000120000000102007726526344020056 0ustar jcameronwheel
Name der Domain
Dies ist der Name der Domain, welche angelegt oder geändert werden soll. Ein Domain-Name muß aus Buchstaben und Nummern bestehen und darf an Sonderzeichen lediglich Minus "-", Unterstriche "_" beinhalten. Andere Zeichen sind in Domain-Namen nicht gestattet. Ist eine Domain erst einmal erzeugt, so kann der Name nicht mehr geändert werden ohne daß die Domain komplett gelöscht und eine neue erzeugt würde.
virtual-server/help/createmailbox.de.html0100644000567100000120000000103607726526344020574 0ustar jcameronwheel
Eine Mailbox anlegen
Diese Seite hilft Ihnen dabei lokale Mailboxen anzulegen. Diese Mailboxen werden für Adressen der Standard-Domain des Servers angelgt und nicht für eine Virtuelle Domain, die auf dem Server gehostet wird. Mailboxen für eine Virtuelle Domain werden in der zweiten Sektion der Modul-Hauptseite angelegt. Wenn Sie eine neue lokale Mailbox anlegen, brauchen Sie nur den Unix-Benutzernamen, den Realnamen des Benutzers und ein Passwort angeben.
virtual-server/help/password.de.html0100644000567100000120000000036707726526344017625 0ustar jcameronwheel
Passwort
Hier geben Sie das Passwort für den Benutzer ein. Wenn bereits ein Passwort für den Benutzer besteht, dann wird es überschrieben und durch dieses hier ersetzt.
virtual-server/help/diskquota.de.html0100644000567100000120000000036407726526344017764 0ustar jcameronwheel
Speicherplatz (Quota)
Dies ist der Speichplatz in Blöcken (ein Block entspricht einem Kilobyte), welcher dem Benutzer für eMail und Webseitenspeicherung zugewiesen wird.
virtual-server/help/dns.de.html0100644000567100000120000000035307726526344016542 0ustar jcameronwheel
Eine DNS-Zone einrichten?
Wenn Sie dies auswählen, dann wird ein neuer DNS-Namenseintrag inklusive Mail-Record und NS-Record der BIND-Konfiguration hinzugefügt.
virtual-server/help/webservertype.de.html0100644000567100000120000000063707726526344020671 0ustar jcameronwheel
Webserver-Typ
Ein virtueller Webserver kann Namen-basierend oder IP-basierend sein. In den allermeisten Fällen reicht ein Namen-basierter virtueller Webserver völlig aus. Erst dann, wenn Sie SSL einsetzen oder Anonymes FTP einrichten für diese Domain einsetzen wollen, dann müssen Sie einen IP-basierenden virtuellen Server einsetzen.
virtual-server/help/index.de.html0100644000567100000120000000130707726526344017065 0ustar jcameronwheel
Virtualmin Virtuelle Server
Das WebMin-Modul "Virtualmin Virtuelle Server" bietet eine einfache Möglichkeit an, um User-Mailboxen und User-Accounts für die Verwaltung von Virtuellen Servern einzurichten, abzuändern oder zu löschen. Mit seinen Domain-Management-Funktionen können Sie relativ schnell und einfach eine neue Webseite mit DNS-Einträgen, Apache-"VirtualHost"-Konfiguration, einem Home-Verzeichnis, einem Unix-Benutzeraccount zur Pflege und Wartung der Virtuellen Servers, Mail-Serverkonfiguration, Speicherplatzbegrenzungen (Disk Quotas) und eMail-Adressen und eMail-Aliasen einrichten.
virtual-server/help/mailfile.de.html0100644000567100000120000000053107726526344017536 0ustar jcameronwheel
Primärer Pfad zur Mailbox eines Benutzers
Dies ist der Dateipfad und der Name der Mailbox eines Benutzers. Wenn auf den eMail lesen-Link geklickt wird, dann wird diese Datei eingelesen. So kann der Benutzer dann eMails lesen, schreiben, löschen und sogar verschieben.
virtual-server/help/mail.de.html0100644000567100000120000000053107726526344016676 0ustar jcameronwheel
Mail-Server für die Domain einrichten?
Wenn dieses ausgewählt ist, dann wird der vorhandene eMail-Server dahingehend konfiguriert, daß er eMails für die anzulegende/angelegte Domain akzeptiert. Ebenso wird das eMail-Management für diese Domain eingeschaltet.
virtual-server/help/websitequota.de.html0100644000567100000120000000054607726526344020476 0ustar jcameronwheel
Komplette Quota für den kompletten Server
Jede Domain hat Ihre eigenen Einstellungen bezüglich Speicherplatzbegrenzung. Diese "Quota" ist eine Begrenzung für den die gesammte Domain. Diese Quota können Sie unter den Nutzern weiter aufsplitten, wenn Sie mögen.
virtual-server/help/web.de.html0100644000567100000120000000073307726526344016535 0ustar jcameronwheel
Eine Webseite fr die Domain anlegen?
Dieses Modul kann einige oder alle der folgenden Dinge für eine neue Domain für Sie einrichten: Mail-, DNS- und eben Web-Service. Wenn Sie diese Option mit "Ja" auswählen, dann wird eine neue Apache-"VirtualHost"-Direktive in der Apache-Konfiguration und ein Verzeichnis für die Webseite im Home-Verzeichnis des Unix-Benutzers angelegt.
virtual-server/help/unixuserquota.de.html0100644000567100000120000000163707726526344020720 0ustar jcameronwheel
Speicherplatz für einen Unix-Benutzer
Der Eigentümer einer Domain ist eigentlich ein normaler Unix-Benutzer. Er kann eMail empfangen und es kann ihm ein gewisser Speicherplatz bindend zugeordnet werden. Alle Dateien innerhalb einer Domain gehören normalerweise diesem Unix-Benutzer. Somit ist es sehr nützlich eine Webseite mit dessen Quota-Einstellungen so zu definieren, da dieser User zB 100 MB Speicherplatz hat (für die gesamte Domain inkl. Webseite und eMail). Wenn weitere vier Benutzer für diese Domain hinzukommen, so können diese dann jeweils 25 MB zugeordnet bekommen. Oder ein Benutzer bekommt 50 MB und die restlichen drei dann jeweils vielleicht nur 10 MB und es bleiben 20 MB übrig. Fr einen Unterbenutzer kann nicht mehr Speicherplatz vergeben werden, als dieser Benutzer insgesamt zur Verfügung hat.
virtual-server/help/username.de.html0100644000567100000120000000057407726526344017602 0ustar jcameronwheel
Domain-Benutzername
Der Domain-Benutzername ist der eindeutige Benutzer-Name innerhalb einer Domain. Er ist der erste Teil einer eMail-Adresse für einen Benutzer. Zum Beispiel: Wenn der Benutzer Joe heit und die Domaine swelltech.com, dann lautet die eMail-Adresse joe@swelltech.com.
virtual-server/help/ipaddress.de.html0100644000567100000120000000063007726526344017732 0ustar jcameronwheel
IP-Adresse
Dies ist die IP-Adresse für Ihren Virtuellen Server. Er wird in den DNS-Name-Records eingerichtet und optional in der Apache-"VirtualHost"-Direktive. Apache kann separat ebenfalls dazu konfiguriert werden die IP-Adresse "*" zu akzeptieren, welche alle aktiven IP-Adressen in Ihrem System abdecken würde.
virtual-server/help/mysql.de.html0100644000567100000120000000037607726526344017130 0ustar jcameronwheel
Eine MySQL-Datenbank anlegen?
Wenn dies ausgewählt ist, dann wird eine neue leere MySQL-Datenbank für diesen Benutzer angelegt. Die Datenbank hat den gleichen Namen, wie der Benutzer.
virtual-server/help/webmin.de.html0100644000567100000120000000104607726526344017237 0ustar jcameronwheel
Einen Webmin-Benutzer anlegen?
Wenn Sie dies auswählen, so wird ein Webmin-Benutzer angelegt, der den gleichen Nutzernamen und das gleiche Passwort für den Zugang zu Webmin hat, wie der Unix-Benutzer, den Sie anlegen müssen. Dieser Webmin-Benutzer kann dann über die Webmin-Oberfläche "seine" Domain selbständig verwalten. Dies betrifft die Webseite, DNS-Einträge, Datenbanken und Mail-Server-Einstellungen, wenn Sie dies auch aktivieren.
virtual-server/help/realname.de.html0100644000567100000120000000042207726526344017537 0ustar jcameronwheel
Real-Name
Diese ist der komplette Real-Name des Benutzers. Hier gehrt wirklich der echte und richtige Name des Benutzers rein und zwar voll ausgeschrieben. Verboten sind hier jegliche Sonderzeichen und Zahlen.
virtual-server/help/unixusername.de.html0100644000567100000120000000160007726526344020475 0ustar jcameronwheel
Unix-Benutzername
Der Unix-Benutzername ist der Benutzername des Inhabers einer Domaine. Dieser User darf zB die .htaccess-Einstellungen des Webservers einrichten und den kompletten Webseiten-Inhalt aller Benutzer dieser Domain editieren. Ebenso darf er eMails empfangen. Obwohl er eine eMail-Adresse user@domain.tld hat, ist es nicht sinnvoll, daß er einen Catch-All-Account auf die Domain hat (Catch-All: Alle eMails an die Domaine domain.tld gehen an User). Viele Spammer arbeiten nach dem Zufallsprinzip und entwickeln eMail-Adressen a la stgmerggmerh78@domain.tld und diese eMails würde er dann auch empfangen. Was jedoch Sinn macht ist, da dieser Benutzer die eMail-Adressen abuse@domain.tld und postmaster@domain.tld bekommt. Diese sind nach einschlägigen RfCs zwingend vorgeschrieben.
virtual-server/help/unixgroupname.de.html0100644000567100000120000000052107726526344020654 0ustar jcameronwheel
Gruppe für Unix-Benutzer
Grundsätzlich ist ein Benutzer Mitglied in der Gruppe, die den Namen des Benutzers hat. Sie können dies jedoch ändern, wenn Sie durch eine Gruppenzuweisung bestimmte Restriktionen bereits eingerichtet haben (fr den Zugang zu FTP z.B.)
virtual-server/help/ownersemail.html0100644000567100000120000000056707716401064017711 0ustar jcameronwheel
Contact email address
This field can be used to specify an email address to which all messages related to this virtual server will be sent. By default they will be sent to the Unix user who owns the server. The most common message is the one sent when the domain is created, containing information about its address, features, login and password.


virtual-server/help/webalizer.html0100664000567100000120000000051307733425115017343 0ustar jcameronwheel
Set up Webalizer for web logs?
When this option is enabled, Webalizer will be set up to generate a report on the websites log files every 24 hours. The report will be placed in ~/public_html/stats, and the domains web logs will be truncated each time the report is updated to save disk space.


virtual-server/help/extraemail.html0100644000567100000120000000031007734767674017527 0ustar jcameronwheel
Additional email addresses
This text box can be used to easily add extra email aliases for this user. These aliases will also be visible and editable in the mail aliases list.

virtual-server/help/ftp.html0100664000567100000120000000075407735447073016170 0ustar jcameronwheel

FTP login enabled?
When this option is set to Yes, the user will be given the shell , allowing him to login via FTP. When set to No, his shell will be set to instead, and FTP logins will be denied.

This assumes that the FTP shell is listed in the /etc/shells file, or otherwise allowed by the FTP server running on your system.


virtual-server/help/mailbox.html0100664000567100000120000000040407735446515017022 0ustar jcameronwheel
Primary email address enabled?
When this option is set to Yes, the user will be given the email address in the domain shown in the Username field. You may want to select No instead if the user is being created for FTP access only.


virtual-server/help/mailgroupname.html0100644000567100000120000000055007741463613020222 0ustar jcameronwheel
Group for Mailbox Users
Every domain must have an associated Unix group that will be used as the primary group for any mailbox Unix users. By default a name will be chosen automatically from the first part of the domain name, but you can use this field to specify any group name that you like, as long as it does not already exist.


virtual-server/help/usermailbox.html0100644000567100000120000000050607742424511017710 0ustar jcameronwheel
Create email address for unix user?
If this field is set to Yes, the Unix user created for this domain will be given an email address in the domain as well. The mailbox part of the address will always be the Unix username, so the address will typically be something like foo@foo.com.


virtual-server/help/aliasname.html0100644000567100000120000000055207744631421017313 0ustar jcameronwheel
Alias name
This field determines the part of the alias email address to the left of the @. You can either select the Mailbox option and enter a specific mailbox name (like sales), or choose All mailboxes to have the alias catch email send to any address at the domain which does not match any other user or alias.


virtual-server/help/aliasdest.html0100644000567100000120000000362107744633541017337 0ustar jcameronwheel
Alias destinations
This table of fields determines what happens to email sent to this alias. If multiple destinations are entered, mail will be sent to all of them. Each destination has a type (chosen from the menu), which can be one of the following :
  • Email address
    Email will be forwarded to the address entered in the adjacent field.

  • Addresses in file
    Email will be forwarded to all of the addresses listed in the text file whose path is entered in the adjacent field.

  • Write to file
    Email to the alias will appended to the specified file. All headers and the raw un-decoded body will be included.

  • Feed to program
    The program entered in the adjacent field will be executed and email to the alias passed to it as input.

  • Autoreply from file
    When email is received by this alias, and automatic reply message will be sent back to the sender. The text of this autoreply will be taken from the file entered in the adjacent text field.

  • Apply filter file
    Email sent to the alias will be processed according to the rules in the specified filter file, which may cause it to be forwarded to other addresses or files depending on the actual contents of the message.

  • Mailbox of user
    Email will be delivered directly to the mailbox of the user entered in the adjacent text field. This will bypass any forwarding addresses that the user has set up. However, you must enter the full POP3 login username, like joe.foo instead of just joe.

If you choose the Addresses in file, Autoreply from file or Apply filter file destination types, when you re-edit the alias links labeled Edit.. will appear next to any such destinations for editing the contents of the specified file.


virtual-server/help/userdest.html0100644000567100000120000000430007744634207017217 0ustar jcameronwheel
Email forwarding destinations
This table of fields determines what happens to email sent to this user. Normally it would just be delivered directly to the user's mailbox, but if any desintations are defined here then they will be used instead. This can be used to setup an autoresponder if the user is away on vacation, or to forward his email to an address on another server.

Each destination has a type (chosen from the menu), which can be one of the following :

  • Email address
    Email will be forwarded to the address entered in the adjacent field.

  • Addresses in file
    Email will be forwarded to all of the addresses listed in the text file whose path is entered in the adjacent field.

  • Write to file
    Email to the alias will appended to the specified file. All headers and the raw un-decoded body will be included.

  • Feed to program
    The program entered in the adjacent field will be executed and email to the alias passed to it as input.

  • Autoreply from file
    When email is received by the user, and automatic reply message will be sent back to the sender. The text of this autoreply will be taken from the file entered in the adjacent text field.

  • Apply filter file
    Email sent to the user will be processed according to the rules in the specified filter file, which may cause it to be forwarded to other addresses or files depending on the actual contents of the message.

  • Mailbox of user
    Email will be delivered directly to the mailbox of the user entered in the adjacent text field. Typically you would enter the name of the user himself, so that he receives a copy of the email as well as it being forwarded to any other destinations. However, you must enter the full POP3 login username, like joe.foo instead of just joe.

If you choose the Addresses in file, Autoreply from file or Apply filter file destination types, when you re-edit the users links labeled Edit.. will appear next to any such destinations for editing the contents of the specified file.


virtual-server/help/mailboxlimit.html0100644000567100000120000000033707772734312020060 0ustar jcameronwheel
Maximum allowed mailboxes
When enabled, this option places an upper limit on the number of mailboxes that can be created for this server. The domain owner's mailbox also counts towards the limit.


virtual-server/help/iface.html0100664000567100000120000000076710012102235016414 0ustar jcameronwheel
Network Interface
If you want to set up an IP-based virtual host (required for SSL websites or virtual FTP hosting), this option must be set to Virtual interface with IP and an un-used address entered. Virtualmin will activate this IP on your system when the server is created, and associate it with the server.

If the Shared option is selected, the system's primary network interface address will be used for this server's website and DNS domain instead.


virtual-server/help/proxypass.html0100664000567100000120000000044307771445237017442 0ustar jcameronwheel
Proxy entire website to URL
If this option is enabled, any website created for the domain will be set up to proxy all requests to the specified URL. This can be useful if the actual website content is stored elsewhere, such as on a host on an internal network.


virtual-server/help/ssl.html0100664000567100000120000000116210020460032016135 0ustar jcameronwheel
Set up SSL website too?
When this option is enabled, an additional Apache virtual host will be created for this virtual server, listening on port 443. This will allow browsers to connect to https://domainname.com/ using SSL encryption, as well as to http://domainname.com/ without encryption.

A self-signed SSL key and certificate will be generated as part of the server setup process, so that the SSL virtual host can be immediately used. However, you should generate a valid SSL certificate for the domain as soon as possible, so that it can be properly verified by browsers.


virtual-server/import.cgi0100775000567100000120000002604410040100064015523 0ustar jcameronwheel#!/usr/local/bin/perl # import.cgi # Work out what will be imported, and either tell the user or actually do it require './virtual-server-lib.pl'; $access{'create'} && $access{'import'} || &error($text{'import_ecannot'}); &ReadParse(); &header($text{'import_title'}, ""); print "
\n"; # Check for domain clash @doms = &list_domains(); ($clash) = grep { $_->{'dom'} eq $in{'dom'} } @doms; $clash && &error_exit($text{'import_eexists'}); # Validate username $in{'user_def'} || $in{'user'} =~ /^[^\t :]+$/ || &error_exit($text{'setup_euser2'}); $in{'group_def'} || $in{'group'} =~ /^[^\t :]+$/ || &error_exit($text{'import_egroup'}); # Validate quota if ($config{'home_quotas'}) { if ($in{'quota'} == -1) { $in{'quota'} = $in{'otherquota'} }; $in{'quota'} =~ /^\d+$/ || &error($text{'setup_equota'}); } # Make sure IP is valid if ($in{'virt'}) { &foreign_require("net", "net-lib.pl"); ($iface) = grep { $_->{'address'} eq $in{'ip'} } ( &net::boot_interfaces(), &net::active_interfaces() ); $iface || &error_exit($text{'import_enoip'}); $iface->{'address'} eq &get_default_ip() && &error_exit($text{'import_eipsame'}); foreach $d (@doms) { $d->{'ip'} eq $in{'ip'} && &error_exit(&text('import_eipclash', $d->{'dom'})); } $iface->{'virtual'} eq '' && &error_exit(&text('import_ereal', $iface->{'fullname'})); } if ($in{'confirm'}) { # Go ahead and do it print "$text{'import_doing'}

\n"; &require_useradmin(); # Get existing group and user details $crgroup = $in{'crgroup'} || $in{'group'}; @groups = &useradmin::list_groups(); ($ginfo) = grep { $_->{'group'} eq $crgroup } @groups; &build_group_taken(\%gtaken, \%ggtaken, \@groups); $gid = $ginfo ? $ginfo->{'gid'} : &allocate_gid(\%gtaken); $cruser = $in{'cruser'} || $in{'user'}; @users = &useradmin::list_users(); ($uinfo) = grep { $_->{'user'} eq $cruser } @users; &build_taken(\%taken, \%utaken, \@users); $uid = $uinfo ? $uinfo->{'uid'} : &allocate_uid(\%taken); $ugid = $uinfo ? $uinfo->{'gid'} : $gid; $ugroup = $uinfo ? getgrgid($uinfo->{'gid'}) : $crgroup; $owner = $uinfo ? $uinfo->{'real'} : "Imported domain $in{'dom'}"; # Create domain details %found = map { $_, 1 } split(/\0/, $in{'found'}); %dom = ( 'id', &domain_id(), 'dom', $in{'dom'}, 'user', $cruser, 'group', $crgroup, 'ugroup', $ugroup, 'quota', "a_parse('quota', $config{'home_quotas'}), 'uid', $uid, 'gid', $gid, 'ugid', $ugid, 'owner', $owner, 'mail', int($found{'mail'}), 'web', int($found{'web'}), 'webalizer', int($found{'webalizer'}), 'mysql', int($found{'mysql'}), 'postgres', int($found{'postgres'}), 'webmin', $in{'webmin'}, 'name', !$in{'virt'}, 'ip', $in{'ip'}, 'iface', $in{'virt'} ? $iface->{'fullname'} : "", 'virt', $in{'virt'}, 'dns', int($found{'dns'}), 'pass', $in{'pass'}, 'db', $in{'db'}, 'source', 'import.cgi' ); # Work out home directory $dom{'home'} = $uinfo ? $uinfo->{'home'} : &server_home_directory(\%dom); if (!$ginfo) { # Create the unix group print &text('setup_group', $crgroup),"
\n"; &useradmin::lock_user_files(); %ginfo = ( 'group', $crgroup, 'gid', $gid ); &useradmin::set_group_envs(\%ginfo, 'CREATE_GROUP'); &useradmin::making_changes(); &useradmin::create_group(\%ginfo); &useradmin::unlock_user_files(); &useradmin::made_changes(); print $text{'setup_done'},"

\n"; } else { %ginfo = %$ginfo; } if (!$uinfo) { # Create the Unix user # XXX use common function?? print &text('setup_user', $cruser),"
\n"; &useradmin::lock_user_files(); %uinfo = ( 'user', $cruser, 'uid', $uid, 'gid', $gid, 'pass', &useradmin::encrypt_password($in{'pass'}), 'real', $owner, 'home', $dom{'home'}, 'shell', $config{'unix_shell'} ); &set_pass_change(\%uinfo); &useradmin::set_user_envs(\%uinfo, 'CREATE_USER', $in{'pass'}, [ ]); &useradmin::making_changes(); &useradmin::create_user(\%uinfo); &useradmin::unlock_user_files(); &useradmin::made_changes(); &useradmin::unlock_user_files(); print $text{'setup_done'},"

\n"; if (!-d $uinfo{'home'}) { # Create his home directory, and copy files into it print $text{'setup_home'},"
\n"; &system_logged( "mkdir '$uinfo{'home'}'"); &system_logged( "chmod '$uconfig{'homedir_perms'}' '$uinfo{'home'}'"); &system_logged("chown $uid:$gid '$uinfo{'home'}'"); ©_skel_files($config{'virtual_skel'}, \%uinfo, $cruser); print $text{'setup_done'},"

\n"; } } else { %uinfo = %$uinfo; } # Setup web directories print $text{'import_dirs'},"
\n"; foreach $d ( [ $config{'html_dir'} || 'public_html', '755' ], [ 'cgi-bin', '755' ], [ 'logs', '755' ], [ 'homes', '755' ] ) { if (!-d "$uinfo{'home'}/$d->[0]") { &system_logged( "mkdir '$uinfo{'home'}/$d->[0]' 2>/dev/null"); &system_logged( "chmod $d->[1] '$uinfo{'home'}/$d->[0]'"); &system_logged( "chown $uid:$ugid '$uinfo{'home'}/$d->[0]'"); } } print $text{'setup_done'},"

\n"; # Create the domain details print $text{'setup_save'},"
\n"; &save_domain(\%dom); print $text{'setup_done'},"

\n"; # Create or update webmin user if ($in{'webmin'}) { &require_acl(); ($wuser) = grep { $_->{'name'} eq $cruser } &acl::list_users(); if ($wuser) { &modify_webmin(\%dom, \%dom); } else { &setup_webmin(\%dom); } &restart_webmin(); } # Add to this user's list of domains if needed if (!&can_edit_domain(\%dom)) { $access{'domains'} = join(" ", split(/\s+/, $access{'domains'}), $dom{'id'}); &save_module_acl(\%access); } &webmin_log("import", "domain", $dom{'dom'}); } else { # Just work out what can be done print "$text{'import_idesc'}

\n"; # Work out the Unix username if ($in{'user_def'}) { # Creating a new user with a name taken from the domain $in{'dom'} =~ /^([^\.]+)/; $try1 = $user = $1; if (defined(getpwnam($1)) || $config{'longname'}) { $user = $in{'dom'}; $try2 = $user; if (defined(getpwnam($user))) { &error_exit(&text('setup_eauto', $try1,$try2)); } } print "",&text('import_user1', "$user"),"

\n"; } else { # Using a specified name, which may or may not exist if (defined(getpwnam($in{'user'}))) { print "",&text('import_user2', "$in{'user'}"),"

\n"; } else { print "",&text('import_user3', "$in{'user'}"),"

\n"; } } if ($in{'group_def'}) { # Need to create new group with the same name as the user $group = $user || $in{'user'}; print "",&text('import_group1', "$group"),"

\n"; } else { # Using a specified group, which may or may not exist if (scalar(@ginfo = getgrnam($in{'group'}))) { print "",&text('import_group2', "$in{'group'}"),"

\n"; setpwent(); while(@muinfo = getpwent()) { $mcount++ if ($muinfo[3] == $ginfo[2]); } endpwent(); if ($mcount) { print "",&text('import_mailboxes', $mcount, "$in{'group'}"),"

\n"; } } else { print "",&text('import_group3', "$in{'group'}"),"

\n"; } } # Check for mail domain if ($config{'mail'}) { &require_mail(); $found{'mail'}++ if (&is_local_domain($in{'dom'})); if ($found{'mail'}) { print "",&text('import_mail', "$in{'dom'}"),"

\n"; } else { print &text('import_nomail', "$in{'dom'}"),"

\n"; } } # Check for an Apache virtualhost if ($config{'web'}) { &require_apache(); ($virt, $vconf) = &get_apache_virtual($in{'dom'}, $web_port); if ($virt) { $found{'web'}++; $sn = &apache::find_directive( "ServerName", $virt->{'members'}); $dr = &apache::find_directive( "DocumentRoot", $virt->{'members'}); print "",&text('import_web', "$sn", "$dr"),"

\n"; } else { print &text('import_noweb', "$in{'dom'}"),"

\n"; } } # Check for Webalizer on the virtual host logs if ($found{'web'}) { &require_webalizer(); $log = &get_apache_log($in{'dom'}); if ($log && -r &webalizer::config_file_name($log)) { $found{'webalizer'}++; print "",&text('import_webalizer', "$log"),"

\n"; } else { print &text('import_nowebalizer', "$log"),"

\n"; } } # Check for a DNS domain if ($config{'dns'}) { &require_bind(); $conf = &bind8::get_config(); @zones = &bind8::find("zone", $conf); foreach $v (&bind8::find("view", $conf)) { push(@zones, &bind8::find("zone", $v->{'members'})); } foreach $z (@zones) { if ($z->{'value'} eq $in{'dom'}) { $found{'dns'}++; last; } } if ($found{'dns'}) { print "",&text('import_dns', "$in{'dom'}"),"

\n"; } else { print &text('import_nodns', "$in{'dom'}"),"

\n"; } } if ($in{'db'}) { # Check for a MySQL database if ($config{'mysql'}) { &require_mysql(); @dbs = &mysql::list_databases(); $found{'mysql'}++ if (&indexof($in{'db'}, @dbs)>=0); if ($found{'mysql'}) { print "",&text('import_mysql', "$in{'db'}"),"

\n"; } else { print &text('import_nomysql', "$in{'db'}"),"

\n"; } } # Check for a PostgreSQL database if ($config{'postgres'}) { &require_postgres(); @dbs = &postgresql::list_databases(); $found{'postgres'}++ if (&indexof($in{'db'}, @dbs)>=0); if ($found{'postgres'}) { print "",&text('import_postgres', "$in{'db'}"),"

\n"; } else { print &text('import_nopostgres', "$in{'db'}"),"

\n"; } } } else { print $text{'import_nodb'},"

\n"; } # Tell if a Webmin user will be created if ($in{'webmin'}) { &require_acl(); ($wuser) = grep { $_->{'name'} eq ($user || $in{'user'}) } &acl::list_users(); if ($wuser) { print "",&text('import_webmin1', "$wuser->{'name'}"),"

\n"; } else { print "",&text('import_webmin2', "$wuser->{'name'}"),"

\n"; } } else { print "$text{'import_nowebmin'}

\n"; } # Work out if IP would be assigned if ($in{'virt'}) { print "",&text('import_virt', "$iface->{'fullname'}"),"

\n"; } else { print "$text{'import_novirt'}

\n"; } # Output form with confirm button print &check_clicks_function(); print "

\n"; foreach $i (keys %in) { print "\n"; } foreach $f (keys %found) { print "\n"; } print "\n"; print "\n"; print "$text{'import_rusure'}

\n"; print "\n"; print "

\n"; } print "
\n"; &footer("", $text{'index_return'}); sub error_exit { print "",$text{'import_err'}," : ",@_,"

\n"; print "


\n"; &footer("", $text{'index_return'}); exit; } virtual-server/defaultacl0100664000567100000120000000006207740742615015574 0ustar jcameronwheeledit=1 create=1 import=1 domains=* stop=1 local=1 virtual-server/acl_security.pl0100644000567100000120000000273210007630566016563 0ustar jcameronwheel require 'virtual-server-lib.pl'; # acl_security_form(&options) # Output HTML for editing security options for the virtual server module sub acl_security_form { print " $text{'acl_domains'}\n"; printf " %s\n", $_[0]->{'domains'} eq '*' ? "checked" : "", $text{'acl_all'}; printf " %s
\n", $_[0]->{'domains'} eq '*' ? "" : "checked", $text{'acl_sel'}; local %doms = map { $_, 1 } split(/\s+/, $_[0]->{'domains'}); print "\n"; foreach $q ('create', 'import', 'edit', 'local', 'stop') { print "",$text{'acl_'.$q},"\n"; printf " %s\n", $q, $_[0]->{$q} ? "checked" : "", $text{'yes'}; printf " %s \n", $q, $_[0]->{$q} ? "" : "checked", $text{'no'}; } } # acl_security_save(&options) # Parse the form for security options for the useradmin module sub acl_security_save { $_[0]->{'domains'} = $in{'domains_def'} ? "*" : join(" ", split(/\0/, $in{'domains'})); $_[0]->{'create'} = $in{'create'}; $_[0]->{'import'} = $in{'import'}; $_[0]->{'edit'} = $in{'edit'}; $_[0]->{'local'} = $in{'local'}; $_[0]->{'stop'} = $in{'stop'}; } virtual-server/config-freebsd0100664000567100000120000000227710036163320016335 0ustar jcameronwheelmail_system=3 mail=1 web=1 dns=1 mysql=1 webalizer=1 iface= shell=/dev/null ftp_shell=/bin/false unix_shell=/bin/sh append=1 append_style=1 longname=0 virtual_skel=/etc/skel quotas=1 avail_file=1 avail_passwd=1 avail_proc=1 avail_cron=1 avail_at=1 avail_telnet=1 avail_custom=0 avail_updown=0 avail_mailboxes=1 avail_htaccess-htpasswd=1 display_max=100 postgres=0 avail_change-user=1 apache_config=ServerName ${DOM} ServerAlias www.${DOM} DocumentRoot ${HOME}/public_html ErrorLog ${HOME}/logs/error_log CustomLog ${HOME}/logs/access_log common ScriptAlias /cgi-bin/ ${HOME}/cgi-bin/ Options Indexes IncludesNOEXEC FollowSymLinks domain_template=none user_template=none local_template=none suexec=1 edit_afiles=1 edit_homes=0 alias_types=1,2,3,4,5,6,7 disable=unix,mail,web,dns,mysql,postgres delete_indom=0 webmin_theme=* leave_acl=1 hard_quotas=0 proxy_pass=0 show_features=0 webmin=1 ssl=0 edit_ftp=1 edit_quota=1 post_check=1 generics=0 all_namevirtual=0 backup_feature_virtualmin=1 backup_feature_unix=1 backup_feature_mail=1 backup_feature_web=1 backup_feature_webalizer=1 backup_feature_ssl=1 backup_feature_dns=1 backup_feature_mysql=1 backup_feature_postgres=1 virtual-server/create-domain.pl0100775000567100000120000001456710036240627016620 0ustar jcameronwheel#!/usr/local/bin/perl # create-domain.pl # Adds a new virtual host, based on command-line parameters $no_acl_check++; $ENV{'WEBMIN_CONFIG'} ||= "/etc/webmin"; $ENV{'WEBMIN_VAR'} ||= "/var/webmin"; if ($0 =~ /^(.*\/)[^\/]+$/) { chdir($1); } chop($pwd = `pwd`); $0 = "$pwd/create-domain.pl"; require './virtual-server-lib.pl'; $< == 0 || die "create-domain.pl must be run as root"; &require_apache(); &require_bind(); &require_useradmin(); &require_mail(); &require_mysql(); &require_acl(); $first_print = \&first_text_print; $second_print = \&second_text_print; # Parse command-line args $name = 1; $virt = 0; while(@ARGV > 0) { local $a = shift(@ARGV); if ($a eq "--domain") { $domain = lc(shift(@ARGV)); } elsif ($a eq "--desc") { $owner = shift(@ARGV); } elsif ($a eq "--email") { $email = shift(@ARGV); } elsif ($a eq "--user") { $user = lc(shift(@ARGV)); } elsif ($a eq "--pass") { $pass = shift(@ARGV); } elsif ($a eq "--quota") { $quota = shift(@ARGV); } elsif ($a eq "--uquota") { $uquota = shift(@ARGV); } elsif ($a =~ /^--(\S+)$/ && &indexof($1, @features) >= 0) { $config{$1} || die "The $a option cannot be used unless the feature is enabled in the module configuration"; $feature{$1}++; } elsif ($a eq "--ip") { $ip = shift(@ARGV); if (!$config{'all_namevirtual'}) { $feature{'virt'} = 1; # for dependency checks $virt = 1; } $name = 0; } elsif ($a eq "--mailboxlimit") { $mailboxlimit = shift(@ARGV); } else { &usage(); } } $feature{'unix'} = 1; # always enabled # Make sure all needed args are set $domain && $pass || &usage(); if ($config{'home_quotas'}) { $quota && $uquota || &usage(); } # Validate args and work out defaults for those unset $domain =~ /^[A-Za-z0-9\.\-]+$/ || die($text{'setup_edomain'}); foreach $d (&list_domains()) { die($text{'setup_edomain2'}) if (lc($d->{'dom'}) eq lc($domain)); } if (!$user) { $domain =~ /^([^\.]+)/; $try1 = $user = $1; if (defined(getpwnam($1)) || $config{'longname'}) { $user = $domain; $try2 = $user; if (defined(getpwnam($user))) { die(&text('setup_eauto', $try1, $try2)); } } } else { $user =~ /^[^\t :]+$/ || die($text{'setup_euser2'}); defined(getpwnam($user)) && die($text{'setup_euser'}); } $owner ||= $domain; !defined($mailboxlimit) || $mailboxlimit =~ /^[1-9]\d*$/ || die($text{'setup_emailboxlimit'}); # Validate username if (defined(&useradmin::check_username_restrictions)) { $uerr = &useradmin::check_username_restrictions($user); if ($uerr) { die(&text('setup_eusername', $user, $uerr)); } } $user =~ /^[a-zA-z]/ || die(&text('setup_eusername2', $user)); # Work out group name $home_base || die($text{'setup_ehomebase'}); if ($config{'home_quotas'}) { $quota =~ /^\d+$/ || die($text{'setup_equota'}); $uquota =~ /^\d+$/ || die($text{'setup_euquota'}); } ($db = $user) =~ s/[\.\-]/_/g; # Check for various clashes my $f; foreach $f (@features) { if ($feature{$f}) { local $cfunc = "check_${f}_clash"; if (&$cfunc($domain, $db, $user)) { die(&text('setup_e'.$f, $domain, $db, $user)); } } } # Check for feature dependencies foreach $f (@features) { if ($feature{$f}) { local $fd; foreach $fd (@{$feature_depends{$f}}) { die(&text('setup_edep'.$f)) if (!$feature{$fd}); } } } $defip = &get_default_ip(); if ($config{'all_namevirtual'}) { # Make sure the IP *is* assigned &check_ipaddress($ip) || die($text{'setup_eip'}); if (!&check_virt_clash($ip)) { die(&text('setup_evirtclash2')); } } elsif ($virt) { # Make sure the IP isn't assigned yet &check_ipaddress($ip) || die($text{'setup_eip'}); if (&check_virt_clash($ip)) { die(&text('setup_evirtclash')); } } print "Beginning domain creation ..\n\n"; # Work out user and group IDs &build_group_taken(\%gtaken, \%ggtaken); $gid = &allocate_gid(\%gtaken); $ugid = $gid; &build_taken(\%taken, \%utaken); $uid = &allocate_uid(\%taken); # Build up domain object %dom = ( 'id', &domain_id(), 'dom', $domain, 'user', $user, 'group', $user, 'ugroup', $user, 'quota', $quota, 'uquota', $uquota, 'uid', $uid, 'gid', $gid, 'ugid', $gid, 'owner', $owner, 'email', $email, 'name', $name, 'ip', $config{'all_namevirtual'} ? $ip : $virt ? $ip : $defip, 'virt', $virt, 'pass', $pass, 'db', $db, 'mailboxlimit', $mailboxlimit, 'source', 'create-domain.pl' ); foreach $f (@features) { $dom{$f} = $feature{$f}; } # Work out home directory $dom{'home'} = &server_home_directory(\%dom); # Run the before command &set_domain_envs(\%dom, "CREATE_DOMAIN"); $merr = &making_changes(); if (defined($merr)) { print "Before creation command failed : $merr\n"; exit 1; } # Set up all the selected features foreach $f (@features) { if ($feature{$f}) { local $sfunc = "setup_$f"; &$sfunc(\%dom); } } # Add virtual IP address, if needed if ($virt) { &setup_virt(\%dom); } # Save domain details print $text{'setup_save'},"\n"; &save_domain(\%dom); print $text{'setup_done'},"\n\n"; # Notify the owner via email &send_domain_email(\%dom); # Run the after creation command &made_changes(); print "All done!\n"; sub usage { print "Adds a new Virtualmin virtual server, with the settings and features\n"; print "specified on the command line.\n"; print "\n"; print "usage: create-domain.pl --domain domain.name\n"; print " --pass password-for-unix-user\n"; print " [--desc description-for-domain]\n"; print " [--email contact-email]\n"; print " [--user new-unix-user]\n"; print " [--mail]\n"; print " [--web]\n"; print " [--webalizer]\n"; print " [--ssl]\n"; print " [--dns]\n"; print " [--mysql]\n"; print " [--postgres]\n"; print " [--webmin]\n"; print " [--ip virtual.ip.address]\n"; print " [--mailboxlimit boxes]\n"; if ($config{'home_quotas'}) { print " --quota quota-for-domain]\n"; print " --uquota quota-for-unix-user]\n"; } exit(1); } virtual-server/import_form.cgi0100775000567100000120000000544610011573426016567 0ustar jcameronwheel#!/usr/local/bin/perl # import_form.cgi # Display a form for importing an existing mail domain, dns zone, apache # virtual host and mysql database so that they can be controlled by this module. require './virtual-server-lib.pl'; $access{'create'} && $access{'import'} || &error($text{'import_ecannot'}); &header($text{'import_title'}, ""); print "
\n"; print "$text{'import_desc1'}

\n"; print "$text{'import_desc2'}

\n"; print "$text{'import_desc3'}

\n"; print "

\n"; print "\n"; print "\n"; print "
$text{'import_header'}
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; $defip = &get_default_ip(); print "\n"; print "\n"; print "\n"; print "\n"; if ($config{'home_quotas'}) { print "\n"; @defquota = split (/ /,$config{'defquota'}); if ( !@defquota or $#defquota eq 0 ) { print "\n"; } else { print "\n"; } print "\n"; } print "
$text{'import_dom'}
$text{'import_user'} \n"; print " $text{'import_ucr'}
\n"; print " $text{'import_uex'}\n"; print &unix_user_input("user"),"
$text{'import_group'} \n"; print " $text{'import_gdf'}
\n"; print " $text{'import_gex'}\n"; print &unix_group_input("group"),"
$text{'import_pass'}
$text{'import_webmin'} $text{'yes'}\n"; print " $text{'no'}$text{'import_db'}
$text{'import_ip'}$text{'import_hasvirt'} $text{'yes'}"; print " $text{'no'}
$text{'form_quota'}","a_input("quota", $config{'defquota'}, $config{'home_quotas'}),"\n"; print "a_input("otherquota", "", $config{'home_quotas'}),"
\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/config.info.fr0100644000567100000120000000611107741463016016270 0ustar jcameronwheelline1=Paramètres du serveur,11 mail=Configuration de boites aux lettres et alias activés?,1,1-Oui,0-Non web=Installation et configuration d'Apache activée?,1,1-Oui,0-Non dns=Installation et configuration de BIND activée?,1,1-Oui,0-Non mysql=Installation et configuration de MySQL activée?,1,1-Oui,0-Non postgres=Installation et configuration de PostgreSQLactivée?,1,1-Oui,0-Non webalizer=Génération de rapports Webalizer activée?,1,1-Oui,0-Non mail_system=Serveur de messagerie a configurer,1,1-Sendmail,0-Postfix,3-Détecter automatiquement quotas=Configuration de quotas pour les domaines et utilisateurs de messagerie?,1,1-Oui (si activé),0-Non iface=Carte réseau pour les adresses virtuelles,0,6 defip=Adresse IP par défaut pour un serveur virtuel,3,Sur l'interface réseau display_max=Nombre maximum de domaines a afficher,3,Illimité line2=Paramètres par défaut pour les nouveaux domaines,11 shell=Shell pour les boites aux lettres,0 ftp_shell=Shell pour les utilisateurs FTP,0 unix_shell=Shell pour les utilisateurs responables d'un domaine,0 append=Inclure le nom de domaine dans les noms d'utilisateurs?,1,1-Toujours,0-Seulement pour éviter un doublon append_style=Le format pour les noms d'utilisateurs incluant le nom de domaine,4,0-nom_utilisateur.domaine,2-domaine.nom_utilisateur,1-nom_utilisateur-domaine,3-domaine-nom_utilisateur longname=Type de nom de domaine dans les noms d'utilisateurs,1,1-Nom de domaine complet,0-Premiere partie du nom de domaine localgroup=Groupe primaire pour les utilisateurs locaux,3,Ne pas afficher les utilisateurs locaux defuquota=Quota par defaut des utilisateurs unix pour un nouveau serveur virtuel,0,8,,blocs defmquota=Quota par defaut pour les nouvelles boites aux lettres,0,8,,blocs defquota=Quota par defaut pour les nouveaux serveurs,0,8,,blocs virtual_skel=Répertoire initial pour les fichiers d'un utilisateur d'un serveur virtuel,3,Aucun local_skel=Répertoire initial pour les fichiers d'un utilisateur local,3,Aucun mail_skel=Répertoire initial pour les fichiers d'un utilisateur de messagerie,3,Aucun line3=Modules supplémentaires disponibles pour les utilisateurs propriétaires de domaines,11 avail_file=Gestionnaire de fichiers (répertoire utilisateur seulement),1,1-Oui,0-Non avail_passwd=Changement de mot de passe (mot de passe de l'utilisateur seulement),1,1-Oui,0-Non avail_proc=Processus exécutés (processus de l'utilisateur seulement),1,1-Oui,0-Non avail_cron=Taches planifiées (taches de l'utilisateur seulement),1,1-Oui,0-Non avail_at=Commandes planifiées (commandes de l'utilisateur seulement),1,1-Oui,0-Non avail_telnet=Connexion SSH/Telnet,1,1-Oui,0-Non avail_webalizer=Analyse de logs Webalizer (logs du site web seulement),1,1-Oui,0-Non avail_updown=Envoi et téléchargement de fichiers (en tant qu'utilisateur),1,1-Oui,0-Non avail_change-user=Changer la langue et le thème,1,1-Oui,0-Non avail_custom=Commandes personalisées,1,1-Oui,0-Non virtual-server/search.cgi0100775000567100000120000000115610007630566015475 0ustar jcameronwheel#!/usr/local/bin/perl # search.cgi # Display domains matching some search require './virtual-server-lib.pl'; &ReadParse(); # Do the search foreach $d (&list_domains()) { next if (!&can_edit_domain($d)); if ($d->{$in{'field'}} =~ /\Q$in{'what'}\E/i) { push(@doms, $d); } } &header($text{'search_title'}, ""); print "
\n"; if (!@doms) { print "",&text('search_none', "$in{'what'}"),"

\n"; } else { print "",&text('search_results', "$in{'what'}", scalar(@doms)),"

\n"; &domains_table(\@doms); print "

\n"; } print "


\n"; &footer("", $text{'index_return'}); virtual-server/config.info.de0100755000567100000120000000604707741462764016275 0ustar jcameronwheel# config.info.de-File for Virtualmin Virtuelle Server ###################################################################### # Last patched: 05.08.2003 Martin Mewes for WEBMIN - MM # Questions, comments, snide-remarks: webmin@webmin.mamemu.de ###################################################################### line1=Server-Einstellungen,11 mail=Mailbox- und Mailalias-Konfiguration aktiviert??,1,1-Ja,0-Nein web=Apache-Setup und Konfiguration aktiviert??,1,1-Ja,0-Nein dns=BIND-Setup und Konfiguration aktiviert?,1,1-Ja,0-Nein mysql=MySQL-Setup und Konfiguration aktiviert?,1,1-Ja,0-Nein postgres=PostgreSQL-Setup und Konfiguration aktiviert?,1,1-Ja,0-Nein webalizer=Webalizer-Reports aktiviert?,1,1-Ja,0-Nein mail_system=Konfigurierbarer Mail-Server:,1,1-Sendmail,0-Postfix,3-Automatisch finden quotas=Quota-Setup für Domainen und eMail-Benutzer?,1,1-Ja (wenn eingeschaltet),0-Nein iface=Netzwerkschnittstelle für virtuelle Adressen,3,Automatisch finden defip=Standard-IP-Addresse für Virtuelle Server,3,von der Netzwerkschnittstelle beziehen display_max=Maximale Anzahl von Domainen in der Anzeige:,3,Unbegrenzt line2=Standardeinstellungen für neue Domainen,11 shell=Unix-Shell der Mailbox-Benutzer,0 ftp_shell=Unix-Shell der FTP-Benutzer,0 unix_shell=Unix-Shell der Domainen-Benutzer,0 append=Domainen in Benutzernamen angeben?,1,1-Immer,0-Nur um Fehler zu vermeiden append_style=Format der Benutzernamen mit Domainen,4,0-Benutzername.Domain,2-Domain.Benutzername,1-Benutzername-Domain,3-Domain-Benutzername longname=Format der Domaine in Benutzernamen,1,1-Voller Domain-Name,0-Erster Teil der Domaine localgroup=Primäre Gruppe der lokalen Benutzer,3,Keine lokalen Benutzer anzeigen defuquota=Standard-Quota der neuen Unix-Benutzer,0,8,,Blöcke defmquota=Stardard-Quota der neuen Mail-Boxen,0,8,,Blöcke defquota=Standard-Quota der neuen Server,0,8,,Blöcke virtual_skel=Standard-Verzeichnis der Benutzer von virtuellen Servern,3,None local_skel=Standard-Verzeichnis der lokalen Benutzer,3,None mail_skel=Standard-Verzeichnis der Mail-Benutzer,3,None line3=Zusätzliche Module der Domainen-Inhaber,11 avail_file=Datei-Manager (nur Home-Verzeichnis),1,1-Ja,0-Nein avail_passwd=Passwort ändern (nur Benutzerpassworte),1,1-Ja,0-Nein avail_proc=Prozesse starten (nur Benutzerprozesse),1,1-Ja,0-Nein avail_cron=Cron-Jobs einrichten (nur Benutzer-Cron-Jobs),1,1-Ja,0-Nein avail_at=At-Jobs einrichten (nur Benutzer-At-Jobs),1,1-Ja,0-Nein avail_telnet=SSH/Telnet-Login aktivieren?,1,1-Ja,0-Nein avail_updown=Upload und Download von Dateien (als Benutzer),1,1-Ja,0-Nein avail_change-user=Webmin-Dekoration modifizieren,1,1-Ja,0-Nein avail_custom=Spezielle Kommandos,1,1-Ja,0-Nein # New 05.08.2003 apache_config=Apache-Direktiven für neue Webseiten.
$HOME - Benutzer-Home-Verzeichnis
$DOM - Domain-Name
$USER - Benutzername,9,0,0,\t mx_server=MX-Record Servers für "Non-Mail"-Domainen,0,40 # Missing in original 05.08.2003 - left in for backward compability avail_webalizer=Webalizer aktivieren? (Webstatistiken),1,1-Ja,0-Neinvirtual-server/delete_domain.cgi0100775000567100000120000000567710041665657017044 0ustar jcameronwheel#!/usr/local/bin/perl # delete_domain.cgi # Delete a domain, after asking first require './virtual-server-lib.pl'; &require_bind() if ($config{'dns'}); &require_useradmin(); &require_mail() if ($config{'mail'}); &ReadParse(); $d = &get_domain($in{'dom'}); $d && $d->{'uid'} && $d->{'gid'} || &error("Domain $in{'dom'} does not exist!"); $access{'edit'} && &can_edit_domain($d) || &error($text{'edit_ecannot'}); if ($in{'confirm'}) { $| = 1; $theme_no_table++; } &header($text{'delete_title'}, ""); print "
\n"; @users = &list_domain_users($d); @aliases = &list_domain_aliases($d); if (!$in{'confirm'}) { # Ask the user if he is sure print &check_clicks_function(); $sz = &disk_usage_kb($d->{'home'}); print "

",&text('delete_rusure2', "$d->{'dom'}", &nice_size($sz*1024)),"

\n"; print "

    \n"; foreach $f (@features) { if ($d->{$f} && ($config{$f} || $f eq 'unix')) { print "
  • ",$text{'feature_'.$f}," - ", $text{'losing_'.$f},"
    \n"; } } if (@users || @aliases) { print "
  • ",&text('delete_mailboxes', scalar(@users), scalar(@aliases)),"
    \n"; } print "
\n"; print "
\n"; print "\n"; print "\n"; print "

", "$text{'delete_only'}
\n"; print "

\n"; print "
\n"; &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); } else { # Go ahead and delete .. # Run the before command &set_domain_envs($d, "DELETE_DOMAIN"); $merr = &making_changes(); &error(&text('delete_emaking', "$merr")) if (defined($merr)); # Delete domain file print $text{'delete_domain'},"
\n"; &delete_domain($d); print $text{'setup_done'},"

\n"; if (!$in{'only'}) { if (@users) { # Delete mail users and their mail files print $text{'delete_users'},"
\n"; foreach $u (@users) { &delete_user($u); &delete_mail_file($u); &system_logged("rm -rf '$u->{'home'}'") if (-d $u->{'home'} && $u->{'home'} ne "/"); } print $text{'setup_done'},"

\n"; } # Delete all virtusers if (@users || @aliases) { print $text{'delete_aliases'},"
\n"; foreach $v (&list_virtusers()) { if ($v->{'from'} =~ /\@(\S+)$/ && $1 eq $d->{'dom'}) { &delete_virtuser($v); } } print $text{'setup_done'},"

\n"; } # Take down IP if ($d->{'iface'}) { &delete_virt($d); } } # Delete all features (or just 'webmin' if un-importing) my $f; foreach $f ($in{'only'} ? ( "webmin" ) : reverse(@features)) { if ($config{$f} && $d->{$f} || $f eq 'unix') { local $dfunc = "delete_$f"; &$dfunc($d); } } # Run the after command &made_changes(); &webmin_log("delete", "domain", $d->{'dom'}, $d); print "


\n"; &footer("", $text{'index_return'}); } virtual-server/enable_domain.cgi0100775000567100000120000000404710017546131017002 0ustar jcameronwheel#!/usr/local/bin/perl # enable_domain.cgi # Undo the disabling of a domain require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); $access{'edit'} && &can_edit_domain($d) || &error($text{'edit_ecannot'}); $d->{'disabled'} || &error($text{'enable_ealready'}); if ($in{'confirm'}) { $| = 1; $theme_no_table++; } &header($text{'enable_title'}, ""); print "
\n"; # Work out what can be enabled @enable = grep { $d->{$_} && $config{$_} || $_ eq 'unix' } split(/,/, $d->{'disabled'}); push(@enable, "ssl") if (&indexof("web", @enable) >= 0); if (!$in{'confirm'}) { # Ask the user if he is sure @distext = map { $text{"disable_f".$_} } @enable; if (@distext == 1) { $distext = $distext[0]; } elsif (@distext == 2) { $distext = &text('disable_and', $distext[0], $distext[1]); } else { $dislast = pop(@distext); $distext = &text('disable_and', join(", ", @distext), $dislast); } print &check_clicks_function(); print "

",&text('enable_rusure2', "$d->{'dom'}", $distext),"

\n"; print "

\n"; print "\n"; print "\n"; print "
\n"; } else { # Go ahead and do it %enable = map { $_, 1 } @enable; # Run the before command &set_domain_envs($d, "ENABLE_DOMAIN"); $merr = &making_changes(); &error(&text('enable_emaking', "$merr")) if (defined($merr)); # Enable all disabled features my $f; foreach $f (@features) { if ($d->{$f} && $enable{$f}) { local $efunc = "enable_$f"; &$efunc($d); } } # Save new domain details print $text{'save_domain'},"
\n"; delete($d->{'disabled'}); &save_domain($d); print $text{'setup_done'},"

\n"; # Run the after command &set_domain_envs($d, "ENABLE_DOMAIN"); &made_changes(); &webmin_log("enable", "domain", $d->{'dom'}, $d); } print "


\n"; &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); virtual-server/disable_domain.cgi0100775000567100000120000000436010017546131017155 0ustar jcameronwheel#!/usr/local/bin/perl # disable_domain.cgi # Temporarily disable a domain, after asking first require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); $access{'edit'} && &can_edit_domain($d) || &error($text{'edit_ecannot'}); $d->{'disabled'} && &error($text{'disable_ealready'}); if ($in{'confirm'}) { $| = 1; $theme_no_table++; } &header($text{'disable_title'}, ""); print "
\n"; # Work out what can be disabled @disable = grep { $d->{$_} && $config{$_} || $_ eq 'unix' } split(/,/, $config{'disable'}); push(@disable, "ssl") if (&indexof("web", @disable) >= 0); if (!@disable) { # Nothing to do! print "

$text{'disable_nothing'}

\n"; } elsif (!$in{'confirm'}) { # Ask the user if he is sure @distext = map { $text{"disable_f".$_} } @disable; if (@distext == 1) { $distext = $distext[0]; } elsif (@distext == 2) { $distext = &text('disable_and', $distext[0], $distext[1]); } else { $dislast = pop(@distext); $distext = &text('disable_and', join(", ", @distext), $dislast); } print &check_clicks_function(); print "

",&text('disable_rusure2', "$d->{'dom'}", $distext),"

\n"; print $text{'disable_undo'},"

\n"; print "

\n"; print "\n"; print "\n"; print "
\n"; } else { # Go ahead and do it .. %disable = map { $_, 1 } @disable; # Run the before command &set_domain_envs($d, "DISABLE_DOMAIN"); $merr = &making_changes(); &error(&text('disable_emaking', "$merr")) if (defined($merr)); # Disable all configured features my $f; foreach $f (@features) { if ($d->{$f} && $disable{$f}) { local $dfunc = "disable_$f"; &$dfunc($d); push(@disabled, $f); } } # Save new domain details print $text{'save_domain'},"
\n"; $d->{'disabled'} = join(",", @disabled); &save_domain($d); print $text{'setup_done'},"

\n"; # Run the after command &set_domain_envs($d, "DISABLE_DOMAIN"); &made_changes(); &webmin_log("disable", "domain", $d->{'dom'}, $d); } print "


\n"; &footer("edit_domain.cgi?dom=$in{'dom'}", $text{'edit_return'}, "", $text{'index_return'}); virtual-server/useradmin_update.pl0100664000567100000120000000257310007630566017433 0ustar jcameronwheel do 'virtual-server-lib.pl'; # useradmin_create_user(&details) # Does nothing sub useradmin_create_user { } # useradmin_delete_user(&details) # Does nothing (though maybe could delete the domain) sub useradmin_delete_user { } # useradmin_modify_user(&details) # If the domain user's password is being changed, update it in the domain's # file as well sub useradmin_modify_user { if ($_[0]->{'passmode'} == 3) { local @doms = &list_domains(); local ($d) = grep { $_->{'user'} eq $_[0]->{'user'} } @doms; if ($d) { # User is for a virtualmin domain $first_print = $second_print = \&null_print; $oldd = { %$d }; $d->{'pass'} = $_[0]->{'plainpass'}; if ($d->{'disabled'}) { # Clear any saved passwords, as they should # be reset at this point $d->{'disabled_oldpass'} = $_[0]->{'pass'}; $d->{'disabled_mysqlpass'} = undef; $d->{'disabled_postgrespass'} = undef; } if ($d->{'mysql'} && $config{'mysql'}) { &require_mysql(); if (!$mconfig{'sync_modify'}) { # Need to update password in MySQL db as well &modify_mysql($d, $oldd); } } if ($d->{'postgres'} && $config{'postgres'}) { &require_postgres(); if (!$qconfig{'sync_modify'}) { # Need to update password in PostgreSQL db too &modify_postgres($d, $oldd); } } &modify_webmin($d, $oldd); # so that acl passwords are updated &save_domain($d); } } } sub null_print { } virtual-server/domain-template0100664000567100000120000000175307716455150016556 0ustar jcameronwheelThe following virtual server has been set up successfully : Domain name: ${DOM} Hosting server: ${HOSTNAME} ${IF-IFACE} Virtual IP address: ${IP} ${ENDIF-IFACE} Administration login: ${USER} Administration password: ${PASS} ${IF-WEBMIN} Administration URL: http://www.${DOM}:10000/ ${ENDIF-WEBMIN} ${IF-WEB} Website: http://www.${DOM}/ ${IF-WEBALIZER} Webalizer log reporting: Enabled ${ELSE-WEBALIZER} Webalizer log reporting: Disabled ${ENDIF-WEBALIZER} ${ENDIF-WEB} ${IF-MAIL} Email domain: ${DOM} SMTP server: mail.${DOM} POP3 server: mail.${DOM} ${ENDIF-MAIL} ${IF-DNS} DNS domain: ${DOM} Nameserver: ${HOSTNAME} ${ENDIF-DNS} ${IF-MYSQL} MySQL database: ${DB} MySQL login: ${USER} MySQL password: ${PASS} ${ENDIF-MYSQL} ${IF-POSTGRES} PostgreSQL database: ${DB} PostgreSQL login: ${USER} PostgreSQL password: ${PASS} ${ENDIF-POSTGRES} virtual-server/user-template0100664000567100000120000000057407716406541016265 0ustar jcameronwheelYour mailbox has been set up successfully as follows : Email address: ${MAILBOX}@${DOM} POP3 login: ${USER} POP3 password: ${PLAINPASS} SMTP server: mail.${DOM} POP3 server: mail.${DOM} ${IF-FTP} FTP login: Enabled Home directory: ${HOME} ${ELSE-FTP} FTP login: Disabled ${ENDIF-FTP} virtual-server/autoreply.pl0100775000567100000120000000713510007630566016130 0ustar jcameronwheel#!/usr/local/bin/perl # autoreply.pl # Simple autoreply script # read sendmail module config $p = -l $0 ? readlink($0) : $0; $p =~ /^(.*)\/[^\/]+$/; if (open(CONF, "$1/config")) { while() { if (/^(\S+)=(.*)/) { $config{$1} = $2; } } close(CONF); } if (!$config{'sendmail_path'}) { # Make some guesses about sendmail if (-x "/usr/sbin/sendmail") { %config = ( 'sendmail_path' => '/usr/sbin/sendmail' ); } elsif (-x "/usr/lib/sendmail") { %config = ( 'sendmail_path' => '/usr/lib/sendmail' ); } else { die "Failed to find sendmail or config file"; } } # read headers and body while() { s/\r|\n//g; if (/^(\S+):\s+(.*)/) { $header{lc($1)} = $2; $lastheader = lc($1); } elsif (/^\s+(.*)/ && $lastheader) { $header{$lastheader} .= $_; } elsif (!$_) { last; } } while() { $body .= $_; } if ($header{'x-webmin-autoreply'}) { print STDERR "Cancelling autoreply to an autoreply\n"; exit 1; } if ($header{'x-mailing-list'} || $header{'list-id'} || $header{'precedence'} =~ /junk|bulk|list/i || $header{'to'} =~ /Multiple recipients of/i) { # Do nothing if post is from a mailing list exit 0; } if ($header{'from'} =~ /postmaster|mailer-daemon/i) { # Do nothing if post is a bounce exit 0; } # work out the correct to address @to = ( &split_addresses($header{'to'}), &split_addresses($header{'cc'}), &split_addresses($header{'bcc'}) ); $to = $to[0]->[0]; foreach $t (@to) { if ($t->[0] =~ /^([^\@\s]+)/ && $1 eq $ARGV[1]) { $to = $t->[0]; } } # build list of default reply headers $rheader{'From'} = $to; $rheader{'To'} = $header{'reply-to'} ? $header{'reply-to'} : $header{'from'}; $rheader{'Subject'} = "Autoreply to $header{'subject'}"; $rheader{'X-Webmin-Autoreply'} = 1; $rheader{'X-Originally-To'} = $header{'to'}; # read the autoreply file if (open(AUTO, $ARGV[0])) { while() { s/\$SUBJECT/$header{'subject'}/g; s/\$FROM/$header{'from'}/g; s/\$TO/$to/g; s/\$DATE/$header{'date'}/g; s/\$BODY/$body/g; if (/^(\S+):\s*(.*)/ && !$doneheaders) { $rheader{$1} = $2; } else { $rbody .= $_; $doneheaders = 1; } } close(AUTO); } else { $rbody = "Failed to open autoreply file $ARGV[0] : $!"; } # Open the replies tracking DBM, if one was set if ($rheader{'Reply-Tracking'}) { $track_replies = dbmopen(%replies, $rheader{'Reply-Tracking'}, 0700); } if ($track_replies) { # See if we have replied to this address before $period = $rheader{'Reply-Period'} || 60*60; ($from) = &split_addresses($header{'from'}); if ($from) { $lasttime = $replies{$from->[0]}; $now = time(); if ($now < $lasttime+$period) { # Autoreplied already in this period .. just halt exit(0); } $replies{$from->[0]} = $now; } } delete($rheader{'Reply-Tracking'}); delete($rheader{'Reply-Period'}); # run sendmail and feed it the reply open(MAIL, "|$config{'sendmail_path'} -t"); foreach $h (keys %rheader) { print MAIL "$h: $rheader{$h}\n"; } print MAIL "\n"; print MAIL $rbody; close(MAIL); # split_addresses(string) # Splits a comma-separated list of addresses into [ email, real-name ] pairs sub split_addresses { local (@rv, $str = $_[0]); while(1) { if ($str =~ /^[\s,]*(([^<>\(\)\s]+)\s+\(([^\(\)]+)\))(.*)$/) { push(@rv, [ $2, $3, $1 ]); $str = $4; } elsif ($str =~ /^[\s,]*("([^"]+)"\s+<([^\s<>]+)>)(.*)$/ || $str =~ /^[\s,]*(([^<>]+)\s+<([^\s<>]+)>)(.*)$/ || $str =~ /^[\s,]*(([^<>\[\]]+)\s+\[mailto:([^\s\[\]]+)\])(.*)$/|| $str =~ /^[\s,]*(()<([^\s<>]+)>)(.*)/ || $str =~ /^[\s,]*(()([^\s<>,]+))(.*)/) { push(@rv, [ $3, $2, $1 ]); $str = $4; } else { last; } } return @rv; } virtual-server/filter.pl0100775000567100000120000000354410007630566015371 0ustar jcameronwheel#!/usr/local/bin/perl # filter.pl # read sendmail module config $p = -l $0 ? readlink($0) : $0; $p =~ /^(.*)\/[^\/]+$/; if (open(CONF, "$1/config")) { while() { if (/^(\S+)=(.*)/) { $config{$1} = $2; } } close(CONF); } if (!$config{'sendmail_path'}) { # Make some guesses about sendmail if (-x "/usr/sbin/sendmail") { %config = ( 'sendmail_path' => '/usr/sbin/sendmail' ); } elsif (-x "/usr/lib/sendmail") { %config = ( 'sendmail_path' => '/usr/lib/sendmail' ); } else { die "Failed to find sendmail or config file"; } } # read headers and body $fromline = ; while() { $headers .= $_; s/\r|\n//g; if (/^(\S+):\s+(.*)/) { $header{lc($1)} = $2; } elsif (!$_) { last; } } while() { $body .= $_; } # read the filter file if (open(FILTER, $ARGV[0])) { while() { s/\r|\n//g; if (/^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) { push(@filter, [ $1, $2, $3, $4 ]); } elsif (/^(\S+)\s+(\S+)$/) { push(@filter, [ $1, $2 ]); } } close(FILTER); } else { print STDERR "Filter file $ARGV[0] does not exist!\n"; exit 1; } # run the filter to find the first matching rule open(LOG, ">>$ARGV[0].log"); foreach $f (@filter) { local $field = $f->[2] eq 'body' ? $body : $header{$f->[2]}; local $st = 0; if ($f->[0] == 0) { $st = ($field !~ /$f->[3]/i); } elsif ($f->[0] == 1) { $st = ($field =~ /$f->[3]/i); } elsif ($f->[0] == 2) { $st = 1; } if ($st) { # The rule matched! if ($f->[1] =~ /^\//) { # Write to a file open(MAIL, ">>$f->[1]") || die "Failed to open $f->[1] ; $!"; print MAIL $fromline; } else { # Forward to another address open(MAIL, "|$config{'sendmail_path'} ". quotemeta($f->[1])); } print MAIL $headers; print MAIL $body; close(MAIL); $now = localtime(time()); print LOG "[$now] [$header{'from'}] [",join(" ",@$f),"]\n"; last; } } virtual-server/RELEASE0100664000567100000120000000017610042122701014527 0ustar jcameronwheel x Create tar.gz file x Upload to sourceforge - Add the freshmeat.net - Announce on mailing list x Add to updates.txt virtual-server/save_afile.cgi0100775000567100000120000000126510017553050016320 0ustar jcameronwheel#!/usr/local/bin/perl # save_afile.cgi # Save an addresses file require './virtual-server-lib.pl'; &ReadParseMime(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); $config{'edit_afiles'} || $master_admin || &error($text{'afile_ecannot'}); &switch_to_domain_user($d); $in{'text'} =~ s/\r//g; $in{'text'} =~ s/\n*$/\n/; &lock_file($in{'file'}); open(FILE, ">$in{'file'}") || &error(&text('afile_ewrite', $in{'file'}, $dom->{'user'}, $!)); print FILE $in{'text'}; close(FILE); &unlock_file($in{'file'}); &webmin_log("save", "afile", $in{'file'}); $what = $in{'alias'} ? 'alias' : 'user'; &redirect("edit_$what.cgi?$what=$in{$what}&dom=$in{'dom'}"); virtual-server/edit_afile.cgi0100775000567100000120000000231210012273042016274 0ustar jcameronwheel#!/usr/local/bin/perl # edit_afile.cgi # Display the contents of an address file require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); $config{'edit_afiles'} || $master_admin || &error($text{'afile_ecannot'}); &header($text{'afile_title'}, ""); print "
\n"; &switch_to_domain_user($d); if (-e $in{'file'}) { open(FILE, $in{'file'}) || &error(&text('afile_eread', $in{'file'}, $d->{'user'}, $!)); @lines = ; close(FILE); } print "",&text('afile_desc', "$in{'file'}"),"

\n"; $what = $in{'alias'} ? 'alias' : 'user'; print "

\n"; print "\n"; print "\n"; print "\n"; print "

\n"; print " ", "\n"; print "

\n"; print "
\n"; &footer("edit_$what.cgi?dom=$in{'dom'}&$what=$in{$what}", $text{$what.'_return'}); virtual-server/edit_rfile.cgi0100775000567100000120000000412010012273140016313 0ustar jcameronwheel#!/usr/local/bin/perl # edit_rfile.cgi # Display the contents of an autoreply file require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); $config{'edit_afiles'} || $master_admin || &error($text{'rfile_ecannot'}); &header($text{'rfile_title'}, ""); print "
\n"; &switch_to_domain_user($d); if (-e $in{'file'}) { open(FILE, $in{'file'}) || &error(&text('rfile_eread', $in{'file'}, $d->{'user'}, $!)); while() { if (/^Reply-Tracking:\s*(.*)/) { $replies = $1; } elsif (/^Reply-Period:\s*(.*)/) { $period = $1; } else { push(@lines, $_); } } close(FILE); } print &text('rfile_desc', "$in{'file'}"),"

\n"; print "$text{'rfile_desc2'}

\n"; $what = $in{'alias'} ? 'alias' : 'user'; print "

\n"; print "\n"; print "\n"; print "\n"; print "

\n"; print $text{'rfile_replies'},"\n"; printf " %s\n", $replies eq '' ? "checked" : "", $text{'rfile_none'}; printf " %s\n", $replies eq '' ? "" :"checked", $text{'rfile_file'}; printf " %s
\n", $replies, &file_chooser_button("replies"); print " " x 3; print $text{'rfile_period'},"\n"; printf " %s\n", $period eq '' ? "checked" : "", $text{'rfile_default'}; printf "\n", $period eq '' ? "" :"checked"; printf " %s

\n", $period, $text{'rfile_secs'}; print " ", "\n"; print "

\n"; print "
\n"; &footer("edit_$what.cgi?dom=$in{'dom'}&$what=$in{$what}", $text{$what.'_return'}); virtual-server/save_rfile.cgi0100775000567100000120000000173310017554154016347 0ustar jcameronwheel#!/usr/local/bin/perl # save_rfile.cgi # Save an autoreply file require './virtual-server-lib.pl'; &ReadParseMime(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); $config{'edit_afiles'} || $master_admin || &error($text{'rfile_ecannot'}); $in{'replies_def'} || $in{'replies'} =~ /^\/\S+/ || &error($text{'rfile_ereplies'}); $in{'period_def'} || $in{'period'} =~ /^\d+$/ || &error($text{'rfile_eperiod'}); &switch_to_domain_user($d); $in{'text'} =~ s/\r//g; &lock_file($in{'file'}); open(FILE, ">$in{'file'}") || &error(&text('rfile_ewrite', $in{'file'}, $dom->{'user'}, $!)); if (!$in{'replies_def'}) { print FILE "Reply-Tracking: $in{'replies'}\n"; } if (!$in{'period_def'}) { print FILE "Reply-Period: $in{'period'}\n"; } print FILE $in{'text'}; close(FILE); &unlock_file($in{'file'}); &webmin_log("save", "rfile", $in{'file'}); $what = $in{'alias'} ? 'alias' : 'user'; &redirect("edit_$what.cgi?$what=$in{$what}&dom=$in{'dom'}"); virtual-server/edit_ffile.cgi0100775000567100000120000000423310012273053016307 0ustar jcameronwheel#!/usr/local/bin/perl # edit_ffile.cgi # Allow editing of a filter config file require './virtual-server-lib.pl'; &ReadParse(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); $config{'edit_afiles'} || $master_admin || &error($text{'ffile_ecannot'}); &header($text{'ffile_title'}, ""); print "
\n"; &switch_to_domain_user($d); if (-e $in{'file'}) { open(FILE, $in{'file'}) || &error(&text('ffile_eread', $in{'file'}, $d->{'user'}, $!)); while() { s/\r|\n//g; if (/^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) { push(@filter, [ $1, $2, $3, $4 ]); } elsif (/^(2)\s+(\S+)$/) { $other = $2; } } close(FILE); } print "",&text('ffile_desc', "$in{'file'}"),"

\n"; $what = $in{'alias'} ? 'alias' : 'user'; print "

\n"; print "\n"; print "\n"; print "\n"; $i = 0; foreach $f (@filter, [ 1, '', '', '' ], [ 1, '', '', '' ], [ 1, '', '', '' ], [ 1, '', '', '' ], [ 1, '', '', '' ]) { $field = "\n"; $what = "\n"; $match = "\n"; $action = "\n"; print &text('ffile_line', $field, $what, $match, $action),"
\n"; $i++; } print &text('ffile_other', ""),"
\n"; print "\n"; print "
\n"; print "
\n"; &footer("edit_$what.cgi?dom=$in{'dom'}&$what=$in{$what}", $text{$what.'_return'}); virtual-server/save_ffile.cgi0100775000567100000120000000176310017553164016336 0ustar jcameronwheel#!/usr/local/bin/perl # save_ffile.cgi # Save a filter file require './virtual-server-lib.pl'; &ReadParseMime(); $d = &get_domain($in{'dom'}); &can_edit_domain($d) || &error($text{'aliases_ecannot'}); $config{'edit_afiles'} || $master_admin || &error($text{'ffile_ecannot'}); &error_setup($text{'ffile_err'}); for($i=0; defined($in{"field_$i"}); $i++) { next if (!$in{"field_$i"}); $in{"match_$i"} || &error($text{'ffile_ematch'}); $in{"action_$i"} || &error($text{'ffile_eaction'}); push(@filter, $in{"what_$i"}." ".$in{"action_$i"}." ". $in{"field_$i"}." ".$in{"match_$i"}."\n"); } push(@filter, "2 ".$in{'other'}."\n") if ($in{'other'}); &switch_to_domain_user($d); &lock_file($in{'file'}); open(FILE, ">$in{'file'}") || &error(&text('ffile_ewrite', $in{'file'}, $d->{'user'}, $!)); print FILE @filter; close(FILE); &unlock_file($in{'file'}); &webmin_log("save", "ffile", $in{'file'}); $what = $in{'alias'} ? 'alias' : 'user'; &redirect("edit_$what.cgi?$what=$in{$what}&dom=$in{'dom'}"); virtual-server/edit_newuser.cgi0100775000567100000120000000201110012273113016677 0ustar jcameronwheel#!/usr/local/bin/perl # edit_newdom.cgi # Display the current new domain email require './virtual-server-lib.pl'; $master_admin || &error($text{'newuser_ecannot'}); &header($text{'newuser_title'}, ""); print "
\n"; print "
\n"; $file = $config{'user_template'}; $file = "$module_config_directory/user-template" if ($file eq "none" || $file eq 'default'); print &text($config{'user_template'} eq "none" ? 'newuser_descdis' : 'newuser_desc', "$file"),"

\n"; $text{'sub_USER'} = $text{'sub_POP3'}; $text{'sub_HOME'} = $text{'sub_POP3HOME'}; &print_subs_table("MAILBOX", "USER", "DOM", "FTP", "HOME"); print "
\n"; print "\n"; print "\n"; print "

\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/edit_newweb.cgi0100775000567100000120000000446010035165023016515 0ustar jcameronwheel#!/usr/local/bin/perl # edit_newweb.cgi # Display the current Apache configuration template require './virtual-server-lib.pl'; $master_admin || &error($text{'newweb_ecannot'}); &header($text{'newweb_title'}, ""); print "
\n"; print "
\n"; print "$text{'newweb_desc'}
\n"; &print_subs_table("DOM", "USER", "IP"); print "
\n"; print "\n"; print "\n"; printf "\n", $config{'suexec'} ? "" : "checked", $text{'no'}; print "\n"; printf "\n", $config{'html_dir'}, $text{'newweb_htmldir0suf'}; $hdir = $config{'html_dir'} || "public_html"; print "\n"; printf "\n", $config{'stats_dir'}; print "\n"; printf "\n", $web_port; print "\n"; printf "\n", $web_sslport; print "
$text{'newweb_suexec'} %s\n", $config{'suexec'} ? "checked" : "", $text{'yes'}; printf " %s
$text{'newweb_htmldir'} %s (%s)\n", $config{'html_dir'} ? "" : "checked", $text{'default'}, "public_html"; printf "
%s\n", $config{'html_dir'} ? "checked" : "", $text{'newweb_htmldir0'}; printf " %s
$text{'newweb_statsdir'} %s (%s)\n", $config{'stats_dir'} ? "" : "checked", $text{'default'}, "$hdir/stats"; printf "
%s\n", $config{'stats_dir'} ? "checked" : "", &text('newweb_statsdir0', "$hdir"); printf "
$text{'newweb_port'}
$text{'newweb_sslport'}
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/edit_newdom.cgi0100775000567100000120000000166510012273076016526 0ustar jcameronwheel#!/usr/local/bin/perl # edit_newdom.cgi # Display the current new domain email require './virtual-server-lib.pl'; $master_admin || &error($text{'newdom_ecannot'}); &header($text{'newdom_title'}, ""); print "
\n"; print "
\n"; $file = $config{'domain_template'}; $file = "$module_config_directory/domain-template" if ($file eq "none" || $file eq 'default'); print &text($config{'domain_template'} eq "none" ? 'newdom_descdis' : 'newdom_desc', "$file"),"

\n"; &print_subs_table("DOM", "USER", "HOME", "UID", "IP"); print "
\n"; print "\n"; print "\n"; print "

\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/save_newweb.cgi0100775000567100000120000000356610035163554016543 0ustar jcameronwheel#!/usr/local/bin/perl # save_newweb.cgi # Update the Apache configuration template require './virtual-server-lib.pl'; $master_admin || &error($text{'newweb_ecannot'}); &ReadParseMime(); &error_setup($text{'newweb_err'}); $in{'apache_config'} =~ s/\r//g; $in{'apache_config'} =~ s/\t/ /g; $config{'apache_config'} = join("\t", split(/\n/, $in{'apache_config'})); $err = &check_apache_directives(); &error($err) if ($err); $config{'suexec'} = $in{'suexec'}; if ($in{'html_dir_def'}) { delete($config{'html_dir'}); } else { $in{'html_dir'} =~ /^\S+$/ && $in{'html_dir'} !~ /^\// && $in{'html_dir'} !~ /\.\./ || &error($text{'newweb_ehtml'}); $config{'html_dir'} = $in{'html_dir'}; } if ($in{'stats_dir_def'}) { delete($config{'stats_dir'}); } else { $in{'stats_dir'} =~ /^\S+$/ && $in{'stats_dir'} !~ /^\// && $in{'stats_dir'} !~ /\.\./ || &error($text{'newweb_estats'}); $config{'stats_dir'} = $in{'stats_dir'}; } $old_web_port = $web_port; $old_web_sslport = $web_sslport; $in{'web_port'} =~ /^\d+$/ && $in{'web_port'} > 0 && $in{'web_port'} < 65536 || &error($text{'newweb_eport'}); $config{'web_port'} = $in{'web_port'}; $in{'web_sslport'} =~ /^\d+$/ && $in{'web_sslport'} > 0 && $in{'web_sslport'} < 65536 || &error($text{'newweb_esslport'}); $in{'web_port'} != $in{'web_sslport'} || &error($text{'newweb_esslport2'}); $config{'web_sslport'} = $in{'web_sslport'}; &lock_file($module_config_file); $config{'last_check'} = time()+1; # no need for check.cgi to be run &write_file($module_config_file, \%config); &unlock_file($module_config_file); # If the web or SSL ports were changed, all existing virtual hosts should be # updated with the *old* setting to that we know what port they were created on if ($old_web_port != $in{'web_port'} || $old_web_sslport != $in{'web_sslport'}) { foreach $d (&list_domains()) { &save_domain($d); } } &webmin_log("newweb"); &redirect(""); virtual-server/save_newuser.cgi0100775000567100000120000000101710017553626016734 0ustar jcameronwheel#!/usr/local/bin/perl # save_newuser.cgi # Save the new mailbox email require './virtual-server-lib.pl'; $master_admin || &error($text{'newuser_ecannot'}); &ReadParseMime(); $file = $config{'user_template'}; $file = "$module_config_directory/user-template" if ($file eq "none" || $file eq 'default'); $in{'user_template'} =~ s/\r//g; &lock_file($file); open(FILE, ">$file") || &error(&text('efilewrite', $file, $!)); print FILE $in{'user_template'}; close(FILE); &unlock_file($file); &webmin_log("newuser"); &redirect(""); virtual-server/save_newdom.cgi0100775000567100000120000000102310017553205016523 0ustar jcameronwheel#!/usr/local/bin/perl # save_newdom.cgi # Save the new domain email require './virtual-server-lib.pl'; $master_admin || &error($text{'newdom_ecannot'}); &ReadParseMime(); $file = $config{'domain_template'}; $file = "$module_config_directory/domain-template" if ($file eq "none" || $file eq 'default'); $in{'domain_template'} =~ s/\r//g; &lock_file($file); open(FILE, ">$file") || &error(&text('efilewrite', $file, $!)); print FILE $in{'domain_template'}; close(FILE); &unlock_file($file); &webmin_log("newdom"); &redirect(""); virtual-server/edit_newdns.cgi0100775000567100000120000000225410035165043016525 0ustar jcameronwheel#!/usr/local/bin/perl # edit_newdns.cgi # Display the current DNS configuration template require './virtual-server-lib.pl'; $master_admin || &error($text{'newdns_ecannot'}); &header($text{'newdns_title'}, ""); print "
\n"; print "
\n"; print "$text{'newdns_desc'}
\n"; &print_subs_table("DOM", "IP"); printf " %s
\n", $config{'bind_replace'} ? "" : "checked", $text{'newdns_replace0'}; printf " %s
\n", $config{'bind_replace'} ? "checked" : "", $text{'newdns_replace1'}; print "
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/save_newdns.cgi0100775000567100000120000000337510035234466016551 0ustar jcameronwheel#!/usr/local/bin/perl # save_newdns.cgi # Update the BIND configuration template require './virtual-server-lib.pl'; $master_admin || &error($text{'newdns_ecannot'}); &ReadParseMime(); &error_setup($text{'newdns_err'}); &require_bind(); # Parse and save records $in{'bind_config'} =~ s/\r//g; $in{'bind_config'} =~ s/\t/ /g; $config{'bind_config'} = join("\t", split(/\n/, $in{'bind_config'})); $config{'bind_replace'} = $in{'bind_replace'}; delete($config{'mx_server'}); $fakeip = "1.2.3.4"; $fakedom = "foo.com"; $recs = &substitute_template( join("\n", split(/\t+/, $config{'bind_config'}))."\n", { 'ip' => $fakeip, 'dom' => $fakedom }); $temp = &tempname(); open(TEMP, ">$temp"); print TEMP $recs; close(TEMP); $bind8::config{'short_names'} = 0; # force canonicalization $bind8::config{'chroot'} = '/'; # turn off chroot for temp path @recs = &bind8::read_zone_file($temp, $fakedom); unlink($temp); foreach $r (@recs) { $soa++ if ($r->{'name'} eq $fakedom."." && $r->{'type'} eq "SOA"); $ns++ if ($r->{'name'} eq $fakedom."." && $r->{'type'} eq "NS"); $dom++ if ($r->{'name'} eq $fakedom."." && ($r->{'type'} eq "A" || $r->{'type'} eq "MX")); $www++ if ($r->{'name'} eq "www.".$fakedom."." && $r->{'type'} eq "A"); } if ($config{'bind_replace'}) { # Make sure an SOA and NS records exist $soa == 1 || &error($text{'newdns_esoa'}); $ns || &error($text{'newdns_ens'}); $dom || &error($text{'newdns_edom'}); $www || &error($text{'newdns_ewww'}); } else { # Make sure SOA doesn't exist $soa && &error($text{'newdns_esoa2'}); } &lock_file($module_config_file); $config{'last_check'} = time()+1; # no need for check.cgi to be run &write_file($module_config_file, \%config); &unlock_file($module_config_file); &webmin_log("newdns"); &redirect(""); virtual-server/create-user.pl0100775000567100000120000001011710007630566016315 0ustar jcameronwheel#!/usr/local/bin/perl # create-user.pl # Adds a new mailbox, based on command-line parameters $no_acl_check++; $ENV{'WEBMIN_CONFIG'} ||= "/etc/webmin"; $ENV{'WEBMIN_VAR'} ||= "/var/webmin"; if ($0 =~ /^(.*\/)[^\/]+$/) { chdir($1); } chop($pwd = `pwd`); $0 = "$pwd/create-user.pl"; require './virtual-server-lib.pl'; $< == 0 || die "create-user.pl must be run as root"; # Parse command-line args while(@ARGV > 0) { local $a = shift(@ARGV); if ($a eq "--domain") { $domain = shift(@ARGV); } elsif ($a eq "--user") { $username = lc(shift(@ARGV)); } elsif ($a eq "--pass") { $pass = shift(@ARGV); } elsif ($a eq "--real") { $real = shift(@ARGV); } elsif ($a eq "--ftp") { $ftp++; } elsif ($a eq "--noemail") { $noemail++; } elsif ($a eq "--extra") { local $extra = shift(@ARGV); push(@extra, $extra); } elsif ($a eq "--quota") { $quota = shift(@ARGV); } elsif ($a eq "--mail-quota") { $mquota = shift(@ARGV); } } # Make sure all needed args are set $domain && $username && $pass || &usage(); if ($config{'home_quotas'}) { $quota =~ /^\d+$/ || &usage(); } if ($config{'mail_quotas'} && $config{'home_quotas'} ne $config{'mail_quotas'}) { $mquota =~ /^\d+$/ || &usage(); } $d = &get_domain_by("dom", $domain); $d || die("Virtual server $domain does not exist"); $username =~ /^[^ \t:]+$/ || die($text{'user_euser'}); $real =~ /^[^:]*$/ || die($text{'user_ereal'}); foreach $e (@extra) { $e = lc($e); if ($e =~ /^([^\@ \t]+$)$/) { $e = "$e\@$d->{'dom'}"; } if ($e !~ /^(\S+)\@(\S+)$/) { die(&text('user_eextra1', $e)); } local ($eu, $ed) = ($1, $2); local $edom = &get_domain_by("dom", $ed); $edom && $edom->{'mail'} || die(&text('user_eextra2', $ed)); } # Build taken lists &build_taken(\%taken, \%utaken); # Construct user object $user->{'uid'} = &allocate_uid(\%taken); $user->{'gid'} = $d->{'gid'}; $user->{'real'} = $real; $user->{'shell'} = $ftp ? $config{'ftp_shell'} : $config{'shell'}; $user->{'home'} = "$d->{'home'}/homes/$username"; $user->{'passmode'} = 3; $user->{'plainpass'} = $pass; $user->{'pass'} = &useradmin::encrypt_password($pass); $user->{'extraemail'} = \@extra; if ($utaken{$username} || $config{'append'}) { $user->{'user'} = &userdom_name($username, $d); } else { $user->{'user'} = $username; } $user->{'email'} = "$username\@$d->{'dom'}" if (!$noemail); # Check for a clash in this domain if ($utaken{$user->{'user'}} || &check_clash($username, $d->{'dom'})) { die($text{'user_eclash'}); } # Check if any extras clash foreach $e (@extra) { $e =~ /^(\S+)\@(\S+)$/; if (&check_clash($1, $2)) { die(&text('user_eextra4', $e)); } } # Check if the name is too long if ($lerr = &too_long($user->{'user'})) { die($lerr); } # Create the user and virtusers and alias &create_user($user, $d); # Create his homedir system("mkdir -p '$user->{'home'}'"); system("chown $user->{'uid'}:$user->{'gid'} '$user->{'home'}'"); system("chmod 755 '$user->{'home'}'"); # Copy files into homedir ©_skel_files($config{'mail_skel'}, $user); # Send an email upon creation @erv = &send_user_email($d, $user); # Set quotas if ($config{'home_quotas'}) { &set_quota($user->{'user'}, $config{'home_quotas'}, $quota); } if ($config{'mail_quotas'} && $config{'home_quotas'} ne $config{'mail_quotas'}) { &set_quota($user->{'user'}, $config{'mail_quotas'}, $quota); } print "User $user->{'user'} created successfully\n"; sub usage { print "Adds a new mailbox user to an existing Virtualmin domain.\n"; print "\n"; print "usage: create-user.pl --domain domain.name\n"; print " --user new-username\n"; print " --pass password-for-new-user\n"; if ($config{'home_quotas'}) { print " --quota quota-in-blocks\n"; } if ($config{'mail_quotas'} && $config{'mail_quotas'} ne $config{'home_quotas'}) { print " --mail-quota quota-in-blocks\n"; } print " [--real real-name-for-new-user]\n"; print " [--ftp]\n"; print " [--noemail]\n"; print " [--extra email.address\@some.domain]\n"; exit(1); } virtual-server/local-template0100664000567100000120000000060710001706376016364 0ustar jcameronwheelYour local mailbox has been set up successfully as follows : Email address: ${MAILBOX}@${HOSTNAME} POP3 login: ${USER} POP3 password: ${PLAINPASS} SMTP server: ${HOSTNAME} POP3 server: ${HOSTNAME} ${IF-FTP} FTP login: Enabled Home directory: ${HOME} ${ELSE-FTP} FTP login: Disabled ${ENDIF-FTP} virtual-server/edit_newlocal.cgi0100775000567100000120000000201210012273105017015 0ustar jcameronwheel#!/usr/local/bin/perl # edit_newlocal.cgi # Display the current new local user email require './virtual-server-lib.pl'; $master_admin || &error($text{'newlocal_ecannot'}); &header($text{'newlocal_title'}, ""); print "
\n"; print "
\n"; $file = $config{'local_template'}; $file = "$module_config_directory/local-template" if ($file eq "none" || $file eq "default"); print &text($config{'local_template'} eq "none" ? 'newlocal_descdis' : 'newlocal_desc', "$file"),"

\n"; $text{'sub_USER'} = $text{'sub_MAILBOX'}; $text{'sub_HOME'} = $text{'sub_LOCALHOME'}; &print_subs_table("USER", "FTP", "HOME"); print "
\n"; print "\n"; print "\n"; print "

\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/save_newlocal.cgi0100775000567100000120000000103410017553606017045 0ustar jcameronwheel#!/usr/local/bin/perl # save_newlocal.cgi # Save the new local mailbox email require './virtual-server-lib.pl'; $master_admin || &error($text{'newlocal_ecannot'}); &ReadParseMime(); $file = $config{'local_template'}; $file = "$module_config_directory/local-template" if ($file eq "none" || $file eq 'default'); $in{'local_template'} =~ s/\r//g; &lock_file($file); open(FILE, ">$file") || &error(&text('efilewrite', $file, $!)); print FILE $in{'local_template'}; close(FILE); &unlock_file($file); &webmin_log("newlocal"); &redirect(""); virtual-server/log_parser.pl0100644000567100000120000000207610041666163016233 0ustar jcameronwheel# log_parser.pl # Functions for parsing this module's logs do 'virtual-server-lib.pl'; # parse_webmin_log(user, script, action, type, object, ¶ms) # Converts logged information from this module into human-readable form sub parse_webmin_log { local ($user, $script, $action, $type, $object, $p, $long) = @_; if ($type eq "user") { return &text('log_'.$action.'_user', "$object", "$p->{'dom'}"); } elsif ($type eq "alias") { return &text('log_'.$action.'_alias', "$object"); } elsif ($type eq "domain") { return &text('log_'.$action.'_domain', "$object"); } elsif ($action eq "start" || $action eq "stop") { return $text{'log_'.$action.'_'.$type}; } elsif ($action eq "backup" || $action eq "restore") { local @doms = split(/\0/, $p->{'doms'}); if ($long) { return &text('log_'.$action.'_l', join(" ", map { "$_" } @doms)); } else { return &text('log_'.$action, scalar(@doms)); } } elsif ($action eq "sched") { return $text{'log_sched_'.$type}; } else { return $text{'log_'.$action}; } return undef; } virtual-server/all_webmin.cgi0100775000567100000120000000047110015255345016335 0ustar jcameronwheel#!/usr/local/bin/perl # all_webmin.cgi # Update all Webmin users require './virtual-server-lib.pl'; $master_admin || &error($text{'allwebmin_ecannot'}); $| = 1; $theme_no_table++; &header($text{'allwebmin_title'}, ""); print "
\n"; &modify_all_webmin(); print "
\n"; &footer("", $text{'index_return'}); virtual-server/check.cgi0100775000567100000120000002371210035131057015277 0ustar jcameronwheel#!/usr/local/bin/perl # check.cgi # Make sure that all enabled features are valid, and check the status of quotas require './virtual-server-lib.pl'; $master_admin || &error($text{'check_ecannot'}); $| = 1; $theme_no_table++; &header($text{'check_title'}, ""); print "
\n"; &read_file("$module_config_directory/last-config", \%lastconfig); print "$text{'check_desc'}

\n"; print "

    \n"; $clink = "../config.cgi?$module_name"; # Make sure networking is supported if (!&foreign_check("net")) { &foreign_require("net", "net-lib.pl"); if (!defined(&net::boot_interfaces)) { &check_error(&text('index_enet')); } print "$text{'check_netok'}

    \n"; } if ($config{'dns'}) { # Make sure BIND is installed &foreign_installed("bind8", 1) == 2 || &check_error(&text('index_ebind', "/bind8/", $clink)); print "$text{'check_bindok'}

    \n"; } if ($config{'mail'}) { if ($config{'mail_system'} == 3) { # Work out which mail server we have if (&postfix_installed()) { $config{'mail_system'} = 0; } elsif (&qmail_installed()) { $config{'mail_system'} = 2; } elsif (&sendmail_installed()) { $config{'mail_system'} = 1; } else { &check_error(&text('index_email')); } &write_file("$module_config_directory/config", \%config); } if ($config{'mail_system'} == 1) { # Make sure sendmail is installed if (!&sendmail_installed()) { &check_error(&text('index_esendmail', '/sendmail/', "/config.cgi?$module_name")); } # Check that aliases and virtusers are configured &require_mail(); @$sendmail_afiles || &check_error(&text('index_esaliases', '/sendmail/')); $sendmail_vdbm || &check_error(&text('index_esvirts', '/sendmail/')); if ($config{'generics'}) { $sendmail_gdbm || &check_error(&text('index_esgens', '/sendmail/', $clink)); } print "$text{'check_sendmailok'}

    \n"; } elsif ($config{'mail_system'} == 0) { # Make sure postfix is installed if (!&postfix_installed()) { &check_error(&text('index_epostfix', '/postfix/', "/config.cgi?$module_name")); } # Check that aliases and virtusers are configured &require_mail(); @$postfix_afiles || &check_error(&text('index_epaliases', '/postfix/')); $virtual_maps || &check_error(&text('index_epvirts', '/postfix/')); if ($config{'generics'}) { $canonical_maps || check_error(&text('index_epgens', '/postfix/', $clink)); } print "$text{'check_postfixok'}

    \n"; } elsif ($config{'mail_system'} == 2) { # Make sure qmail is installed if (!&qmail_installed()) { &check_error(&text('index_eqmail', '/qmailadmin/', "/config.cgi?$module_name")); } if ($config{'generics'}) { # Is this even possible for qmail? } print "$text{'check_qmailok'}

    \n"; } } if ($config{'web'}) { # Make sure Apache is installed &foreign_installed("apache", 1) == 2 || &check_error(&text('index_eapache', "/apache/", $clink)); print "$text{'check_webok'}

    \n"; } if ($config{'webalizer'}) { # Make sure Webalizer is installed $config{'web'} || &check_error(&text('check_edepwebalizer', $clink)); &foreign_installed("webalizer", 1) == 2 || &check_error(&text('index_ewebalizer', "/webalizer/", $clink)); print "$text{'check_webalizerok'}

    \n"; } if ($config{'ssl'}) { # Make sure openssl is installed, that Apache supports mod_ssl, # and that port 443 is in use $config{'web'} || &check_error(&text('check_edepssl', $clink)); &has_command("openssl") || &check_error(&text('index_eopenssl', "openssl", $clink)); &require_apache(); local $conf = &apache::get_config(); local @loads = &apache::find_directive_struct("LoadModule", $conf); local ($l, $hasmod); foreach $l (@loads) { $hasmod++ if ($l->{'words'}->[1] =~ /mod_ssl/); } local ($aver, $amods) = &apache::httpd_info(); $hasmod++ if (&indexof("mod_ssl", @$amods) >= 0); $hasmod++ if ($apache::httpd_modules{'mod_ssl'}); $hasmod || &check_error(&text('index_emodssl', "mod_ssl", $clink)); local @listens = &apache::find_directive_struct("Listen", $conf); foreach $l (@listens) { $haslisten++ if ($l->{'words'}->[0] =~ /^(\S+:)?$web_sslport$/); } local @ports = &apache::find_directive_struct("Port", $conf); foreach $l (@ports) { $haslisten++ if ($l->{'words'}->[0] == $web_sslport); } $haslisten || &check_error(&text('index_emodssl2', $web_sslport, $clink)); print "$text{'check_sslok'}

    \n"; } if ($config{'mysql'}) { # Make sure MySQL is installed &foreign_installed("mysql", 1) == 2 || &check_error(&text('index_emysql', "/mysql/", $clink)); print "$text{'check_mysqlok'}

    \n"; } if ($config{'postgres'}) { # Make sure PostgreSQL is installed &foreign_installed("postgresql", 1) == 2 || &check_error(&text('index_epostgres', "/postgresql/", $clink)); print "$text{'check_postgresok'}

    \n"; } if (!$config{'iface'}) { # Work out the network interface automatically &foreign_require("net", "net-lib.pl"); foreach $a (&net::active_interfaces()) { if ($a->{'up'} && $a->{'virtual'} eq '' && &net::iface_type($a->{'name'}) =~ /ethernet/i) { $config{'iface'} = $a->{'fullname'}; last; } } if (!$config{'iface'}) { &check_error(&text('index_eiface', "/config.cgi?$module_name")); } &write_file("$module_config_directory/config", \%config); } print &text('check_ifaceok', "$config{'iface'}"),"

    \n"; # Make sure local group exists if ($config{'localgroup'} && !defined(getgrnam($config{'localgroup'}))) { &check_error(&text('index_elocal', "$config{'localgroup'}", "/config.cgi?$module_name")); } $config{'home_quotas'} = ''; $config{'mail_quotas'} = ''; $config{'group_quotas'} = ''; if ($config{'quotas'}) { # Make sure quotas are enabled, and work out where they are needed &require_useradmin(); if (!$home_base) { print "

    ",&text('index_ehomebase'),"

    \n"; } else { &foreign_require("mount", "mount-lib.pl"); $mail_base = &mail_system_base(); ($home_mtab, $home_fstab) = &mount_point($home_base); ($mail_mtab, $mail_fstab) = &mount_point($mail_base); if (!$home_mtab) { print "

    ",&text('index_ehomemtab', "$home_base"),"

    \n"; } elsif (!$mail_mtab) { print "

    ",&text('index_emailmtab', "$mail_base"),"

    \n"; } else { # Check if quotas are enabled for home filesystem local $nohome; if (!($home_mtab->[4] = "a::quota_can( $home_mtab, $home_fstab))%2 || !"a::quota_now($home_mtab, $home_fstab)) { $nohome++; } else { if ($home_mtab->[4] >= 2) { # Group quotas are active too $config{'group_quotas'} = 1; } } if ($home_mtab->[0] eq $mail_mtab->[0]) { # Home and mail are the same filesystem if ($nohome) { # Neither are enabled $qerr = &text('index_equota2', "$home_mtab->[0]", "$home_base", "$mail_base"); } else { # Both are enabled $config{'home_quotas'} = $home_mtab->[0]; $config{'mail_quotas'} = $home_mtab->[0]; } } else { # Different .. so check mail too local $nomail; if (!($mail_mtab->[4] = "a::quota_can( $mail_mtab, $mail_fstab)) || !"a::quota_now($mail_mtab, $mail_fstab)) { $nomail++; } if ($nohome) { $qerr = &text('index_equota3', "$home_mtab->[0]", "$home_base"); } else { $config{'home_quotas'} = $home_mtab->[0]; } if ($nomail) { $qerr = &text('index_equota4', "$mail_mtab->[0]", "$mail_base"); } else { $config{'mail_quotas'} = $mail_mtab->[0]; } } } } } if ($qerr) { print "$qerr

    \n"; } elsif (!$config{'group_quotas'}) { print "$text{'check_nogroup'}

    \n"; } else { print "$text{'check_group'}

    \n"; } # Check for FTP shells in /etc/shells open(SHELLS, "/etc/shells"); while() { s/\r|\n//g; s/#.*$//; $shells{$_}++; } close(SHELLS); if ($shells{$config{'shell'}}) { print &text('check_eshell', "$config{'shell'}", "/etc/shells"),"

    \n"; } if (!$shells{$config{'ftp_shell'}}) { print &text('check_eftpshell', "$config{'ftp_shell'}", "/etc/shells"),"

    \n"; } $config{'last_check'} = time()+1; $config{'disable'} =~ s/user/unix/g; # changed since last release &lock_file($module_config_file); &write_file($module_config_file, \%config); &unlock_file($module_config_file); #&lock_file("$module_config_directory/last-config"); &write_file("$module_config_directory/last-config", \%config); #&unlock_file("$module_config_directory/last-config"); print "

\n"; print "$text{'check_done'}

\n"; # See if any options effecting Webmin users have changed $webminchanged = 0; foreach $k (keys %config) { if ($k =~ /^avail_/ || $k eq 'leave_acl' || &indexof($k, @features) >= 0) { $webminchanged++ if ($config{$k} != $lastconfig{$k}); } } if ($webminchanged) { if ($config{'post_check'}) { # Update all Webmin users &modify_all_webmin(); } else { # Just offer to update print "

\n"; print "$text{'check_needupdate'}

\n"; print "\n"; print "

\n"; } } &webmin_log("check"); print "
\n"; &footer("", $text{'index_return'}); sub check_error { print "

$_[0]

\n"; print "\n"; print "$text{'check_failed'}

\n"; print "


\n"; &footer("/", $text{'index'}); exit; } # mount_point(dir) # Returns both the mtab and fstab details for the parent mount for a directory sub mount_point { local $dir = &resolve_links($_[0]); local @mounts = &mount::list_mounts(); local @mounted = &mount::list_mounted(); @mounts = @mounted if (!@mounts); foreach $m (sort { length($b->[0]) <=> length($a->[0]) } @mounted) { if ($dir eq $m->[0] || $m->[0] eq "/" || substr($dir, 0, length($m->[0])+1) eq "$m->[0]/") { local ($m2) = grep { $_->[0] eq $m->[0] } @mounts; if ($m2) { return ($m, $m2); } } } &error("Failed to find mount point for $dir"); } virtual-server/feature-web.pl0100664000567100000120000002375510041666222016311 0ustar jcameronwheel$web_port = $config{'web_port'} || 80; sub require_apache { return if ($require_apache++); &foreign_require("apache", "apache-lib.pl"); } # setup_web(&domain) # Setup a virtual website for some domain sub setup_web { &$first_print($text{'setup_web'}); &require_apache(); local $conf = &apache::get_config(); if ($apache::config{'virt_file'}) { $f = -d $apache::config{'virt_file'} ? "$apache::config{'virt_file'}/www.$_[0]->{'dom'}.conf" : $apache::config{'virt_file'}; } else { $vconf = &apache::get_virtual_config(); $f = $vconf->[0]->{'file'}; } &lock_file($f); # add NameVirtualHost if needed local $nvstar; if ($_[0]->{'name'}) { local $found; local @nv = &apache::find_directive("NameVirtualHost", $conf); foreach $nv (@nv) { $found++ if ($nv eq $_[0]->{'ip'} || $nv =~ /^(\S+):(\S+)/ && $1 eq $_[0]->{'ip'} || $nv eq '*'); $nvstar++ if ($nv eq "*"); } if (!$found) { &apache::save_directive("NameVirtualHost", [ @nv, $_[0]->{'ip'} ], $conf, $conf); &flush_file_lines(); } } # Add the actual local @dirs = &apache_template($config{'apache_config'}, $_[0]); local $vip = $_[0]->{'name'} && $apache::httpd_modules{'core'} >= 1.312 && $nvstar ? "*" : $_[0]->{'ip'}; open(FILE, ">>$f"); print FILE "\n"; foreach (@dirs) { print FILE $_,"\n"; } print FILE "\n"; close(FILE); &unlock_file($f); undef(@apache::get_config_cache); &$second_print($text{'setup_done'}); &restart_apache(); $_[0]->{'web_port'} = $web_port; } # delete_web(&domain) # Delete the virtual server from the Apache config sub delete_web { &require_apache(); local $conf = &apache::get_config(); &$first_print($text{'delete_apache'}); if ($config{'delete_indom'}) { local @virt = reverse(&apache::find_directive_struct("VirtualHost", $conf)); foreach $v (@virt) { local $sn = &apache::find_directive("ServerName", $v->{'members'}); if ($sn =~ /\Q$_[0]->{'dom'}\E$/) { &delete_virtual_server($v); } } &$second_print($text{'setup_done'}); &restart_apache(); } else { local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_port'}); if ($virt) { &delete_virtual_server($virt); &$second_print($text{'setup_done'}); &restart_apache(); } else { &$second_print($text{'delete_noapache'}); } } undef(@apache::get_config_cache); } # delete_virtual_server(&domain) # Delete a single virtual server from the Apache config sub delete_virtual_server { &require_apache(); &lock_file($_[0]->{'file'}); local $lref = &read_file_lines($_[0]->{'file'}); splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1); &flush_file_lines(); &unlock_file($_[0]->{'file'}); } # modify_web(&domain, &olddomain) # If this server has changed from name-based to IP-based hosting, update # the Apache configuration sub modify_web { local $rv = 0; &require_apache(); local $conf = &apache::get_config(); local ($virt, $vconf) = &get_apache_virtual($_[1]->{'dom'}, $_[1]->{'web_port'}); &lock_file($virt->{'file'}); if ($_[0]->{'name'} != $_[1]->{'name'} || $_[0]->{'ip'} ne $_[1]->{'ip'}) { # Name-based hosting mode has changed &$first_print($text{'save_apache'}); local $lref = &read_file_lines($virt->{'file'}); $lref->[$virt->{'line'}] = $_[0]->{'name'} ? "" : "{'ip'}:$_[1]->{'web_port'}>"; &flush_file_lines(); $rv++; &$second_print($text{'setup_done'}); } &unlock_file($virt->{'file'}); &restart_apache() if ($rv); return $rv; } $disabled_website = "$module_config_directory/disabled.html"; # disable_web(&domain) # Adds a directive to force all requests to show an error page sub disable_web { &$first_print($text{'disable_apache'}); &require_apache(); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_port'}); if ($virt) { &create_disable_directives($virt, $vconf); &$second_print($text{'setup_done'}); &restart_apache(); } else { &$second_print($text{'delete_noapache'}); } } # create_disable_directives(&virt, &vconf) sub create_disable_directives { local ($virt, $vconf) = @_; &lock_file($virt->{'file'}); local @am = &apache::find_directive("AliasMatch", $vconf); local $conf = &apache::get_config(); &apache::save_directive("AliasMatch", [ @am, "^/.*\$ $disabled_website" ], $vconf, $conf); &flush_file_lines(); if (!-r $disabled_website) { open(DISABLED, ">$disabled_website"); print DISABLED "

Website Disabled

\n"; close(DISABLED); chmod(0644, $disabled_website); } &unlock_file($virt->{'file'}); } # enable_web(&domain) # Deletes the special error page directive sub enable_web { &$first_print($text{'enable_apache'}); &require_apache(); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_port'}); if ($virt) { &remove_disable_directives($virt, $vconf); &$second_print($text{'setup_done'}); &restart_apache(); } else { &$second_print($text{'delete_noapache'}); } } # remove_disable_directives(&virt, &vconf) sub remove_disable_directives { local ($virt, $vconf) = @_; &lock_file($virt->{'file'}); local @am = &apache::find_directive("AliasMatch", $vconf); @am = grep { $_ ne "^/.*\$ $disabled_website" } @am; local $conf = &apache::get_config(); &apache::save_directive("AliasMatch", \@am, $vconf, $conf); &flush_file_lines(); &unlock_file($virt->{'file'}); } # check_web_clash(domain, db, user) # Returns 1 if an Apache webserver already exists for some domain sub check_web_clash { local ($cvirt, $cconf) = &get_apache_virtual($_[0], $web_port); return $cvirt ? 1 : 0; } # restart_apache([restart]) # Tell Apache to re-read its config file sub restart_apache { &$first_print($_[0] ? $text{'setup_webpid2'} : $text{'setup_webpid'}); local $pid = &get_apache_pid(); if (!$pid || !kill(0, $pid)) { &$second_print($text{'setup_notrun'}); return 0; } if ($_[0]) { # Totally stop and start if ($apache::config{'stop_cmd'}) { &system_logged("$apache::config{'stop_cmd'} >/dev/null 2>&1"); } else { &system_logged("$apache::config{'apachectl_path'} stop >/dev/null 2>&1"); } sleep(5); if ($apache::config{'start_cmd'}) { &system_logged("$apache::config{'start_cmd'} >/dev/null 2>&1"); } else { &system_logged("$apache::config{'apachectl_path'} start >/dev/null 2>&1"); } &$second_print($text{'setup_done'}); return 1; } else { # Just signal a re-load if ($apache::config{'apply_cmd'}) { # use the configured start command &system_logged("($apache::config{'apply_cmd'}) 2>&1"); } elsif (-x $apache::config{'apachectl_path'}) { # Use apachectl &system_logged("$apache::config{'apachectl_path'} restart 2>&1"); } else { # Just signal the process &kill_logged('HUP', $pid); } &$second_print($text{'setup_done'}); return 1; } } # get_apache_log(domain, [port]) # Given a domain name, returns the path to its log file sub get_apache_log { &require_apache(); local ($virt, $vconf) = &get_apache_virtual($_[0], $_[1]); if ($virt) { local $log = &apache::find_directive("TransferLog", $vconf, 1) || &apache::find_directive("CustomLog", $vconf, 1); return $log; } else { return undef; } } # get_apache_virtual(domain, [port]) # Returns the list of configuration directives and the directive for the # virtual domain itself for some domain sub get_apache_virtual { &require_apache(); local $conf = &apache::get_config(); local $v; local $sp = $_[1] || $web_port; foreach $v (&apache::find_directive_struct("VirtualHost", $conf)) { local $vp = $v->{'words'}->[0] =~ /:(\d+)$/ ? $1 : $web_port; next if ($vp != $sp); local $sn = &apache::find_directive("ServerName", $v->{'members'}); return ($v, $v->{'members'}) if ($sn eq $_[0] || $sn eq "www.$_[0]"); local $n; foreach $n (&apache::find_directive_struct( "ServerAlias", $v->{'members'})) { return ($v, $v->{'members'}) if (&indexof($_[0], @{$n->{'words'}}) >= 0 || &indexof("www.$_[0]", @{$n->{'words'}}) >= 0); } } return (); } # get_apache_pid() sub get_apache_pid { &require_apache(); local $pidfile = &apache::get_pid_file(); open(PID, $pidfile) || return undef; chop($pid = ); close(PID); return $pid; } # apache_template(text, &domain) # Returns a suitably substituted Apache template sub apache_template { local $dirs = $_[0]; $dirs =~ s/\t/\n/g; $dirs = &substitute_template($dirs, $_[1]); local @dirs = split(/\n/, $dirs); local ($sudir, $ppdir); foreach (@dirs) { $sudir++ if (/^SuexecUserGroup\s/i || /^User\s/i); $ppdir++ if (/^ProxyPass\s/); } if (!$sudir && $config{'suexec'}) { # Automatically add suexec directives if missing if ($apache::httpd_modules{'core'} >= 2.0) { if ($apache::httpd_modules{'mod_suexec'}) { unshift(@dirs, "SuexecUserGroup \"#$_[1]->{'uid'}\" ". "\"#$_[1]->{'ugid'}\""); } } else { unshift(@dirs, "User \"#$_[1]->{'uid'}\"", "Group \"#$_[1]->{'ugid'}\""); } } if (!$ppdir && $_[1]->{'proxy_pass'}) { push(@dirs, "ProxyPass / $_[1]->{'proxy_pass'}", "ProxyPassReverse / $_[1]->{'proxy_pass'}"); } return @dirs; } # backup_web(&domain, file) # Save the virtual server's Apache config as a separate file sub backup_web { &$first_print($text{'backup_apachecp'}); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_port'}); local $lref = &read_file_lines($virt->{'file'}); local $l; open(FILE, ">$_[1]"); foreach $l (@$lref[$virt->{'line'} .. $virt->{'eline'}]) { print FILE "$l\n"; } close(FILE); &$second_print($text{'setup_done'}); return 1; } # restore_web(&domain, file) # Update the virtual server's Apache configuration from a file. Does not # change the actual lines! sub restore_web { &$first_print($text{'restore_apachecp'}); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_port'}); local $srclref = &read_file_lines($_[1]); local $dstlref = &read_file_lines($virt->{'file'}); &lock_file($virt->{'file'}); splice(@$dstlref, $virt->{'line'}+1, $virt->{'eline'}-$virt->{'line'}-1, @$srclref[1 .. @$srclref-2]); &flush_file_lines(); &unlock_file($virt->{'file'}); &$second_print($text{'setup_done'}); &restart_apache(); return 1; } 1; virtual-server/feature-webalizer.pl0100664000567100000120000001327310042050641017503 0ustar jcameronwheel $feature_depends{'webalizer'} = [ 'web' ]; sub require_webalizer { return if ($require_webalizer++); &foreign_require("webalizer", "webalizer-lib.pl"); %wconfig = &foreign_config("webalizer"); } # setup_webalizer(&domain) # Setup the Webalizer module for this domain, and create a Cron job to run it sub setup_webalizer { &$first_print($text{'setup_webalizer'}); &require_webalizer(); local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'}); if (!$alog) { &$second_print($text{'setup_nolog'}); return; } # Create directory for stats local ($hdir) = ($config{'html_dir'} || 'public_html'); local ($sdir) = ($config{'stats_dir'} || 'stats'); local $stats = "$_[0]->{'home'}/$hdir/$sdir"; if (!-d $stats) { &system_logged("mkdir '$stats' 2>/dev/null"); &system_logged("chmod 755 '$stats'"); &system_logged("chown $_[0]->{'uid'}:$_[0]->{'ugid'} '$stats'"); } # Set up config for log in Webalizer module local $lcn = &webalizer::log_config_name($alog); if (!-r $lcn) { &lock_file($lcn); $lconf = { 'dir' => $stats, 'sched' => 1, 'type' => 0, 'over' => 0, 'clear' => 1, 'user' => $_[0]->{'user'}, 'mins' => int(rand()*60), 'hours' => 0, 'days' => '*', 'months' => '*', 'weekdays' => '*' }; &webalizer::save_log_config($alog, $lconf); &unlock_file($lcn); # Create a custom webalizer.conf for the site # Copy webalizer.conf into place for site, and update local $cfile = &webalizer::config_file_name($alog); &lock_file($cfile); system("cp $wconfig{'webalizer_conf'} $cfile"); local $wconf = &webalizer::get_config($alog); &webalizer::save_directive($wconf, "HistoryName", "$stats/webalizer.hist"); &webalizer::save_directive($wconf, "IncrementalName", "$stats/webalizer.current"); &webalizer::save_directive($wconf, "Incremental", "yes"); &webalizer::save_directive($wconf, "LogFile", $alog); &webalizer::save_directive($wconf, "HostName", $_[0]->{'dom'}); &flush_file_lines(); &unlock_file($cfile); &system_logged("chown $_[0]->{'user'}:$_[0]->{'group'} $cfile"); } else { $lconf = &webalizer::get_log_config($alog); } &foreign_require("cron", "cron-lib.pl"); local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $alog" } &cron::list_cron_jobs(); if (!$job) { # Create a Cron job to process the log &setup_webalizer_cron($lconf, $alog); } &$second_print($text{'setup_done'}); } # setup_webalizer_cron(&lconf, access-log) sub setup_webalizer_cron { local ($lconf, $alog) = @_; local $job = { 'user' => 'root', 'active' => 1, 'mins' => $lconf->{'mins'}, 'hours' => $lconf->{'hours'}, 'days' => $lconf->{'days'}, 'months' => $lconf->{'months'}, 'weekdays' => $lconf->{'weekdays'}, 'command' => "$webalizer::cron_cmd $alog" }; if (!-r $webalizer::cron_cmd) { &lock_file($webalizer::cron_cmd); &cron::create_wrapper($webalizer::cron_cmd, "webalizer", "webalizer.pl"); &unlock_file($webalizer::cron_cmd); } &lock_file(&cron::cron_file($job)); &cron::create_cron_job($job); &unlock_file(&cron::cron_file($job)); } # modify_webalizer(&domain, &olddomain) # Nothing to do here sub modify_webalizer { } # delete_webalizer(&domain) # Delete the Webalizer config files and Cron job sub delete_webalizer { &$first_print($text{'delete_webalizer'}); &require_webalizer(); local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'}); return if (!$alog); # Delete config files #local $lfile = &webalizer::log_config_name($alog); #unlink($lfile); #local $cfile = &webalizer::config_file_name($alog); #unlink($cfile); # Turn off cron job for webalizer config &foreign_require("cron", "cron-lib.pl"); local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $alog" } &cron::list_cron_jobs(); if ($job) { &lock_file(&cron::cron_file($job)); &cron::delete_cron_job($job); &unlock_file(&cron::cron_file($job)); } &$second_print($text{'setup_done'}); } # check_webalizer_clash() # Does nothing, because the web clash check is all that is needed sub check_webalizer_clash { return 0; } sub enable_webalizer { # Does nothing yet } sub disable_webalizer { # Does nothing yet } # backup_webalizer(&domain, file) # Saves the server's Webalizer config file, module config file and schedule sub backup_webalizer { &$first_print($text{'backup_webalizercp'}); &require_webalizer(); local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'}); if (!$alog) { &$second_print($text{'setup_nolog'}); return 0; } else { local $lcn = &webalizer::log_config_name($alog); system("cp ".quotemeta($lcn)." ".quotemeta($_[1])); local $cfile = &webalizer::config_file_name($alog); system("cp ".quotemeta($cfile)." ".quotemeta($_[1])."_conf"); &$second_print($text{'setup_done'}); return 1; } } # restore_webalizer(&domain, file) # Copies back the server's Webalizer config files, and re-sets up the Cron job sub restore_webalizer { &$first_print($text{'restore_webalizercp'}); &require_webalizer(); local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'}); if (!$alog) { &$second_print($text{'setup_nolog'}); return 0; } else { local $lcn = &webalizer::log_config_name($alog); &lock_file($lcn); system("cp ".quotemeta($_[1])." ".quotemeta($lcn)); &unlock_file($lcn); local $cfile = &webalizer::config_file_name($alog); &lock_file($cfile); system("cp ".quotemeta($_[1])."_conf"." ".quotemeta($cfile)); &unlock_file($cfile); &foreign_require("cron", "cron-lib.pl"); local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $alog" } &cron::list_cron_jobs(); if ($job) { &lock_file(&cron::cron_file($job)); &cron::delete_cron_job($job); } local $lconf = &webalizer::get_log_config($alog); &setup_webalizer_cron($lconf, $alog); &$second_print($text{'setup_done'}); return 1; } } 1; virtual-server/feature-mail.pl0100664000567100000120000007200310041666670016453 0ustar jcameronwheelsub require_mail { return if ($require_mail++); if ($config{'mail_system'} == 1) { # Using sendmail for email &foreign_require("sendmail", "sendmail-lib.pl"); &foreign_require("sendmail", "virtusers-lib.pl"); &foreign_require("sendmail", "aliases-lib.pl"); &foreign_require("sendmail", "boxes-lib.pl"); %sconfig = &foreign_config("sendmail"); $sendmail_conf = &sendmail::get_sendmailcf(); $sendmail_vfile = &sendmail::virtusers_file($sendmail_conf); ($sendmail_vdbm, $sendmail_vdbmtype) = &sendmail::virtusers_dbm($sendmail_conf); $sendmail_afiles = &sendmail::aliases_file($sendmail_conf); if ($config{'generics'}) { &foreign_require("sendmail", "generics-lib.pl"); $sendmail_gfile = &sendmail::generics_file($sendmail_conf); ($sendmail_gdbm, $sendmail_gdbmtype) = &sendmail::generics_dbm($sendmail_conf); } } elsif ($config{'mail_system'} == 0) { # Using postfix for email &foreign_require("postfix", "postfix-lib.pl"); &foreign_require("postfix", "boxes-lib.pl"); %pconfig = &foreign_config("postfix"); $virtual_type = $postfix::virtual_maps || "virtual_maps"; $virtual_maps = &postfix::get_real_value($virtual_type); @virtual_map_files = &postfix::get_maps_files($virtual_maps); $postfix_afiles = [ &postfix::get_aliases_files( &postfix::get_real_value("alias_maps")) ]; if ($config{'generics'}) { $canonical_type = "sender_canonical_maps"; $canonical_maps = &postfix::get_real_value($canonical_type); @canonical_map_files =&postfix::get_maps_files($canonical_maps); } } elsif ($config{'mail_system'} == 2) { # Using qmail for email &foreign_require("qmailadmin", "qmail-lib.pl"); %qmconfig = &foreign_config("qmailadmin"); $can_alias_types{2} = 0; $can_alias_types{7} = 0; } } # list_domain_aliases(&domain) sub list_domain_aliases { &require_mail(); local $g = $_[0]->{'group'}; local ($u, %foruser); foreach $u (&list_domain_users($_[0])) { local $pop3 = &remove_userdom($u->{'user'}, $_[0]); $foruser{$pop3."\@".$_[0]->{'dom'}} = $u->{'user'}; } if ($d->{'mailbox'}) { $foruser{$d->{'user'}."\@".$_[0]->{'dom'}} = $d->{'user'}; } local @virts = &list_virtusers(); return grep { $_->{'from'} =~ /\@(\S+)$/ && $1 eq $_[0]->{'dom'} && ($foruser{$_->{'from'}} ne $_->{'to'}->[0] || @{$_->{'to'}} != 1) } @virts; } # setup_mail(&domain) # Adds a domain to the list of those accepted by the mail system sub setup_mail { &$first_print($text{'setup_doms'}); &require_mail(); if ($config{'mail_system'} == 1) { # Just add to sendmail local domains file local $cwfile = &sendmail_locals_file(); &lock_file($cwfile); open(LOCALS, ">>$cwfile"); print LOCALS $_[0]->{'dom'},"\n"; close(LOCALS); &unlock_file($cwfile); &sendmail::restart_sendmail(); } elsif ($config{'mail_system'} == 0) { # Add a special postfix virtual entry just for the domain &create_virtuser({ 'from' => $_[0]->{'dom'}, 'to' => [ 'anything' ] }); } elsif ($config{'mail_system'} == 2) { # Add to qmail locals file, rcpthosts file and virtualdomains file local $dlist = &qmailadmin::list_control_file("locals"); push(@$dlist, $_[0]->{'dom'}); &qmailadmin::save_control_file("locals", $dlist); local $rlist = &qmailadmin::list_control_file("rcpthosts"); push(@$rlist, $_[0]->{'dom'}); &qmailadmin::save_control_file("rcpthosts", $rlist); local $virtmap = { 'domain' => $_[0]->{'dom'}, 'prepend' => $_[0]->{'group'} }; &qmailadmin::create_virt($virtmap); &qmailadmin::restart_qmail(); } &$second_print($text{'setup_done'}); } # delete_mail(&domain) # Removes a domain from the list of those accepted by the mail system sub delete_mail { &$first_print($text{'delete_doms'}); &require_mail(); if ($config{'mail_system'} == 1) { # Delete domain from sendmail local domains file local $cwfile = &sendmail_locals_file(); &lock_file($cwfile); local @locals; open(LOCALS, $cwfile); while() { s/\r|\n//; push(@locals, "$_\n") if ($_ ne $_[0]->{'dom'}); } close(LOCALS); open(LOCALS, ">$cwfile"); print LOCALS @locals; close(LOCALS); &unlock_file($cwfile); &sendmail::restart_sendmail(); } elsif ($config{'mail_system'} == 0) { # Delete the special postfix virtuser local @virts = &list_virtusers(); local ($lv) = grep { $_->{'from'} eq $_[0]->{'dom'} } @virts; if ($lv) { &delete_virtuser($lv); } local @md = split(/[, ]+/,&postfix::get_current_value("mydestination")); local $idx = &indexof($_[0]->{'dom'}, @md); if ($idx >= 0) { # Delete old-style entry too &lock_file($postfix::config{'postfix_config_file'}); splice(@md, $idx, 1); &postfix::set_current_value("mydestination", join(", ", @md)); &unlock_file($postfix::config{'postfix_config_file'}); &shutdown_mail_server(); &startup_mail_server(); } } elsif ($config{'mail_system'} == 2) { # Delete domain from qmail locals file, rcpthosts file and virtuals local $dlist = &qmailadmin::list_control_file("locals"); $dlist = [ grep { $_ ne $_[0]->{'dom'} } @$dlist ]; &qmailadmin::save_control_file("locals", $dlist); local $rlist = &qmailadmin::list_control_file("rcpthosts"); $rlist = [ grep { $_ ne $_[0]->{'dom'} } @$rlist ]; &qmailadmin::save_control_file("rcpthosts", $rlist); local ($virtmap) = grep { $_->{'domain'} eq $_[0]->{'dom'} && !$_->{'user'} } &qmailadmin::list_virts(); &qmailadmin::delete_virt($virtmap) if ($virtmap); &qmailadmin::restart_qmail(); } &$second_print($text{'setup_done'}); } # modify_mail(&domain, &olddomain) # Deal with a change in domain name sub modify_mail { if ($_[0]->{'dom'} ne $_[1]->{'dom'}) { &delete_mail($_[1]); &setup_mail($_[0]); } } # disable_mail(&domain) # Same as deleting .. sub disable_mail { &delete_mail($_[0]); } # enable_mail(&domain) # Same as setting up .. sub enable_mail { &setup_mail($_[0]); } # check_mail_clash() # Does nothing, because no clash checking is needed sub check_mail_clash { return 0; } # is_local_domain(domain) # Returns 1 if some domain is used for mail on this system, 0 if not sub is_local_domain { local $found = 0; if ($config{'mail_system'} == 1) { # Check Sendmail local domains file local $cwfile = &sendmail_locals_file(); open(CW, $cwfile); while() { s/\r|\n//; $found++ if ($_ eq $_[0]); } close(CW); } elsif ($config{'mail_system'} == 0) { # Check Postfix virtusers and mydestination local @virts = &list_virtusers(); local ($lv) = grep { $_->{'from'} eq $_[0] } @virts; $found++ if ($lv); local @md = split(/[, ]+/,&postfix::get_current_value("mydestination")); $found++ if (&indexof($_[0], @md) >= 0); } elsif ($config{'mail_system'} == 2) { # Check qmail local domains file local $dlist = &qmailadmin::list_control_file("locals"); $found++ if (&indexof($_[0], @$dlist) >= 0); } return $found; } sub sendmail_locals_file { local $conf = &sendmail::get_sendmailcf(); local ($f, $cwfile); foreach $f (&sendmail::find_type("F", $conf)) { if ($f->{'value'} =~ /^w[^\/]*(\/\S+)/ || $f->{'value'} =~ /^\{w\}[^\/]*(\/\S+)/) { $cwfile = $1; } } return $cwfile; } # list_virtusers() # Returns a list of a virtual mail address mappings. Each may actually have # an alias as its destination, and is automatically expanded to the destinations # for that alias. sub list_virtusers { # Build list of unix users, to exclude aliases with same name as users # (which are picked up by list_domain_users instead). &require_mail(); if (!defined(%unix_users)) { local $u; setpwent(); while($u = getpwent()) { $unix_user{$u}++; } endpwent(); } if ($config{'mail_system'} == 1) { # Get from sendmail local @svirts = &sendmail::list_virtusers($sendmail_vfile); local %aliases = map { $_->{'name'}, $_ } grep { $_->{'enabled'} && !$unix_user{$_->{'name'}} } &sendmail::list_aliases($sendmail_afiles); local ($v, $a, @virts); foreach $v (@svirts) { local %rv = ( 'virt' => $v, 'from' => $v->{'from'} ); if ($v->{'to'} !~ /\@/ && ($a = $aliases{$v->{'to'}})) { # Points to an alias - use its values $rv{'to'} = $a->{'values'}; $rv{'alias'} = $a; } else { # Just the original value $rv{'to'} = [ $v->{'to'} ]; } push(@virts, \%rv); } return @virts; } elsif ($config{'mail_system'} == 0) { # Get from postfix local $svirts = &postfix::get_maps($virtual_type); local %aliases = map { $_->{'name'}, $_ } grep { $_->{'enabled'} && !$unix_user{$_->{'name'}} } &postfix::list_aliases($postfix_afiles); local ($v, $a, @virts); foreach $v (@$svirts) { local %rv = ( 'from' => $v->{'name'}, 'virt' => $v ); if ($v->{'value'} !~ /\@/ && ($a = $aliases{$v->{'value'}})) { $rv{'to'} = $a->{'values'}; $rv{'alias'} = $a; } else { $rv{'to'} = [ $v->{'value'} ]; } push(@virts, \%rv); } return @virts; } elsif ($config{'mail_system'} == 2) { # Find all qmail aliases like .qmail-group-user local @virtmaps = grep { !$_->{'user'} } &qmailadmin::list_virts(); local @aliases = &qmailadmin::list_aliases(); local ($an, $v, @virts); foreach $an (@aliases) { # Find domain in virtual maps local $a = &qmailadmin::get_alias($an); local $name = $a->{'name'}; foreach $v (@virtmaps) { if ($a->{'name'} =~ /^\Q$v->{'prepend'}\E\-(.*)$/) { $name = $1."\@".$v->{'domain'}; } } # XXX need to change alias types? push(@virts, { 'from' => $name, 'alias' => $a, 'to' => [ map { s/^\&//; $_ } @{$a->{'values'}} ] }); } return @virts; } } # delete_virtuser(&virtuser) # Deletes a virtual mail user mapping sub delete_virtuser { &require_mail(); if ($config{'mail_system'} == 1) { # Delete from sendmail if ($_[0]->{'alias'}) { # Delete alias too &lock_file($_[0]->{'alias'}->{'file'}); &sendmail::delete_alias($_[0]->{'alias'}); &unlock_file($_[0]->{'alias'}->{'file'}); } &lock_file($_[0]->{'virt'}->{'file'}); &sendmail::delete_virtuser($_[0]->{'virt'}, $sendmail_vfile, $sendmail_vdbm, $sendmail_vdbmtype); &unlock_file($_[0]->{'virt'}->{'file'}); } elsif ($config{'mail_system'} == 0) { # Delete from postfix file if ($_[0]->{'alias'}) { # Delete alias too &lock_file($_[0]->{'alias'}->{'file'}); &postfix::delete_alias($_[0]->{'alias'}); &unlock_file($_[0]->{'alias'}->{'file'}); &postfix::regenerate_aliases(); } &lock_file($_[0]->{'virt'}->{'file'}); &postfix::delete_mapping($virtual_type, $_[0]->{'virt'}); &unlock_file($_[0]->{'virt'}->{'file'}); &postfix::regenerate_virtual_table(); } elsif ($config{'mail_system'} == 2) { # Just delete the qmail alias &qmailadmin::delete_alias($_[0]->{'alias'}); } } # modify_virtuser(&old, &new) sub modify_virtuser { &require_mail(); local @to = @{$_[1]->{'to'}}; if ($config{'mail_system'} == 1) { # Modify in sendmail local $alias = $_[0]->{'alias'}; if (&needs_alias(@to) && !$alias) { # Alias needs to be created and virtuser updated $_[1]->{'from'} =~ /^(\S*)\@(\S+)$/; local $an = ($1 || "default")."-".$2; local $alias = { "name" => $an, "enabled" => 1, "values" => \@to }; &sendmail::lock_alias_files($sendmail_afiles); &sendmail::create_alias($alias, $sendmail_afiles); &sendmail::unlock_alias_files($sendmail_afiles); local $virt = { "from" => $_[1]->{'from'}, "to" => $an }; &lock_file($_[0]->{'virt'}->{'file'}); &sendmail::modify_virtuser($_[0]->{'virt'}, $virt, $sendmail_vfile, $sendmail_vdbm, $sendmail_vdbmtype); &unlock_file($_[0]->{'virt'}->{'file'}); $_[0]->{'virt'} = $virt; } elsif ($alias) { # Just update alias and maybe virtuser $alias->{'values'} = \@to; &lock_file($alias->{'file'}); &sendmail::modify_alias($alias, $alias); &unlock_file($alias->{'file'}); if ($_[1]->{'from'} ne $_[0]->{'from'}) { # Re-named .. need to change too local $virt = { "from" => $_[1]->{'from'}, "to" => $_[0]->{'virt'}->{'to'} }; &lock_file($_[0]->{'virt'}->{'file'}); &sendmail::modify_virtuser($_[0]->{'virt'}, $virt, $sendmail_vfile, $sendmail_vdbm, $sendmail_vdbmtype); &unlock_file($_[0]->{'virt'}->{'file'}); $_[0]->{'virt'} = $virt; } } else { # Just update virtuser local $virt = { "from" => $_[1]->{'from'}, "to" => $_[1]->{'to'}->[0] }; &lock_file($_[0]->{'virt'}->{'file'}); &sendmail::modify_virtuser($_[0]->{'virt'}, $virt, $sendmail_vfile, $sendmail_vdbm, $sendmail_vdbmtype); &unlock_file($_[0]->{'virt'}->{'file'}); $_[0]->{'virt'} = $virt; } } elsif ($config{'mail_system'} == 0) { # Modify in postfix file local $alias = $_[0]->{'alias'}; if (&needs_alias(@to) && !$alias) { # Alias needs to be created and virtuser updated $_[0]->{'from'} =~ /^(\S*)\@(\S+)$/; local $an = ($1 || "default")."-".$2; local $alias = { "name" => $an, "enabled" => 1, "values" => \@to }; &sendmail::lock_alias_files($postfix_afiles); &postfix::create_alias($alias, $postfix_afiles); &sendmail::unlock_alias_files($postfix_afiles); &postfix::regenerate_aliases(); local $virt = { "name" => $_[1]->{'from'}, "value" => $an }; &lock_file($_[0]->{'virt'}->{'file'}); &postfix::modify_mapping($virtual_type, $_[0]->{'virt'}, $virt); &unlock_file($_[0]->{'virt'}->{'file'}); $_[0]->{'virt'} = $virt; &postfix::regenerate_virtual_table(); } elsif ($alias) { # Just update alias $alias->{'values'} = \@to; &lock_file($alias->{'file'}); &postfix::modify_alias($alias, $alias); &unlock_file($alias->{'file'}); &postfix::regenerate_aliases(); if ($_[1]->{'from'} ne $_[0]->{'from'}) { # Re-named .. need to change virtuser too local $virt = { "name" => $_[1]->{'from'}, "value" => $_[1]->{'virt'}->{'value'} }; &lock_file($_[0]->{'virt'}->{'file'}); &postfix::modify_mapping($virtual_type, $_[0]->{'virt'}, $virt); &unlock_file($_[0]->{'virt'}->{'file'}); $_[0]->{'virt'} = $virt; &postfix::regenerate_virtual_table(); } } else { # Just update virtuser local $virt = { "name" => $_[1]->{'from'}, "value" => $_[1]->{'to'}->[0] }; &lock_file($_[0]->{'virt'}->{'file'}); &postfix::modify_mapping($virtual_type, $_[0]->{'virt'}, $virt); &unlock_file($_[0]->{'virt'}->{'file'}); $_[0]->{'virt'} = $virt; &postfix::regenerate_virtual_table(); } } elsif ($config{'mail_system'} == 2) { # Just update the qmail alias $_[1]->{'from'} =~ /^(\S*)\@(\S+)$/; local ($box, $dom) = ($1, $2); local ($virtmap) = grep { $_->{'domain'} eq $dom && !$_->{'user'} } &qmailadmin::list_virts(); local $alias = { 'name' => "$virtmap->{'prepend'}-$box", 'values' => \@to }; &qmailadmin::modify_alias($_[0]->{'alias'}, $alias); $_[1]->{'alias'} = $alias; } } # create_virtuser(&virtuser) # Creates a new virtual mail mapping sub create_virtuser { &require_mail(); local @to = @{$_[0]->{'to'}}; if ($config{'mail_system'} == 1) { # Create in sendmail local $virt; if (&needs_alias(@to)) { # Need to create an alias, named address-domain $_[0]->{'from'} =~ /^(\S*)\@(\S+)$/; local $an = ($1 || "default")."-".$2; &check_alias_clash($an) && &error(&text('alias_eclash2', $an)); local $alias = { "name" => $an, "enabled" => 1, "values" => \@to }; &sendmail::lock_alias_files($sendmail_afiles); &sendmail::create_alias($alias, $sendmail_afiles); &sendmail::unlock_alias_files($sendmail_afiles); $virt = { "from" => $_[0]->{'from'}, "to" => $an }; } else { # A single virtuser will do $virt = { "from" => $_[0]->{'from'}, "to" => $_[0]->{'to'}->[0] }; } &lock_file($sendmail_vfile); &sendmail::create_virtuser($virt, $sendmail_vfile, $sendmail_vdbm, $sendmail_vdbmtype); &unlock_file($sendmail_vfile); $_[0]->{'virt'} = $virt; } elsif ($config{'mail_system'} == 0) { # Create in postfix file if (&needs_alias(@to)) { # Need to create an alias, named address-domain $_[0]->{'from'} =~ /^(\S*)\@(\S+)$/; local $an = ($1 || "default")."-".$2; &check_alias_clash($an) && &error(&text('alias_eclash2', $an)); local $alias = { "name" => $an, "enabled" => 1, "values" => \@to }; &postfix::lock_alias_files($postfix_afiles); &postfix::create_alias($alias, $postfix_afiles); &postfix::unlock_alias_files($postfix_afiles); &postfix::regenerate_aliases(); $virt = { 'name' => $_[0]->{'from'}, 'value' => $an }; } else { # A single virtuser will do $virt = { 'name' => $_[0]->{'from'}, 'value' => $_[0]->{'to'}->[0] }; } &lock_file($virtual_map_files[0]); &postfix::create_mapping($virtual_type, $virt); &unlock_file($virtual_map_files[0]); &postfix::regenerate_virtual_table(); $_[0]->{'virt'} = $virt; } elsif ($config{'mail_system'} == 2) { # Create a single Qmail alias $_[0]->{'from'} =~ /^(\S*)\@(\S+)$/; local ($box, $dom) = ($1, $2); local ($virtmap) = grep { $_->{'domain'} eq $dom && !$_->{'user'} } &qmailadmin::list_virts(); local $alias = { 'name' => "$virtmap->{'prepend'}-$box", 'values' => \@to }; &qmailadmin::create_alias($alias); $_[0]->{'alias'} = $alias; } } # needs_alias(list..) sub needs_alias { return 1 if (@_ != 1); local $t; foreach $t (@_) { return 1 if (&alias_type($t) != 1); } return 0; } # join_alias(list..) sub join_alias { return join(',', map { /\s/ ? "\"$_\"" : $_ } @_); } # is_mail_running() # Returns 1 if the configured mail server is running, 0 if not sub is_mail_running { &require_mail(); if ($config{'mail_system'} == 1) { # Check the sendmail PID local $pid; open(PID, $sconfig{'sendmail_pid'}) || return 0; chop($pid = ); close(PID); return kill(0, $pid); } elsif ($config{'mail_system'} == 0) { # Call the postfix module return &postfix::is_postfix_running(); } elsif ($config{'mail_system'} == 2) { # Just look for qmail-send local ($pid) = &find_byname("qmail-send"); return $pid ? 1 : 0; } } # shutdown_mail_server() # Shuts down the mail server, or calls &error sub shutdown_mail_server { &require_mail(); if ($config{'mail_system'} == 1) { # Kill or stop sendmail if ($sconfig{'sendmail_stop_command'}) { $out = &backquote_logged("$sconfig{'sendmail_stop_command'} &1"); if ($?) { &error("
$out
"); } } else { local $pid; open(PID, $sconfig{'sendmail_pid'}) || &error($text{'mstop_edown'}); chop($pid = ); close(PID); &kill_logged('KILL', $pid) || &error($text{'mstop_edown'}); unlink($sconfig{'sendmail_pid'}); } } elsif ($config{'mail_system'} == 0) { # Run the postfix stop command $out = &backquote_logged("$pconfig{'postfix_control_command'} -c $postfix::config_dir stop 2>&1"); if ($?) { &error("$out"); } } } # startup_mail_server() # Starts up the mail server, or calls &error sub startup_mail_server { &require_mail(); if ($config{'mail_system'} == 1) { # Run the sendmail start command $out = &backquote_logged("$sconfig{'sendmail_command'} &1"); if ($?) { &error("
$out
"); } } elsif ($config{'mail_system'} == 0) { # Run the postfix start command $out = &backquote_logged("$pconfig{'postfix_control_command'} -c $postfix::config_dir start 2>&1"); if ($?) { &error("$out"); } } } # delete_mail_file(&user) sub delete_mail_file { &require_mail(); if ($config{'mail_system'} == 1) { # Just remove the Sendmail mail file unlink(&sendmail::user_mail_file($_[0]->{'user'})); } elsif ($config{'mail_system'} == 0) { # Find out from Postfix which file to delete local $s = &postfix::postfix_mail_system(); unlink(&postfix::postfix_mail_file($_[0]->{'user'})); } elsif ($config{'mail_system'} == 2) { # Find out from Qmail which file to delete unlink(&qmailadmin::user_mail_dir($_[0]->{'user'})); } } # rename_mail_file(&user, oldname) sub rename_mail_file { return if (&mail_under_home()); &require_mail(); if ($config{'mail_system'} == 1) { # Just rename the Sendmail mail file (if necessary) local $of = &sendmail::user_mail_file($_[1]); local $nf = &sendmail::user_mail_file($_[0]->{'user'}); rename($of, $nf); } elsif ($config{'mail_system'} == 0) { # Find out from Postfix which file to rename (if necessary) local $newumf = &postfix::postfix_mail_file($_[0]->{'user'}); local $oldumf = &postfix::postfix_mail_file($_[1]); rename($oldumf, $newumf); } elsif ($config{'mail_system'} == 2) { # Just rename the Qmail mail file (if necessary) local $of = &qmailadmin::user_mail_file($_[1]); local $nf = &qmailadmin::user_mail_file($_[0]->{'user'}); rename($of, $nf); } } # mail_under_home() # Returns 1 if mail is stored under use home directories sub mail_under_home { &require_mail(); if ($config{'mail_system'} == 1) { return !$sconfig{'mail_dir'}; } elsif ($config{'mail_system'} == 0) { local $s = &postfix::postfix_mail_system(); return $s != 0; } elsif ($config{'mail_system'} == 2) { return $qmconfig{'mail_system'} != 0 || !$qmconfig{'mail_dir'}; } } # user_mail_file(&user) # Returns the full path a user's mail file sub user_mail_file { &require_mail(); if ($config{'mail_system'} == 1) { # Just look at the Sendmail mail file return &sendmail::user_mail_file($_[0]->{'user'}); } elsif ($config{'mail_system'} == 0) { # Find out from Postfix which file to check return &postfix::postfix_mail_file($_[0]->{'user'}); } elsif ($config{'mail_system'} == 2) { # Find out from Qmail which file or dir to check return &qmailadmin::user_mail_dir($_[0]->{'user'}); } return undef; } # mail_file_size(&user) sub mail_file_size { &require_mail(); local $umf = &user_mail_file($_[0]); if (-d $umf) { # Need to sum up a maildir-format directory local $sz = 0; foreach $d ("$umf/cur", "$umf/new", "$umf/tmp") { opendir(DIR, $d) || last; foreach $f (readdir(DIR)) { local @st = stat("$d/$f"); $sz += $st[7]; } closedir(DIR); } return ( $sz, $umf ); } else { # Just the size of a single mail file local @st = stat($umf); return ( int($st[7]), $umf ); } } # mail_system_base() # Returns the base directory under which user mail files can be found sub mail_system_base { &require_mail(); if ($config{'mail_system'} == 1) { # Find out from sendmail module config if ($sconfig{'mail_dir'}) { return $sconfig{'mail_dir'}; } } elsif ($config{'mail_system'} == 0) { # Find out from postfix local @s = &postfix::postfix_mail_system(); if ($s[0] == 0) { return $s[1]; } } elsif ($config{'mail_system'} == 2) { # Find out from qmail module config if ($qmconfig{'mail_system'} == 0 && $qmconfig{'mail_dir'}) { return $qmconfig{'mail_dir'}; } } # If we get here, assume that mail is under home dirs local %uconfig = &foreign_config("useradmin"); return $home_base; } # read_mail_link(&user) sub read_mail_link { local %acl; &read_acl(\%acl); if (&foreign_check("mailboxes") && $acl{$base_remote_user,'mailboxes'}) { # Use mailboxes module if possible local %mconfig = &foreign_config("mailboxes"); if ($mconfig{'mail_system'} == $config{'mail_system'}) { return "../mailboxes/list_mail.cgi?user=".$_[0]->{'user'}; } } if ($config{'mail_system'} == 1 && $acl{$base_remote_user,'sendmail'} && &get_webmin_version() <= 1.140) { return "../sendmail/list_mail.cgi?user=".$_[0]->{'user'}; } elsif ($config{'mail_system'} == 0 && $acl{$base_remote_user,'postfix'} && &get_webmin_version() <= 1.140) { return "../postfix/list_mail.cgi?user=".$_[0]->{'user'}; } elsif ($config{'mail_system'} == 2 && $acl{$base_remote_user,'qmailadmin'} && &get_webmin_version() <= 1.140) { return "../qmailadmin/list_mail.cgi?user=".$_[0]->{'user'}; } else { return undef; } } # postfix_installed() # Returns 1 if postfix is installed sub postfix_installed { return &foreign_installed("postfix", 1) == 2; } # sendmail_installed() # Returns 1 if postfix is installed sub sendmail_installed { return &foreign_installed("sendmail", 1) == 2; } # qmail_installed() # Returns 1 if qmail is installed sub qmail_installed { return &foreign_installed("qmailadmin", 1) == 2; } # check_alias_clash(name) # Checks if an alias with the given name already exists sub check_alias_clash { &require_mail(); if ($config{'mail_system'} == 1) { local @aliases = &sendmail::list_aliases($sendmail_afiles); local ($clash) = grep { lc($_->{'name'}) eq lc($_[0]) } @aliases; return $clash; } elsif ($config{'mail_system'} == 0) { local @aliases = &postfix::list_aliases($postfix_afiles); local ($clash) = grep { lc($_->{'name'}) eq lc($_[0]) } @aliases; return $clash; } return undef; } # backup_mail(&domain, file, &options) # Saves all mail aliases and mailbox users for this domain sub backup_mail { &require_mail(); # Create dummy file open(FILE, ">$_[1]"); close(FILE); # Build file of all virtusers. Each line contains one virtuser address and # it's destinations, in alias-style format &$first_print($text{'backup_mailaliases'}); open(AFILE, ">$_[1]_aliases"); local $a; foreach $a (&list_domain_aliases($_[0])) { print AFILE $a->{'from'},": "; print AFILE join(",", @{$a->{'to'}}),"\n"; } close(AFILE); &$second_print($text{'setup_done'}); # Build file of all mailboxes. Each user has a passwd-file style line with # the email address and quotas appended, followed by a list of destination # addresses. &$first_print($text{'backup_mailusers'}); open(UFILE, ">$_[1]_users"); local $u; foreach $u (&list_domain_users($_[0])) { print UFILE join(":", $u->{'user'}, $u->{'pass'}, $u->{'uid'}, $u->{'gid'}, $u->{'real'}, $u->{'home'}, $u->{'shell'}, $u->{'email'}); if ($config{'home_quotas'}) { print UFILE ":$user->{'quota'}"; if ($config{'mail_quotas'} && $config{'home_quotas'} ne $config{'mail_quotas'}) { print UFILE ":$user->{'mquota'}"; } } print UFILE "\n"; print UFILE join(",", @{$u->{'to'}}),"\n"; } close(UFILE); &$second_print($text{'setup_done'}); if (!&mail_under_home() && $_[2]->{'mailfiles'}) { # Backup actual mail files too.. local $mbase = &mail_system_base(); local @mfiles; &$first_print($text{'backup_mailfiles'}); foreach $u (&list_domain_users($_[0])) { local $umf = &user_mail_file($u); if ($umf =~ s/^$mbase\///) { push(@mfiles, $umf) if (-r "$mbase/$umf"); } } local $mfiles = join(" ", map { quotemeta($_) } @mfiles); local $out = `cd '$mbase'; tar cf '$_[1]_files' $mfiles 2>&1`; if ($?) { &$second_print(&text('backup_mailfilesfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); } } return 1; } # restore_mail(&domain, file, &options) sub restore_mail { # Delete all mailboxes (but not home dirs) and re-create &$first_print($text{'restore_mailusers'}); foreach $u (&list_domain_users($_[0], 1)) { &delete_user($u); } open(UFILE, "$_[1]_users"); while() { s/\r|\n//g; local @user = split(/:/, $_); $_ = ; s/\r|\n//g; local @to = split(/,/, $_); if ($user[0] eq $_[0]->{'user'}) { # Domain owner, just update alias list local @users = &list_domain_users($_[0]); local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'}} @users; local %old = %$uinfo; $uinfo->{'email'} = $user[7]; $uinfo->{'extraemail'} = \@to; &modify_user($uinfo, \%old, $_[0]); } else { # Need to create user local $uinfo = { 'user' => $user[0], 'pass' => $user[1], 'uid' => $user[2], 'gid' => $_[0]->{'gid'}, 'real' => $user[4], 'home' => $user[5], 'shell' => $user[6], 'email' => $user[7], 'extraemail' => \@to }; &create_user($uinfo); if ($config{'home_quotas'} && $user[8]) { &set_quota($user[0], $config{'home_quotas'}, $user[8]); } if ($config{'mail_quotas'} && $user[9] && $config{'mail_quotas'} ne $config{'home_quotas'}) { &set_quota($user[0], $config{'mail_quotas'}, $user[9]); } } } close(UFILE); &$second_print($text{'setup_done'}); # Delete all aliases and re-create &$first_print($text{'restore_mailaliases'}); local $a; foreach $a (&list_domain_aliases($_[0])) { &delete_virtuser($a); } open(AFILE, "$_[1]_aliases"); while() { if (/^(\S+):\s*(.*)/) { local $virt = { 'from' => $1, 'to' => [ split(/,/, $2) ] }; &create_virtuser($virt); } } close(AFILE); &$second_print($text{'setup_done'}); if (!&mail_under_home() && -r "$_[1]_files" && $_[2]->{'mailfiles'}) { # Extract all mail files local $mbase = &mail_system_base(); &$first_print($text{'restore_mailfiles'}); local $out = `cd '$mbase' && tar xf '$_[1]_files' 2>&1`; if ($?) { &$second_print(&text('backup_mailfilesfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); } } return 1; } # show_backup_mail(&options) # Returns HTML for mail backup option inputs sub show_backup_mail { if (&mail_under_home()) { # Option makes no sense in this case, as the home directories backup # will catch it return ""; } else { # Offer to backup mail files return sprintf "( %s)", $opts{'mailfiles'} ? "checked" : "", $text{'backup_mailfiles2'}; } } # parse_backup_mail(&in) # Parses the inputs for mail backup options sub parse_backup_mail { local %in = %{$_[0]}; return { 'mailfiles' => $in{'mail_mailfiles'} }; } # show_restore_mail(&options) # Returns HTML for mail restore option inputs sub show_restore_mail { if (&mail_under_home()) { # Option makes no sense in this case, as the home directories backup # will catch it return ""; } else { # Offer to restore mail files return sprintf "( %s)", $opts{'mailfiles'} ? "checked" : "", $text{'restore_mailfiles2'}; } } # parse_restore_mail(&in) # Parses the inputs for mail backup options sub parse_restore_mail { local %in = %{$_[0]}; return { 'mailfiles' => $in{'mail_mailfiles'} }; } 1; virtual-server/feature-dns.pl0100664000567100000120000003301410041666311016304 0ustar jcameronwheelsub require_bind { return if ($require_bind++); &foreign_require("bind8", "bind8-lib.pl"); %bconfig = &foreign_config("bind8"); } # setup_dns(&domain) # Set up a zone for a domain sub setup_dns { &$first_print($text{'setup_bind'}); local $rootcfile = &bind8::make_chroot($bconfig{'named_conf'}); &lock_file($rootcfile); local $conf = &bind8::get_config(); local $base = $bconfig{'master_dir'} ? $bconfig{'master_dir'} : &bind8::base_directory($conf); local $format = $bconfig{'forwardzonefilename_format'}; $format =~ s/ZONE/$_[0]->{'dom'}/g; local $file = $base."/".$format; local $dir = { 'name' => 'zone', 'values' => [ $_[0]->{'dom'} ], 'type' => 1, 'members' => [ { 'name' => 'type', 'values' => [ 'master' ] }, { 'name' => 'file', 'values' => [ $file ] } ] }; local $pconf = &bind8::get_config_parent(); &bind8::save_directive($pconf, undef, [ $dir ], 0); &flush_file_lines(); &unlock_file($rootcfile); # Create the records file local %zd; &bind8::get_zone_defaults(\%zd); local $rootfile = &bind8::make_chroot($file); if (!-r $rootfile) { &lock_file($rootfile); local $serial = $bconfig{'soa_style'} ? &bind8::date_serial()."00" : time(); if (!$config{'bind_replace'}) { # Create records that are appropriate for this domain open(RECS, ">$rootfile"); print RECS "\$ttl $zd{'minimum'}$zd{'minunit'}\n" if ($bconfig{'master_ttl'}); close(RECS); local $master = $bconfig{'default_prins'} || &get_system_hostname(); $master .= "." if ($master !~ /\.$/); local $email = $bconfig{'tmpl_email'} || "root\@$master"; $email = &bind8::email_to_dotted($email); local $soa = "$master $email (\n". "\t\t\t$serial\n". "\t\t\t$zd{'refresh'}$zd{'refunit'}\n". "\t\t\t$zd{'retry'}$zd{'retunit'}\n". "\t\t\t$zd{'expiry'}$zd{'expunit'}\n". "\t\t\t$zd{'minimum'}$zd{'minunit'} )"; &bind8::create_record($file, "@", undef, "IN", "SOA", $soa); &bind8::create_record($file, "@", undef, "IN", "NS", $master); if ($bconfig{'default_slave'}) { my $slave = $bconfig{'default_slave'}; $slave .= "." if ($slave !~ /\.$/); &bind8::create_record($file, "@", undef, "IN", "NS", $slave); } &bind8::create_record($file, "@", undef, "IN", "A", $_[0]->{'ip'}); &bind8::create_record($file, "www", undef, "IN", "A", $_[0]->{'ip'}); &bind8::create_record($file, "ftp", undef, "IN", "A", $_[0]->{'ip'}); if ($_[0]->{'mail'}) { &bind8::create_record($file, "mail", undef, "IN", "A", $_[0]->{'ip'}); &bind8::create_record($file, "@", undef, "IN", "MX", "5 mail"); } } if ($config{'bind_config'}) { # Add or use the user-defined template open(RECS, ">>$rootfile"); local %subs = %{$_[0]}; $subs{'serial'} = $serial; local $recs = &substitute_template( join("\n", split(/\t+/, $config{'bind_config'}))."\n", \%subs); print RECS $recs; close(RECS); } &bind8::set_ownership($rootfile); &unlock_file($rootfile); } &$second_print($text{'setup_done'}); # Create on slave server local $slave = $bconfig{'default_slave'}; if ($slave) { &$first_print(&text('setup_bindslave', $slave)); &remote_error_setup(\&slave_error_handler); &remote_foreign_require($slave, "bind8", "bind8-lib.pl"); if ($slave_error) { # Failed to connect! Just tell user and continue &$second_print(&text('setup_eslave', $slave_error)); return; } local $sparent = &remote_foreign_call($slave, "bind8", "get_config_parent"); local $sconfig = &remote_foreign_config($slave, "bind8"); local $sconf = $sparent->{'members'}; local $opts = &bind8::find("options", $sconf); if (!$opts) { &$second_print(&text('setup_eslave', &bind8::text('master_eslave', $slave))); return; } foreach $z (&bind8::find("zone", $sconf)) { if ($z->{'value'} eq $_[0]->{'dom'}) { &$second_print(&text('setup_eslave', &bind8::text('master_etaken'))); return; } } local $masters = { 'name' => 'masters', 'type' => 1, 'members' => [ { 'name' => $bconfig{'this_ip'} || &to_ipaddress(&get_system_hostname()) } ] }; local $dir = { 'name' => 'zone', 'values' => [ $_[0]->{'dom'} ], 'type' => 1, 'members' => [ { 'name' => 'type', 'values' => [ 'slave' ] }, $masters ] }; local $sbase = $sconfig->{'slave_dir'} ? $sconfig->{'slave_dir'} : &remote_foreign_call($slave, "bind8", "base_directory", $sconf); local $file = $sbase."/".$_[0]->{'dom'}.".hosts"; push(@{$dir->{'members'}}, { 'name' => 'file', 'values' => [ $file ] } ); &remote_foreign_call($slave, "bind8", "save_directive", $sparent, undef, [ $dir ], 0); &remote_foreign_call($slave, "bind8", "flush_file_lines"); $_[0]->{'dns_slave'} = $slave; &$second_print($text{'setup_done'}); } &restart_bind(); } sub slave_error_handler { $slave_error = $_[0]; } # delete_dns(&domain) # Delete a domain from the BIND config sub delete_dns { &$first_print($text{'delete_bind'}); &require_bind(); local $z = &get_bind_zone($_[0]->{'dom'}); if ($z) { # Delete the records file local $file = &bind8::find("file", $z->{'members'}); if ($file) { local $zonefile = &bind8::make_chroot($file->{'values'}->[0]); &lock_file($zonefile); unlink($zonefile); &unlock_file($zonefile); } # Delete from named.conf local $rootfile = &bind8::make_chroot($z->{'file'}); &lock_file($rootfile); local $lref = &read_file_lines($rootfile); splice(@$lref, $z->{'line'}, $z->{'eline'} - $z->{'line'} + 1); &flush_file_lines(); &unlock_file($rootfile); &$second_print($text{'setup_done'}); } else { &$second_print($text{'save_nobind'}); } local $slave = $_[0]->{'dns_slave'}; if ($slave) { # Delete from slave server too &$first_print(&text('delete_bindslave', $slave)); &remote_error_setup(\&slave_error_handler); &remote_foreign_require($slave, "bind8", "bind8-lib.pl"); if ($slave_error) { &$second_print(&text('setup_eslave', $slave_error)); return; } local $sparent = &remote_foreign_call($slave, "bind8", "get_config_parent"); local $sconf = $sparent->{'members'}; local ($z, $szconf); foreach $z (&bind8::find("zone", $sconf)) { $szconf = $z if ($z->{'value'} eq $_[0]->{'dom'}); } if (!$szconf) { &$second_print(&text('setup_eslave', &bind8::text('delete_ezone'))); return; } &remote_foreign_call($slave, "bind8", "save_directive", $sparent, [ $szconf ], [ ]); &remote_foreign_call($slave, "bind8", "flush_file_lines"); delete($_[0]->{'dns_slave'}); &$second_print($text{'setup_done'}); } &restart_bind(); } # modify_dns(&domain, &olddomain) # If the IP for this server has changed, update all records containing the old # IP to the new. sub modify_dns { &require_bind(); local $z = &get_bind_zone($_[0]->{'dom'}); if ($_[0]->{'ip'} ne $_[1]->{'ip'}) { # IP address has changed .. need to update any records that use # the old IP &$first_print($text{'save_dns'}); local $file = &bind8::find("file", $z->{'members'}); local $zonefile = &bind8::make_chroot($file); &lock_file($zonefile); local $fn = $file->{'values'}->[0]; local @recs = &bind8::read_zone_file($fn, $_[1]->{'dom'}); foreach $r (@recs) { if ($r->{'values'}->[0] eq $_[1]->{'ip'}) { &bind8::modify_record($fn, $r, $r->{'name'}, $r->{'ttl'}, $r->{'class'}, $r->{'type'}, $_[0]->{'ip'}, $r->{'comment'}); } } # Update SOA record &bind8::bump_soa_record($fn, \@recs); &unlock_file($zonefile); $rv++; &$second_print($text{'setup_done'}); } &restart_bind() if ($rv); return $rv; } # disable_dns(&domain) # Re-names this domain in named.conf with the .disabled suffix sub disable_dns { &$first_print($text{'disable_dns'}); &require_bind(); local $z = &get_bind_zone($_[0]->{'dom'}); if ($z) { local $rootfile = &bind8::make_chroot($z->{'file'}); &lock_file($rootfile); $z->{'values'}->[0] = $_[0]->{'dom'}.".disabled"; &bind8::save_directive(&bind8::get_config_parent(), [ $z ], [ $z ], 0); &flush_file_lines(); &unlock_file($rootfile); &$second_print($text{'setup_done'}); &restart_bind(); } else { &$second_print($text{'save_nobind'}); } } # enable_dns(&domain) # Re-names this domain in named.conf to remove the .disabled suffix sub enable_dns { &$first_print($text{'enable_dns'}); &require_bind(); local $z = &get_bind_zone($_[0]->{'dom'}); if ($z) { local $rootfile = &bind8::make_chroot($z->{'file'}); &lock_file($rootfile); $z->{'values'}->[0] = $_[0]->{'dom'}; &bind8::save_directive(&bind8::get_config_parent(), [ $z ], [ $z ], 0); &flush_file_lines(); &unlock_file($rootfile); &$second_print($text{'setup_done'}); &restart_bind(); } else { &$second_print($text{'save_nobind'}); } } # get_bind_zone(name) # Returns the zone structure for the named domain, possibly with .disabled sub get_bind_zone { &require_bind(); local $conf = &bind8::get_config(); local @zones = &bind8::find("zone", $conf); local ($v, $z); foreach $v (&bind8::find("view", $conf)) { push(@zones, &bind8::find("zone", $v->{'members'})); } local ($z) = grep { $_->{'value'} eq $_[0] || $_->{'value'} eq "$_[0].disabled" } @zones; return $z; } # restart_bind(&domain) # Signal BIND to re-load its configuration sub restart_bind { &$first_print($text{'setup_bindpid'}); local $pid = &get_bind_pid(); if ($pid) { if ($bconfig{'restart_cmd'}) { &system_logged("$bconfig{'restart_cmd'} >/dev/null 2>&1 {'dns_slave'} || $bconfig{'default_slave'}; if ($slave) { # Re-start on slave too &$first_print(&text('setup_bindslavepid', $slave)); &remote_error_setup(\&slave_error_handler); &remote_foreign_require($slave, "bind8", "bind8-lib.pl"); if ($slave_error) { # Failed to connect! Just tell user and continue &$second_print(&text('setup_eslave', $slave_error)); return $rv; } # Find remote PID file local $sconfig = &remote_foreign_config($slave, "bind8"); local $sconf = &remote_foreign_call($slave, "bind8", "get_config"); local $pidfile; if (($opts = &bind8::find("options", $sconf)) && ($pidopt = &bind8::find("pid-file", $opts->{'members'}))) { # read from PID file $pidfile = $pidopt->{'value'}; if ($pidfile !~ /^\//) { local $dir = &bind8::find("directory", $opts->{'members'}); $pidfile = $dir->{'value'}."/".$pidfile; } } else { # use default file $pidfile = $sconfig->{'pid_file'} ? $sconfig->{'pid_file'} : "/var/run/named.pid"; } # Read the PID and restart $pid = &remote_eval($slave, "bind8", <); close(PID); return \$pid; EOF ); if (!$pid) { &$second_print($text{'setup_notrun'}); return $rv; } &remote_eval($slave, "bind8", "kill('HUP', $pid) ? \$! : 0"); &$second_print($text{'setup_done'}); } return $rv; } # check_dns_clash(domain, db, user) # Returns 1 if a domain already exists in BIND sub check_dns_clash { local ($czone) = &get_bind_zone($_[0]); return $czone ? 1 : 0; } # get_bind_pid() sub get_bind_pid { &require_bind(); local ($pidfile, $opts, $pidopt); if (defined(&bind8::get_pid_file)) { $pidfile = &bind8::get_pid_file(); } else { local $conf = &bind8::get_config(); if (($opts = &bind8::find("options", $conf)) && ($pidopt = &bind8::find("pid-file", $opts->{'members'}))) { # read from PID file $pidfile = $pidopt->{'value'}; if ($pidfile !~ /^\//) { local $dir = &bind8::find( "directory", $opts->{'members'}); $pidfile = $dir->{'value'}."/".$pidfile; } } else { # use default file $pidfile = -r &bind8::make_chroot($bconfig{'pid_file'}) ? $bconfig{'pid_file'} : "/var/run/named.pid"; } } open(PID, &bind8::make_chroot($pidfile)) || return undef; chop($pid = ); close(PID); return $pid; } # backup_dns(&domain, file) # Save all the virtual server's DNS records as a separate file sub backup_dns { &require_bind(); &$first_print($text{'backup_dnscp'}); local $z = &get_bind_zone($_[0]->{'dom'}); if ($z) { local $file = &bind8::find("file", $z->{'members'}); local $filename = &bind8::make_chroot($file->{'values'}->[0]); system("cp ".quotemeta($filename)." ".quotemeta($_[1])); &$second_print($text{'setup_done'}); return 1; } else { &$second_print($text{'backup_dnsnozone'}); return 0; } } # restore_dns(&domain, file) # Update the virtual server's DNS records from the backup file, except the SOA sub restore_dns { &require_bind(); &$first_print($text{'restore_dnscp'}); local $z = &get_bind_zone($_[0]->{'dom'}); if ($z) { local $file = &bind8::find("file", $z->{'members'}); local $filename = &bind8::make_chroot($file->{'values'}->[0]); local $srclref = &read_file_lines($_[1]); local $dstlref = &read_file_lines($filename); &lock_file($filename); local ($srcstart, $srcend) = &except_soa($_[0], $_[1]); local ($dststart, $dstend) = &except_soa($_[0], $filename); splice(@$dstlref, $dststart, $dstend - $dststart + 1, @$srclref[$srcstart .. $srcend]); &flush_file_lines(); # Need to bump SOA local @recs = &bind8::read_zone_file($file->{'values'}->[0], $_[0]->{'dom'}); &bind8::bump_soa_record($file->{'values'}->[0], \@recs); &unlock_file($filename); &$second_print($text{'setup_done'}); &restart_bind(); return 1; } else { &$second_print($text{'backup_dnsnozone'}); return 0; } } # except_soa(&domain, file) sub except_soa { local $bind8::config{'chroot'} = "/"; # make sure path is absolute local @recs = &bind8::read_zone_file($_[1], $_[0]->{'dom'}); foreach $r (@recs) { if ($r->{'type'} ne "SOA" && !defined($start)) { $start = $r->{'line'}; } $end = $r->{'eline'}; } return ($start, $end); } 1; virtual-server/feature-ssl.pl0100664000567100000120000001364210042202003016307 0ustar jcameronwheel $feature_depends{'ssl'} = [ 'web', 'virt' ]; $web_sslport = $config{'web_sslport'} || 443; # setup_ssl(&domain) # Creates a website with SSL enabled, and a private key and cert it to use. sub setup_ssl { &require_apache(); local $conf = &apache::get_config(); if ($apache::config{'virt_file'}) { $f = -d $apache::config{'virt_file'} ? "$apache::config{'virt_file'}/www.$_[0]->{'dom'}.conf" : $apache::config{'virt_file'}; } else { $vconf = &apache::get_virtual_config(); $f = $vconf->[0]->{'file'}; } &lock_file($f); # Create a self-signed cert and key, if needed $_[0]->{'ssl_cert'} ||= "$_[0]->{'home'}/ssl.cert"; $_[0]->{'ssl_key'} ||= "$_[0]->{'home'}/ssl.key"; if (!-r $_[0]->{'ssl_cert'} && !-r $_[0]->{'ssl_key'}) { # Need to do it local $temp = &tempname(); &$first_print($text{'setup_openssl'}); &lock_file($_[0]->{'ssl_cert'}); &lock_file($_[0]->{'ssl_key'}); open(CA, "| openssl req -newkey rsa:512 -x509 -nodes -out $_[0]->{'ssl_cert'} -keyout $_[0]->{'ssl_key'} -days 1825 >$temp 2>&1"); print CA ".\n"; print CA ".\n"; print CA ".\n"; print CA "$_[0]->{'owner'}\n"; print CA ".\n"; print CA "www.$_[0]->{'dom'}\n"; print CA ($_[0]->{'email'} || "."),"\n"; close(CA); local $rv = $?; local $out = `cat $temp`; unlink($temp); if (!-r $_[0]->{'ssl_cert'} || !-r $_[0]->{'ssl_key'} || $?) { chown($_[0]->{'uid'}, $_[0]->{'ugid'}, $_[0]->{'ssl_cert'}, $_[0]->{'ssl_key'}); chmod(0755, $_[0]->{'ssl_cert'}, $_[0]->{'ssl_key'}); &$second_print(&text('setup_eopenssl', "
$out
")); } else { &$second_print($text{'setup_done'}); } &unlock_file($_[0]->{'ssl_cert'}); &unlock_file($_[0]->{'ssl_key'}); } # Add the actual &$first_print($text{'setup_ssl'}); local @dirs = &apache_template($config{'apache_config'}, $_[0]); open(FILE, ">>$f"); print FILE "{'ip'}:$web_sslport>\n"; foreach (@dirs) { print FILE $_,"\n"; } print FILE "SSLEngine on\n"; print FILE "SSLCertificateFile $_[0]->{'ssl_cert'}\n"; print FILE "SSLCertificateKeyFile $_[0]->{'ssl_key'}\n"; print FILE "\n"; close(FILE); &unlock_file($f); undef(@apache::get_config_cache); &$second_print($text{'setup_done'}); &restart_apache(1); $_[0]->{'web_sslport'} = $web_sslport; } # modify_ssl(&domain, &olddomain) sub modify_ssl { # Does nothing (yet) return 0; } # delete_ssl(&domain) # Deletes the SSL virtual server from the Apache config sub delete_ssl { &require_apache(); local $conf = &apache::get_config(); &$first_print($text{'delete_ssl'}); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_sslport'}); if ($virt) { &delete_virtual_server($virt); &$second_print($text{'setup_done'}); &restart_apache(1); } else { &$second_print($text{'delete_noapache'}); } undef(@apache::get_config_cache); } # check_web_clash(domain, db, user) # Returns 1 if an SSL Apache webserver already exists for some domain sub check_ssl_clash { local ($cvirt, $cconf) = &get_apache_virtual($_[0], $web_sslport); return $cvirt ? 1 : 0; } # disable_ssl(&domain) # Adds a directive to force all requests to show an error page sub disable_ssl { &$first_print($text{'disable_ssl'}); &require_apache(); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_sslport'}); if ($virt) { &create_disable_directives($virt, $vconf); &$second_print($text{'setup_done'}); &restart_apache(); } else { &$second_print($text{'delete_noapache'}); } } # enable_ssl(&domain) sub enable_ssl { &$first_print($text{'enable_ssl'}); &require_apache(); local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_sslport'}); if ($virt) { &remove_disable_directives($virt, $vconf); &$second_print($text{'setup_done'}); &restart_apache(); } else { &$second_print($text{'delete_noapache'}); } } # backup_ssl(&domain, file) # Save the SSL virtual server's Apache config as a separate file sub backup_ssl { &$first_print($text{'backup_sslcp'}); # Save the apache directives local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_sslport'}); local $lref = &read_file_lines($virt->{'file'}); local $l; open(FILE, ">$_[1]"); foreach $l (@$lref[$virt->{'line'} .. $virt->{'eline'}]) { print FILE "$l\n"; } close(FILE); # Save the cert and key, if any local $cert = &apache::find_directive("SSLCertificateFile", $vconf, 1); if ($cert) { system("cp ".quotemeta($cert)." ".quotemeta("$_[1]_cert")); } local $key = &apache::find_directive("SSLCertificateKeyFile", $vconf, 1); if ($key && $key ne $cert) { system("cp ".quotemeta($key)." ".quotemeta("$_[1]_key")); } &$second_print($text{'setup_done'}); return 1; } # restore_ssl(&domain, file) # Update the SSL virtual server's Apache configuration from a file. Does not # change the actual lines! sub restore_ssl { &$first_print($text{'restore_sslcp'}); # Restore the Apache directives local ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_sslport'}); local $srclref = &read_file_lines($_[1]); local $dstlref = &read_file_lines($virt->{'file'}); &lock_file($virt->{'file'}); splice(@$dstlref, $virt->{'line'}+1, $virt->{'eline'}-$virt->{'line'}-1, @$srclref[1 .. @$srclref-2]); &flush_file_lines(); &unlock_file($virt->{'file'}); # Restore the cert and key, if any and if saved undef(@apache::get_config_cache); ($virt, $vconf) = &get_apache_virtual($_[0]->{'dom'}, $_[0]->{'web_sslport'}); local $cert = &apache::find_directive("SSLCertificateFile", $vconf, 1); if ($cert && -r "$_[1]_cert") { &lock_file($cert); system("cp ".quotemeta("$_[1]_cert")." ".quotemeta($cert)); &unlock_file($cert); } local $key = &apache::find_directive("SSLCertificateKeyFile", $vconf, 1); if ($key && -r "$_[1]_key" && $key ne $cert) { &lock_file($key); system("cp ".quotemeta("$_[1]_key")." ".quotemeta($key)); &unlock_file($key); } &$second_print($text{'setup_done'}); &restart_apache(); return 1; } 1; virtual-server/feature-mysql.pl0100664000567100000120000001306510041667056016700 0ustar jcameronwheelsub require_mysql { return if ($require_mysql++); &foreign_require("mysql", "mysql-lib.pl"); %mconfig = &foreign_config("mysql"); } # setup_mysql(&domain) # Create a new MySQL database, user and permissions sub setup_mysql { &$first_print($text{'setup_mysql'}); &require_mysql(); $_[0]->{'mysql_user'} = &mysql_user($_[0]); local $user = $_[0]->{'mysql_user'}; &mysql::execute_sql_logged($mysql::master_db, "create database $_[0]->{'db'}"); local @hosts = split(/\s+/, $config{'mysql_hosts'}); @hosts = ( 'localhost' ) if (!@hosts); local $h; foreach $h (@hosts) { &mysql::execute_sql_logged($mysql::master_db, "insert into user (host, user, password) values ('$h', '$user', password('$_[0]->{'pass'}'))"); &mysql::execute_sql_logged($mysql::master_db, "insert into db (host, db, user, select_priv, insert_priv, update_priv, delete_priv, create_priv, drop_priv, grant_priv, references_priv, index_priv, alter_priv) values ('$h', '$_[0]->{'db'}', '$user', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y')"); } &mysql::execute_sql_logged($mysql::master_db, 'flush privileges'); &$second_print($text{'setup_done'}); } # delete_mysql(&domain) # Delete a mysql database, the domain's mysql user and all permissions for both sub delete_mysql { &$first_print($text{'delete_mysql'}); &require_mysql(); local $user = &mysql_user($_[0]); &mysql::execute_sql_logged($mysql::master_db, "drop database $_[0]->{'db'}"); &mysql::execute_sql_logged($mysql::master_db, "delete from user where user = '$user'"); &mysql::execute_sql_logged($mysql::master_db, "delete from db where user = '$user' or db = '$_[0]->{'db'}'"); &mysql::execute_sql_logged($mysql::master_db, 'flush privileges'); &$second_print($text{'setup_done'}); } # modify_mysql(&domain, &olddomain) # Changes the mysql user's password if needed sub modify_mysql { &require_mysql(); local $user = &mysql_user($_[0]); if ($_[0]->{'pass'} ne $_[1]->{'pass'}) { &$first_print($text{'save_mysqlpass'}); if (&mysql_user_exists($_[0])) { &mysql::execute_sql_logged($mysql::master_db, "update user set password = password('$_[0]->{'pass'}') where user = '$user'"); &mysql::execute_sql_logged($master_db, 'flush privileges'); &$second_print($text{'setup_done'}); return 1; } else { &$first_print($text{'save_nomysql'}); } } return 0; } # disable_mysql(&domain) # Modifies the mysql user for this domain so that he cannot login sub disable_mysql { &$first_print($text{'disable_mysqluser'}); &require_mysql(); local $user = &mysql_user($_[0]); if ($oldpass = &mysql_user_exists($_[0])) { &mysql::execute_sql_logged($mysql::master_db, "update user set password = '*LK*' where user = '$user'"); &mysql::execute_sql_logged($master_db, 'flush privileges'); $_[0]->{'disabled_oldmysql'} = $oldpass; &$second_print($text{'setup_done'}); } else { &$second_print($text{'save_nomysql'}); } } # enable_mysql(&domain) # Puts back the original password for the mysql user so that he can login again sub enable_mysql { &$first_print($text{'enable_mysql'}); &require_mysql(); local $user = &mysql_user($_[0]); if (&mysql_user_exists($_[0])) { if ($_[0]->{'disabled_oldmysql'}) { &mysql::execute_sql_logged($mysql::master_db, "update user set password = '$_[0]->{'disabled_oldmysql'}' where user = '$user'"); delete($_[0]->{'disabled_oldmysql'}); } else { &mysql::execute_sql_logged($mysql::master_db, "update user set password = password('$_[0]->{'pass'}') where user = '$user'"); } &mysql::execute_sql($master_db, 'flush privileges'); &$second_print($text{'setup_done'}); } else { &$second_print($text{'save_nomysql'}); } } # mysql_user_exists(&domain) # Returns his password if a mysql user exists for the domain's user, or undef sub mysql_user_exists { &require_mysql(); local $user = &mysql_user($_[0]); local $u = &mysql::execute_sql_logged($mysql::master_db, "select password from user where user = '$user'"); return @{$u->{'data'}} ? $u->{'data'}->[0]->[0] : undef; } # check_mysql_clash(domain, db, user) # Returns 1 if some MySQL database already exists sub check_mysql_clash { &require_mysql(); local @dblist = &mysql::list_databases(); return &indexof($_[1], @dblist) >= 0; } # backup_mysql(&domain, file) # Dumps this domain's mysql database to a backup file sub backup_mysql { &$first_print($text{'backup_mysqldump'}); &require_mysql(); local $cmd = "$mysql::config{'mysqldump'} $mysql::authstr --add-drop-table". (&mysql::supports_quoting() ? " --quote-names" : ""). " $_[0]->{'db'} 2>&1 >$_[1]"; local $out = `$cmd`; if ($? || $out) { &$second_print(&text('backup_mysqldumpfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } # restore_mysql(&domain, file) # Restores this domain's mysql database from a backup file, and re-creates # the mysql user. sub restore_mysql { &$first_print($text{'restore_mysqlload'}); { local $first_print = \&null_print; # supress messages local $second_print = \&null_print; &require_mysql(); # First clear out the database if (&check_mysql_clash($_[0]->{'dom'}, $_[0]->{'db'}, $_[0]->{'user'})) { &delete_mysql($_[0]); } # Now re-set it up &setup_mysql($_[0]); } # Finally, import the data local $cmd = "$mysql::config{'mysql'} $mysql::authstr -t $_[0]->{'db'} <$_[1] 2>&1"; local $out = &backquote_logged($cmd); if ($? || $out) { &$second_print(&text('restore_mysqlloadfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } # mysql_user(&domain) sub mysql_user { return $_[0]->{'mysql_user'} if (defined($_[0]->{'mysql_user'})); return length($_[0]->{'user'}) > 16 ? substr($_[0]->{'user'}, 0, 16) : $_[0]->{'user'}; } 1; virtual-server/feature-postgres.pl0100664000567100000120000001035510041667062017375 0ustar jcameronwheelsub require_postgres { return if ($require_postgres++); &foreign_require("postgresql", "postgresql-lib.pl"); %qconfig = &foreign_config("postgresql"); } # check_postgres_clash(domain, db, user) # Returns 1 if some PostgreSQL database already exists sub check_postgres_clash { &require_postgres(); local @dblist = &postgresql::list_databases(); return &indexof($_[1], @dblist) >= 0; } # setup_postgres(&domain) # Create a new PostgreSQL database and user sub setup_postgres { &$first_print($text{'setup_postgres'}); &require_postgres(); &postgresql::execute_sql_logged($qconfig{'basedb'}, "create database $_[0]->{'db'}"); local $pass = &postgresql::get_postgresql_version() >= 7 ? "'$_[0]->{'pass'}'" : $_[0]->{'pass'}; &postgresql::execute_sql_logged($qconfig{'basedb'}, "create user \"$_[0]->{'user'}\" with password $pass nocreatedb nocreateuser"); &$second_print($text{'setup_done'}); } # modify_postgres(&domain, &olddomain) # Change the PostgreSQL user's password if needed sub modify_postgres { &require_postgres(); if ($_[0]->{'pass'} ne $_[1]->{'pass'}) { &$first_print($text{'save_postgrespass'}); local $pass = &postgresql::get_postgresql_version() >= 7 ? "'$_[0]->{'pass'}'" : $_[0]->{'pass'}; &postgresql::execute_sql_logged($qconfig{'basedb'}, "alter user \"$_[0]->{'user'}\" with password $pass"); &$second_print($text{'setup_done'}); } } # delete_postgres(&domain) # Delete the PostgreSQL database and user sub delete_postgres { &$first_print($text{'delete_postgres'}); &require_postgres(); &postgresql::execute_sql_logged($qconfig{'basedb'}, "drop database $_[0]->{'db'}"); &postgresql::execute_sql_logged($qconfig{'basedb'}, "drop user \"$_[0]->{'user'}\""); &$second_print($text{'setup_done'}); } # disable_postgres(&domain) # Invalidate the domain's PostgreSQL user sub disable_postgres { &$first_print($text{'disable_postgres'}); &require_postgres(); local $date = localtime(0); &postgresql::execute_sql_logged($qconfig{'basedb'}, "alter user \"$_[0]->{'user'}\" valid until '$date'"); &$second_print($text{'setup_done'}); } # enable_postgres(&domain) # Validate the domain's PostgreSQL user sub enable_postgres { &$first_print($text{'enable_postgres'}); &require_postgres(); &postgresql::execute_sql_logged($qconfig{'basedb'}, "alter user \"$_[0]->{'user'}\" valid until 'Jan 1 2038'"); &$second_print($text{'setup_done'}); } # backup_postgres(&domain, file) # Dumps this domain's postgreSQL database to a backup file sub backup_postgres { &$first_print($text{'backup_postgresdump'}); &require_postgres(); &foreign_require("proc", "proc-lib.pl"); local $pass = &tempname(); open(PASS, ">$pass"); print PASS "$postgresql::postgres_pass\n"; close(PASS); local $cmd = $postgresql::config{'dump_cmd'}. ($postgresql::postgres_login ? " -U $postgresql::postgres_login" : ""). ($postgresql::config{'host'} ? " -h $postgresql::config{'host'}" : ""). " -F c -b -f $_[1] $_[0]->{'db'} 2>&1 <$pass"; local $out = `$cmd`; unlink($pass); if ($?) { &$second_print(&text('backup_postgresdumpfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } # restore_postgres(&domain, file) # Restores this domain's postgresql database from a backup file, and re-creates # the postgresql user. sub restore_postgres { &$first_print($text{'restore_postgresload'}); &require_postgres(); &foreign_require("proc", "proc-lib.pl"); { local $first_print = \&null_print; # supress messages local $second_print = \&null_print; &require_mysql(); # First clear out the database if (&check_postgres_clash($_[0]->{'dom'}, $_[0]->{'db'}, $_[0]->{'user'})) { &delete_postgres($_[0]); } # Now re-set it up &setup_postgres($_[0]); } # Finally, import the data local $pass = &tempname(); open(PASS, ">$pass"); print PASS "$postgresql::postgres_pass\n"; close(PASS); local $cmd = $postgresql::config{'rstr_cmd'}. ($postgresql::postgres_login ? " -U $postgresql::postgres_login" : ""). ($postgresql::config{'host'} ? " -h $postgresql::config{'host'}" : ""). " -d $_[0]->{'db'} $_[1] <$pass 2>&1"; local $out = &backquote_logged($cmd); unlink($pass); if ($? || $out =~ /failed|fatal/i) { &$second_print(&text('restore_mysqlloadfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } 1; virtual-server/feature-webmin.pl0100664000567100000120000002634510041655733017020 0ustar jcameronwheelsub require_acl { return if ($require_acl++); &foreign_require("acl", "acl-lib.pl"); } # setup_webmin(&domain) # Creates a new user to manage this domain, with access to the appropriate # modules with the right permissions sub setup_webmin { &$first_print($text{'setup_webmin'}); &require_acl(); local @modules; local %wuser = ( 'name' => $_[0]->{'user'}, 'pass' => 'x', 'notabs' => 1, 'modules' => [ ], 'theme' => $config{'webmin_theme'} eq '*' ? undef : $config{'webmin_theme'} eq '' ? '' : $config{'webmin_theme'} ); &acl::create_user(\%wuser); &set_user_modules($_[0], \%wuser); &$second_print($text{'setup_done'}); &restart_webmin(); } # delete_webmin(&domain) # Delete the webmin user for the domain, and all his permissions sub delete_webmin { &$first_print($text{'delete_webmin'}); &require_acl(); &acl::delete_user($_[0]->{'user'}); local $m; foreach $m (&get_all_module_infos()) { unlink("$config_directory/$m->{'dir'}/$_[0]->{'user'}.acl"); } &$second_print($text{'setup_done'}); &restart_webmin(); } # modify_webmin(&domain, &olddomain) sub modify_webmin { &$first_print($text{'save_webmin'}); &require_acl(); local ($wuser) = grep { $_->{'name'} eq $_[0]->{'user'} } &acl::list_users(); &set_user_modules($_[0], $wuser) if ($wuser); &$second_print($text{'setup_done'}); &restart_webmin(); return 1; } # disable_webmin(&domain) # Lock the password of the domains's Webmin user sub disable_webmin { &$first_print($text{'disable_webmin'}); &require_acl(); local ($wuser) = grep { $_->{'name'} eq $_[0]->{'user'} } &acl::list_users(); if ($wuser) { $wuser->{'pass'} = "*LK*"; &acl::modify_user($wuser->{'name'}, $wuser); &restart_webmin(); } &$second_print($text{'setup_done'}); } # enable_webmin(&domain) # Changes the password of the domain's Webmin user back to unix auth sub enable_webmin { &$first_print($text{'enable_webmin'}); &require_acl(); local ($wuser) = grep { $_->{'name'} eq $_[0]->{'user'} } &acl::list_users(); if ($wuser) { $wuser->{'pass'} = "x"; &acl::modify_user($wuser->{'name'}, $wuser); &restart_webmin(); } &$second_print($text{'setup_done'}); } # restart_webmin() sub restart_webmin { return if ($no_restart_webmin); &$first_print($text{'setup_webminpid'}); &restart_miniserv(); &$second_print($text{'setup_done'}); } # set_user_modules(&domain, &webminuser) sub set_user_modules { local @mods; local %hasmods = map { $_, 1 } @{$_[1]->{'modules'}}; %hasmods = ( ) if (!$config{'leave_acl'}); # Grant access to BIND module if needed if ($_[0]->{'dns'}) { # Allow user to manage just this domain push(@mods, "bind8"); local %acl = ( 'noconfig' => 1, 'zones' => $_[0]->{'dom'}, 'dir' => &resolve_links($_[0]->{'home'}), 'master' => 0, 'slave' => 0, 'forward' => 0, 'defaults' => 0, 'reverse' => 0, 'multiple' => 1, 'ro' => 0, 'apply' => 2, 'file' => 0, 'params' => 1, 'opts' => 0, 'delete' => 0, 'gen' => 1, 'whois' => 1, 'findfree' => 1, 'remote' => 0, 'views' => 0, 'vlist' => '' ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "bind8") if (!$hasmods{'bind8'}); } else { @mods = grep { $_ ne "bind8" } @mods; } # Grant access to MySQL module if needed if ($_[0]->{'mysql'}) { # Allow user to manage just the domain's DB push(@mods, "mysql"); local %acl = ( 'noconfig' => 1, 'dbs' => $_[0]->{'db'}, 'create' => 0, 'delete' => 0, 'stop' => 0, 'perms' => 0, 'edonly' => 0, 'user' => &mysql_user($_[0]), 'pass' => $_[0]->{'pass'}, 'buser' => $_[0]->{'user'}, 'bpath' => "/" ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "mysql") if (!$hasmods{'mysql'}); } else { @mods = grep { $_ ne "mysql" } @mods; } # Grant access to PostgreSQL module if needed if ($_[0]->{'postgres'}) { # Allow user to manage just the domain's DB push(@mods, "postgresql"); local %acl = ( 'noconfig' => 1, 'dbs' => $_[0]->{'db'}, 'create' => 0, 'delete' => 0, 'stop' => 0, 'users' => 0, 'user' => $_[0]->{'user'}, 'pass' => $_[0]->{'pass'}, 'sameunix' => 1, 'backup' => 1, 'restore' => 1 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "postgresql") if (!$hasmods{'postgresql'}); } else { @mods = grep { $_ ne "postgresql" } @mods; } # Grant access to Apache module if needed if ($_[0]->{'web'}) { # Allow user to manage just this website push(@mods, "apache"); local %acl = ( 'noconfig' => 1, 'virts' => "$_[0]->{'dom'} $_[0]->{'dom'}:$_[0]->{'web_port'}", 'global' => 0, 'create' => 0, 'vuser' => 0, 'vaddr' => 0, 'pipe' => 0, 'stop' => 0, 'dir' => &resolve_links($_[0]->{'home'}), 'test_always' => 1, 'types' => join(" ", (0 .. 7, 9 .. 16, 18 .. $apache::directive_type_count)) ); if ($_[0]->{'ssl'}) { $acl{'virts'} .= " $_[0]->{'dom'}:$_[0]->{'web_sslport'}"; } &save_module_acl_logged(\%acl, $_[1]->{'name'}, "apache") if (!$hasmods{'apache'}); } else { @mods = grep { $_ ne "apache" } @mods; } # Grant access to Webalizer module if needed if ($_[0]->{'webalizer'}) { push(@mods, "webalizer"); local %acl = ( 'noconfig' => 1, 'view' => 0, 'global' => 0, 'add' => 0, 'user' => $_[0]->{'user'}, 'dir' => &resolve_links(&get_apache_log($_[0]->{'dom'})) ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "webalizer") if (!$hasmods{'webalizer'}); } else { @mods = grep { $_ ne "webalizer" } @mods; } # Grant access to this module for managing its users and aliaes if ($_[0]->{'mail'}) { push(@mods, $module_name); local %acl = ( 'noconfig' => 1, 'edit' => 0, 'create' => 0, 'import' => 0, 'stop' => 0, 'local' => 0, 'domains' => $_[0]->{'id'} ); &save_module_acl_logged(\%acl, $_[1]->{'name'}) if (!$hasmods{'virtual-server'}); } else { @mods = grep { $_ ne "virtual-server" } @mods; } # Set global ACL options local %acl = ( 'feedback' => 0, 'desc_'.$module_name => $text{'index_title2'}, 'root' => &resolve_links($_[0]->{'home'}), 'rpc' => 0 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "."); local @extramods = map { /^avail_(\S+)/; $1 } grep { $config{$_} } grep { /^avail_/ } (keys %config); local %extramods = map { $_, $config{"avail_".$_} } grep { my $m=$_; { local $_; &foreign_check($m) } } @extramods; if ($extramods{'file'}) { # Limit file manager to user's directory local %acl = ( 'noconfig' => 1, 'uid' => -1, 'follow' => 0, 'root' => '', 'home' => 1, 'goto' => 1 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "file") if (!$hasmods{'file'}); push(@mods, "file"); } if ($extramods{'passwd'} == 1) { # Can only change his password local %acl = ( 'noconfig' => 1, 'mode' => 3, 'repeat' => 1, 'old' => 1, 'expire' => 0, 'others' => 1 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "passwd") if (!$hasmods{'passwd'}); push(@mods, "passwd"); } elsif ($extramods{'passwd'} == 2) { # Can change all mailbox passwords local %acl = ( 'noconfig' => 1, 'mode' => 5, 'users' => $_[0]->{'group'}, 'repeat' => 1, 'old' => 0, 'expire' => 0, 'others' => 1 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "passwd") if (!$hasmods{'passwd'}); push(@mods, "passwd"); } if ($extramods{'proc'}) { # Can only manage his own processes local %acl = ( 'noconfig' => 1, 'uid' => -1, 'edit' => 1, 'run' => 1 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "proc") if (!$hasmods{'proc'}); push(@mods, "proc"); } if ($extramods{'cron'}) { # Can only manage his cron jobs local %acl = ( 'noconfig' => 1, 'mode' => 3, 'allow' => 0 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "cron") if (!$hasmods{'cron'}); push(@mods, "cron"); } if ($extramods{'at'}) { # Can only manage his at jobs local %acl = ( 'noconfig' => 1, 'mode' => 3 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "at") if (!$hasmods{'at'}); push(@mods, "at"); } if ($extramods{'telnet'}) { # Cannot configure module local %acl = ( 'noconfig' => 1 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "telnet") if (!$hasmods{'telnet'}); push(@mods, "telnet"); } if ($extramods{'custom'}) { # Cannot edit and create commands local %acl = ( 'noconfig' => 1, 'cmd' => '*', 'edit' => 0 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "custom") if (!$hasmods{'custom'}); push(@mods, "custom"); } if ($extramods{'updown'}) { # Can upload and download to home dir only local %acl = ( 'noconfig' => 1, 'dirs' => '', 'home' => 1, 'mode' => 3 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "updown") if (!$hasmods{'updown'}); push(@mods, "updown"); # Set defaults for upload and download directories for this user local %udconfig; local $udfile = "$config_directory/updown/config"; &lock_file($udfile); &read_file($udfile, \%udconfig); $udfile{'dir_'.$_[1]->{'name'}} ||= &resolve_links($_[0]->{'home'}); $udfile{'ddir_'.$_[1]->{'name'}} ||= &resolve_links($_[0]->{'home'}); &write_file($udfile, \%udconfig); &unlock_file($udfile); } if ($extramods{'change-user'}) { # This module is always safe, so no ACL needs to be set push(@mods, "change-user"); } if ($extramods{'htaccess-htpasswd'}) { # Can create .htaccess files in home dir, as user local %acl = ( 'noconfig' => 1, 'dirs' => &resolve_links($_[0]->{'home'}), 'user' => '*' ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "htaccess-htpasswd") if (!$hasmods{'htaccess-htpasswd'}); push(@mods, "htaccess-htpasswd"); } if ($extramods{'mailboxes'} && $_[0]->{'mail'}) { # Can read mailboxes of users local %acl = ( 'noconfig' => 1, 'mmode' => 5, 'musers' => $_[0]->{'gid'}, 'fmode' => 1, 'from' => $_[0]->{'dom'}, 'canattach' => 0, 'candetach' => 0 ); &save_module_acl_logged(\%acl, $_[1]->{'name'}, "mailboxes") if (!$hasmods{'mailboxes'}); push(@mods, "mailboxes"); } else { @mods = grep { $_ ne "mailboxes" } @mods; } $_[1]->{'modules'} = [ &unique(@mods) ]; &acl::modify_user($_[1]->{'name'}, $_[1]); } # check_webmin_clash(domain, db, user) # Returns 1 if a user or group with this name already exists sub check_webmin_clash { &require_acl(); return 1 if ($_[2] eq 'webmin'); local $u; foreach $u (&acl::list_users(), &acl::list_groups()) { return 1 if ($u->{'name'} eq $_[2]); } return 0; } # modify_all_webmin() # Updates the Webmin users for all domains sub modify_all_webmin { &$first_print($text{'check_allwebmin'}); { local $first_print = sub { }; local $second_print = sub { }; local $no_restart_webmin = 1; local $d; foreach $d (&list_domains()) { if ($d->{'webmin'} && $config{'webmin'}) { &modify_webmin($d, $d); } } } &$second_print($text{'setup_done'}); &restart_webmin(); } # save_module_acl_logged(&acl, user, module) sub save_module_acl_logged { local $afile = "$config_directory/$_[2]/$_[1].acl"; &lock_file($afile); &save_module_acl(@_); &unlock_file($afile); } 1; virtual-server/feature-unix.pl0100664000567100000120000001615310041666722016516 0ustar jcameronwheel# Functions for managing a domain's Unix user # setup_unix(&domain) # Creates the Unix user and group for a domain sub setup_unix { # Create the group &require_useradmin(); &$first_print(&text('setup_group', $_[0]->{'group'})); &useradmin::lock_user_files(); local %ginfo = ( 'group', $_[0]->{'group'}, 'gid', $_[0]->{'gid'} ); &useradmin::set_group_envs(\%ginfo, 'CREATE_GROUP'); &useradmin::making_changes(); &useradmin::create_group(\%ginfo); &useradmin::made_changes(); if (!defined(getgrnam($_[0]->{'group'}))) { &second_print($text{'setup_ecrgroup'}); exit; } &$second_print($text{'setup_done'}); # Then the user &$first_print(&text('setup_user', $user)); local %uinfo = ( 'user', $_[0]->{'user'}, 'uid', $_[0]->{'uid'}, 'gid', $_[0]->{'ugid'}, 'pass', &useradmin::encrypt_password($_[0]->{'pass'}), 'real', $_[0]->{'owner'}, 'home', $_[0]->{'home'}, 'shell', $config{'unix_shell'} ); &set_pass_change(\%user); &useradmin::set_user_envs(\%uinfo, 'CREATE_USER', $_[0]->{'pass'}, [ ]); &useradmin::making_changes(); &useradmin::create_user(\%uinfo); &useradmin::made_changes(); &useradmin::unlock_user_files(); if (!defined(getpwnam($user))) { &second_print($text{'setup_ecruser'}); exit; } &$second_print($text{'setup_done'}); # Set the user's quota if ($config{'home_quotas'}) { &set_server_quotas($_[0]); } # Create and populate home directory &$first_print($text{'setup_home'}); &system_logged("mkdir '$uinfo{'home'}'"); &system_logged("chmod '$uconfig{'homedir_perms'}' '$uinfo{'home'}'"); &system_logged("chown $uinfo{'uid'}:$uinfo{'gid'} '$uinfo{'home'}'"); ©_skel_files($config{'virtual_skel'}, \%uinfo, $_[0]->{'group'}); # Setup web directories local $d; foreach $d ( [ $config{'html_dir'} || 'public_html', '755' ], [ 'cgi-bin', '755' ], [ 'logs', '755' ], [ 'homes', '755' ] ) { &system_logged("mkdir '$uinfo{'home'}/$d->[0]' 2>/dev/null"); &system_logged("chmod $d->[1] '$uinfo{'home'}/$d->[0]'"); &system_logged("chown $uinfo{'uid'}:$uinfo{'gid'} '$uinfo{'home'}/$d->[0]'"); } &$second_print($text{'setup_done'}); } # modify_unix(&domain, &olddomain) # Change the password and real name for a domain unix user sub modify_unix { &require_useradmin(); &useradmin::lock_user_files(); local @allusers = &useradmin::list_users(); local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers; if ($uinfo) { # Update the Unix user &$first_print($text{'save_user'}); $uinfo->{'real'} = $_[0]->{'owner'}; if ($_[0]->{'pass_set'}) { local $enc = &useradmin::encrypt_password($_[0]->{'pass'}); if ($d->{'disabled'}) { # Just keep for later use when enabling $d->{'disabled_oldpass'} = $enc; } else { # Set password now $uinfo->{'pass'} = $enc; } &set_pass_change($uinfo); } &useradmin::set_user_envs($uinfo, 'MODIFY_USER', $_[0]->{'pass_set'} ? $_[0]->{'pass'} : ""); &useradmin::making_changes(); &useradmin::modify_user($uinfo, $uinfo); &useradmin::made_changes(); &$second_print($text{'setup_done'}); } &useradmin::unlock_user_files(); if ($config{'home_quotas'}) { # Update his quotas &$first_print($text{'save_quota'}); &set_server_quotas($_[0]); &$second_print($text{'setup_done'}); } } # delete_unix(&domain) # Delete the unix user and group for a domain sub delete_unix { &require_useradmin(); # Delete unix user local @allusers = &useradmin::list_users(); local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers; &useradmin::lock_user_files(); if ($uinfo) { &$first_print($text{'delete_user'}); &delete_user($uinfo); &$second_print($text{'setup_done'}); } # Delete unix group local @allgroups = &useradmin::list_groups(); local ($ginfo) = grep { $_->{'group'} eq $_[0]->{'group'} } @allgroups; if ($ginfo) { &$first_print($text{'delete_group'}); &useradmin::set_group_envs($ginfo, 'DELETE_GROUP'); &useradmin::making_changes(); &useradmin::delete_group($ginfo); &useradmin::made_changes(); &$second_print($text{'setup_done'}); } &useradmin::unlock_user_files(); # Delete homedir if ($uinfo && -d $uinfo->{'home'} && $uinfo->{'home'} ne "/") { &$first_print($text{'delete_home'}); &system_logged("rm -rf ".quotemeta($uinfo->{'home'})); &$second_print($text{'setup_done'}); } } # check_unix_clash(domain, db, user, group) sub check_unix_clash { return 1 if (defined(getpwnam($_[2])) || defined(getgrnam($_[3]))); } # disable_unix(&domain) # Lock out the password of this domain's Unix user sub disable_unix { &require_useradmin(); &useradmin::lock_user_files(); local @allusers = &useradmin::list_users(); local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers; if ($uinfo) { &$first_print($text{'disable_unix'}); &useradmin::set_user_envs($uinfo, 'MODIFY_USER', ""); &useradmin::making_changes(); $_[0]->{'disabled_oldpass'} = $uinfo->{'pass'}; $uinfo->{'pass'} = $uconfig{'lock_string'}; &useradmin::modify_user($uinfo, $uinfo); &useradmin::made_changes(); &$second_print($text{'setup_done'}); } &useradmin::unlock_user_files(); } # enable_unix(&domain) # Re-enable this domain's Unix user sub enable_unix { &require_useradmin(); &useradmin::lock_user_files(); local @allusers = &useradmin::list_users(); local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers; if ($uinfo) { &$first_print($text{'enable_unix'}); &useradmin::set_user_envs($uinfo, 'MODIFY_USER', ""); &useradmin::making_changes(); $uinfo->{'pass'} = $_[0]->{'disabled_oldpass'}; delete($_[0]->{'disabled_oldpass'}); &useradmin::modify_user($uinfo, $uinfo); &useradmin::made_changes(); &$second_print($text{'setup_done'}); } &useradmin::unlock_user_files(); } # backup_unix(&domain, file) # Backs up the user's home directory in tar format to the given file sub backup_unix { &$first_print($text{'backup_unixtar'}); local $out = `cd '$_[0]->{'home'}'; tar cf '$_[1]' . 2>&1`; if ($?) { &$second_print(&text('backup_unixtarfailed', "
$out
")); return 0; } else { &$second_print($text{'setup_done'}); return 1; } } # restore_unix(&domain, file) # Extracts the given tar file into a user's home directory sub restore_unix { &$first_print($text{'restore_unixtar'}); local $out = `cd '$_[0]->{'home'}'; tar xf '$_[1]' 2>&1`; if ($?) { &$second_print(&text('backup_unixtarfailed', "
$out
")); return 0; } else { # Also re-set quotas if ($config{'home_quotas'}) { &set_server_quotas($_[0]); } # And update password and description &require_useradmin(); local @allusers = &useradmin::list_users(); local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers; if ($uinfo) { &useradmin::lock_user_files(); $uinfo->{'real'} = $_[0]->{'owner'}; local $enc = &useradmin::encrypt_password( $_[0]->{'pass'}); $uinfo->{'pass'} = $enc; &set_pass_change($uinfo); &useradmin::set_user_envs( $uinfo, 'MODIFY_USER', $_[0]->{'pass'}); &useradmin::making_changes(); &useradmin::modify_user($uinfo, $uinfo); &useradmin::made_changes(); &useradmin::lock_user_files(); } &$second_print($text{'setup_done'}); return 1; } } 1; virtual-server/CHANGELOG0100664000567100000120000000246010042051245014740 0ustar jcameronwheel---- Changes since 1.81 ---- A Sendmail genericstable or Postfix canonical mapping file can be automatically updated with login name to email address mappings. This is useful for programs like Usermin, which can read such a file to work out From: addresses. The directory for Webalizer statistics can be set on the Apache Website Template page. Domain owners can be granted access to the Read User Mail module, for reading mailboxe's mail. The port to use for normal and SSL virtual websites can now be set on the Apache Website Template page. Virtual servers can now be backed up to one or many tar.gz files, either locally or on a remote FTP server. Backups can also be restored from these tar.gz files, again locally or from an FTP server. The MySQL feature now properly supports usernames longer that 16 characters. A new configuration option has been added for sites that use multiple IP addresses, but always use name-based Apache virtual hosts. Username length and other restrictions are now checked by the create-domain.pl script. Virtualmin now participates in Webmin action logging, so you can see what actions were taken and which files they changed. IP address clash checking for new servers now actually works. ---- Changes since 1.90 ---- Webalizer configuration files and schedule can now be included in backups. virtual-server/restore_form.cgi0100664000567100000120000000260710041653750016733 0ustar jcameronwheel#!/usr/local/bin/perl # Show a form for restoring a single virtual server, or a bunch require './virtual-server-lib.pl'; $master_admin || &error($text{'restore_ecannot'}); &header($text{'restore_title'}, ""); print "
\n"; print "
\n"; print "\n"; print "\n"; print "
$text{'restore_header'}
\n"; # Show source file field print "\n"; print "\n"; # Show feature selection boxes print "\n"; print "
$text{'restore_src'}",&show_backup_destination("src", $config{'backup_dest'}), "
$text{'restore_features'} \n"; foreach $f (@backup_features) { local $bfunc = "restore_$f"; if (defined(&$bfunc) && ($config{$f} || $f eq "unix" || $f eq "virtualmin")) { printf " %s\n", $f, $config{'backup_feature_'.$f} ? "checked" : "", $text{'backup_feature_'.$f} || $text{'feature_'.$f}; local $ofunc = "show_restore_$f"; if (defined(&$ofunc)) { local %opts = map { split(/=/, $_) } split(/,/, $config{'backup_opts_'.$f}); local $ohtml = &$ofunc(\%opts); print $ohtml; } print "
\n"; } } print "
\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); virtual-server/backup.cgi0100664000567100000120000000242710041664670015475 0ustar jcameronwheel#!/usr/local/bin/perl # Do an immediate virtual server backup require './virtual-server-lib.pl'; $master_admin || &error($text{'backup_ecannot'}); &ReadParse(); # Validate inputs &error_setup($text{'backup_err'}); if ($in{'all'}) { @doms = &list_domains(); } else { foreach $d (split(/\0/, $in{'doms'})) { push(@doms, &get_domain($d)); } } @doms || &error($text{'backup_edoms'}); @do_features = split(/\0/, $in{'feature'}); @do_features || &error($text{'backup_efeatures'}); $dest = &parse_backup_destination("dest", \%in); $dest = &backup_strftime($dest) if ($in{'strftime'}); # Parse option inputs foreach $f (@do_features) { local $ofunc = "parse_backup_$f"; if (defined(&$ofunc)) { $options{$f} = &$ofunc(\%in); } } $| = 1; $theme_no_table++; &header($text{'backup_title'}, ""); print "
\n"; print "

",&text('backup_doing', scalar(@doms), "$dest"),"

\n"; ($ok, $size) = &backup_domains($dest, \@doms, \@do_features, $in{'fmt'}, $in{'errors'}, \%options); if (!$ok) { unlink($dest); print "

",$text{'backup_failed'},"

\n"; } else { print "

",&text('backup_done', &nice_size($size)),"

\n"; &webmin_log("backup", $dest, undef, { 'doms' => [ map { $_->{'dom'} } @doms ] }); } print "


\n"; &footer("", $text{'index_return'}); virtual-server/restore.cgi0100664000567100000120000000533510042051043015675 0ustar jcameronwheel#!/usr/local/bin/perl # Actually restore some servers, after asking for confirmation require './virtual-server-lib.pl'; $master_admin || &error($text{'restore_ecannot'}); &ReadParse(); # Validate inputs &error_setup($text{'restore_err'}); if ($in{'src'}) { $src = $in{'src'}; } else { $src = &parse_backup_destination("src", \%in); } ($mode) = &parse_backup_url($src); $mode > 0 || -r $src || -d $src || &error($text{'restore_esrc'}); @do_features = split(/\0/, $in{'feature'}); @do_features || &error($text{'restore_efeatures'}); %do_features = map { $_, 1 } @do_features; # Parse option inputs foreach $f (@do_features) { local $ofunc = "parse_restore_$f"; if (defined(&$ofunc)) { $options{$f} = &$ofunc(\%in); } } $cont = &backup_contents($src); if (!$in{'confirm'}) { # See what is in the tar file or directory ref($cont) || &error(&text('restore_efile', $cont)); (keys %$cont) || &error($text{'restore_enone'}); } else { # Find the selected domains foreach $d (split(/\0/, $in{'dom'})) { local $dinfo = &get_domain_by("dom", $d); push(@doms, $dinfo) if ($dinfo); } @doms || &error($text{'restore_edoms'}); } if ($in{'confirm'}) { $| = 1; $theme_no_table++; } &header($text{'restore_title'}, ""); print "
\n"; if (!$in{'confirm'}) { # Tell the user what will be done print "
\n"; print &text('restore_from', "$src"),"

\n"; print "

\n"; foreach $d (sort { $a cmp $b } keys %$cont) { print "
$d\n"; @dfeats = grep { $do_features{$_} } @{$cont->{$d}}; if (!@dfeats) { print "
$text{'restore_nofeat'}\n"; } else { print "
",join("
", map { $text{'backup_feature_'.$_} || $text{'feature_'.$_} } @dfeats),"\n"; $any++; } } print "
\n"; if ($any) { # Pass all HTML inputs to program again, and show OK button print "\n"; foreach $i (keys %in) { next if ($i =~ /^src_/); foreach $v (split(/\0/, $in{$i})) { print "\n"; } } print "
\n"; } else { print "$text{'restore_notany'}

\n"; } print "

\n"; } else { # Actually execute the restore print "

",&text('restore_doing', scalar(@doms), "$src"),"

\n"; $ok = &restore_domains($src, \@doms, \@do_features, \%options); if ($ok) { print &text('restore_done'),"

\n"; } else { print &text('restore_failed'),"

\n"; } &webmin_log("restore", $src, undef, { 'doms' => [ map { $_->{'dom'} } @doms ] }); } print "


\n"; &footer("", $text{'index_return'}); virtual-server/uninstall.pl0100664000567100000120000000057310036655733016116 0ustar jcameronwheel# uninstall.pl # Called when this module is un-installed to delete the backup cron job require 'virtual-server-lib.pl'; sub module_uninstall { &foreign_require("cron", "cron-lib.pl"); local @jobs = &cron::list_cron_jobs(); local ($job) = grep { $_->{'user'} eq 'root' && $_->{'command'} eq $backup_cron_cmd } @jobs; if ($job) { &cron::delete_cron_job($job); } } 1; virtual-server/backup_sched.cgi0100664000567100000120000000506610041665262016643 0ustar jcameronwheel#!/usr/local/bin/perl # Create, update or delete the backup cron job require './virtual-server-lib.pl'; $master_admin || &error($text{'backup_ecannot'}); &ReadParse(); # Validate inputs &error_setup($text{'backup_err2'}); if ($in{'all'}) { @doms = &list_domains(); } else { foreach $d (split(/\0/, $in{'doms'})) { push(@doms, &get_domain($d)); } } @doms || &error($text{'backup_edoms'}); @do_features = split(/\0/, $in{'feature'}); @do_features || &error($text{'backup_efeatures'}); $dest = &parse_backup_destination("dest", \%in); # Parse option inputs foreach $f (@do_features) { local $ofunc = "parse_backup_$f"; if (defined(&$ofunc)) { $options{$f} = &$ofunc(\%in); } } # Check if the cron job exists &foreign_require("cron", "cron-lib.pl"); local @jobs = &cron::list_cron_jobs(); local ($job) = grep { $_->{'user'} eq 'root' && $_->{'command'} eq $backup_cron_cmd } @jobs; # Create, update or delete it if ($job && $in{'enabled'}) { # Update job &lock_file(&cron::cron_file($job)); &cron::parse_times_input($job, \%in); &cron::change_cron_job($job); &unlock_file(&cron::cron_file($job)); $what = "modify"; } elsif (!$job && $in{'enabled'}) { # Create job $job = { 'user' => 'root', 'command' => $backup_cron_cmd, 'active' => 1 }; &lock_file(&cron::cron_file($job)); &cron::parse_times_input($job, \%in); &cron::create_cron_job($job); &lock_file($backup_cron_cmd); &cron::create_wrapper($backup_cron_cmd, $module_name, "backup.pl"); &unlock_file($backup_cron_cmd); &unlock_file(&cron::cron_file($job)); $what = "create"; } elsif ($job && !$in{'enabled'}) { # Delete job &lock_file(&cron::cron_file($job)); &cron::delete_cron_job($job); &unlock_file(&cron::cron_file($job)); $what = "delete"; } else { $what = "none"; } # Update module config with domains and features $config{'backup_all'} = $in{'all'}; $config{'backup_doms'} = join(" ", map { $_->{'id'} } @doms); %features = map { $_, 1 } @do_features; foreach $f (@backup_features) { $config{'backup_feature_'.$f} = $features{$f} ? 1 : 0; } $config{'backup_dest'} = $dest; $config{'backup_fmt'} = $in{'fmt'}; $config{'backup_email'} = $in{'email'}; $config{'backup_errors'} = $in{'errors'}; $config{'backup_strftime'} = $in{'strftime'}; $config{'last_check'} = time()+1; # no need for check.cgi to be run foreach $f (keys %options) { $config{'backup_opts_'.$f} = join(",", map { $_."=".$options{$f}->{$_} } keys %{$options{$f}}); } &lock_file($module_config_file); &save_module_config(); &unlock_file($module_config_file); &webmin_log("sched", $what); # Return to main menu &redirect(""); virtual-server/backup.pl0100775000567100000120000000350010040674232015334 0ustar jcameronwheel#!/usr/local/bin/perl # Do an immediate virtual server backup $no_acl_check++; require './virtual-server-lib.pl'; # Work out what will be backed up if ($config{'backup_all'}) { @doms = &list_domains(); } else { foreach $d (split(/\s+/, $config{'backup_doms'})) { local $dinfo = &get_domain($d); push(@doms, $dinfo) if ($dinfo); } } foreach $f (@backup_features) { push(@do_features, $f) if ($config{'backup_feature_'.$f}); $options{$f} = { map { split(/=/, $_) } split(/,/, $config{'backup_opts_'.$f}) }; } # Do the backup, capturing any output $first_print = \&first_save_print; $second_print = \&second_save_print; $indent_print = \&indent_save_print; $outdent_print = \&outdent_save_print; if ($config{'backup_strftime'}) { $dest = &backup_strftime($config{'backup_dest'}); } else { $dest = $config{'backup_dest'}; } ($ok, $size) = &backup_domains($dest, \@doms, \@do_features, $config{'backup_fmt'}, $config{'backup_errors'}, \%options); # Send an email to the recipient if ($config{'backup_email'} && &foreign_check("mailboxes")) { if ($ok) { $output .= &text('backup_done', &nice_size($size))."\n"; } else { $output .= $text{'backup_failed'}."\n"; } &foreign_require("mailboxes", "mailboxes-lib.pl"); $host = &get_system_hostname(); $mail = { 'headers' => [ [ 'From', "webmin\@$host" ], [ 'Subject', "Backup of Virtualmin on $host" ], [ 'To', $config{'backup_email'} ] ], 'attach' => [ { 'headers' => [ [ 'Content-type', 'text/plain' ] ], 'data' => $output } ] }; &mailboxes::send_mail($mail); } sub first_save_print { $output .= $indent_text.join("", @_)."\n"; } sub second_save_print { $output .= $indent_text.join("", @_)."\n\n"; } sub indent_save_print { $indent_text .= " "; } sub outdent_save_print { $indent_text = substr($indent_text, 4); }