--- /dev/null
+Version 1.0
+
+Copyright 2001-2009 The Horde Project (http://www.horde.org/)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if
+any, must include the following acknowledgment:
+
+ "This product includes software developed by the Horde Project
+ (http://www.horde.org/)."
+
+Alternately, this acknowledgment may appear in the software itself, if
+and wherever such third-party acknowledgments normally appear.
+
+4. The names "Horde", "The Horde Project", and "Vilma" must not be
+used to endorse or promote products derived from this software without
+prior written permission. For written permission, please contact
+core@horde.org.
+
+5. Products derived from this software may not be called "Horde" or
+"Vilma", nor may "Horde" or "Vilma" appear in their name, without
+prior written permission of the Horde Project.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE HORDE PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the Horde Project. For more information on
+the Horde Project, please see <http://www.horde.org/>.
--- /dev/null
+What is Vilma?
+--------------
+
+Vilma is a tool for administrators who need to handle various aspects
+of domain administration.
+
+
+Obtaining Vilma
+---------------
+
+Further information on Vilma and the latest version can be obtained at:
+
+ http://www.horde.org/vilma/
+
+
+Documentation
+-------------
+
+The following documentation is available in the Vilma distribution:
+
+README - This file
+LICENSE - Copyright and license information
+docs/CHANGES - List of changes by release
+docs/CREDITS - Who developed this
+docs/INSTALL - Installation instructions
+
+
+Installation
+------------
+
+Instructions for installing Vilma can be found in the file INSTALL in the
+docs/ directory of the Vilma distribution.
+
+
+Assistance
+----------
+
+If you encounter problems with Vilma, help is available!
+
+The Horde Frequently Asked Questions List (FAQ), available on the Web at:
+
+ http://www.horde.org/faq/
+
+The Horde Project runs a number of mailing lists, for individual applications
+and for issues relating to the project as a whole. Information, archives, and
+subscription information can be found at:
+
+ http://www.horde.org/mail/
+
+Lastly, Horde developers, contributors and users also make occasional
+appearances on IRC, on the channel #horde on the Freenode Network
+(irc.freenode.net).
+
+
+Licensing
+---------
+
+For licensing and copyright information, please see the file LICENSE in the
+Vilma distribution.
+
+Thanks,
+
+The Vilma team
+
+$Horde: vilma/README,v 1.3 2007/08/05 22:37:11 mp Exp $
--- /dev/null
+conf.php
+conf.bak.php
--- /dev/null
+<?xml version="1.0"?>
+<!-- $Horde: vilma/config/conf.xml,v 1.24 2009/05/28 00:33:00 bklang Exp $ -->
+<configuration>
+ <configtab name="storage" desc="Domains and Accounts Driver">
+ <configsection name="storage">
+ <configdescription>
+ These are the settings for storing all the Vilma data, such as domains,
+ users within those domains, virtual addresses for users, etc.
+ </configdescription>
+ <configsection name="limits" desc="Default Limits">
+ <configstring name="defaultmaxusers" desc="Default Max Users (0 is unlimited)">0</configstring>
+ <configstring name="defaultquota" desc="Default Per-User Quota (in bytes, 0 is unlimited)">0</configstring>
+ </configsection>
+ <configswitch name="driver" desc="What storage driver should we use?">sql
+ <case name="sql" desc="SQL">
+ <configsection name="params">
+ <configsql switchname="driverconfig"/>
+ <configsection name="tables">
+
+ <configswitch name="domainsconfig" desc="Domains table specification">default
+ <case name="default" desc="Use Vilma Defaults"/>
+ <case name="custom" desc="Custom parameters">
+ <configstring name="domains" required="true" desc="Domain table name"/>
+ <configsection name="domains_fields">
+ <configstring name="domain_id" required="true" desc="Domain Id field."/>
+ <configstring name="domain_name" required="true" desc="Domain name field."/>
+ <configstring name="domain_transport" required="true" desc="Domain transport field."/>
+ <configstring name="domain_admin" required="true" desc="Domain admin field."/>
+ <configstring name="domain_max_users" required="true" desc="Domain max users field."/>
+ <configstring name="domain_quota" required="true" desc="Domain quota field."/>
+ <configstring name="domain_key" required="true" desc="Domain key field."/>
+ </configsection>
+ </case>
+ </configswitch>
+
+ <configswitch name="usersconfig" desc="Users table specification">default
+ <case name="default" desc="Use Vilma Defaults"/>
+ <case name="custom" desc="Custom parameters">
+ <configstring name="users" required="true" desc="Users table name"/>
+ <configsection name="users_fields">
+ <configstring name="user_id" required="true" desc="User Id field"/>
+ <configstring name="user_name" required="true" desc="User name field"/>
+ <configstring name="user_full_name" required="true" desc="User full name field"/>
+ <configstring name="user_home_dir" required="true" desc="User home dir field"/>
+ <configstring name="user_mail_dir" required="true" desc="User mail dir field"/>
+ <configstring name="user_mail_quota" required="true" desc="User quota field"/>
+ <configstring name="user_clear" required="true" desc="User clear password field"/>
+ <configstring name="user_crypt" required="true" desc="User crypted password field"/>
+ <configstring name="user_uid" required="true" desc="User uid field"/>
+ <configstring name="user_gid" required="true" desc="User gid field"/>
+ <configstring name="user_enabled" required="true" desc="User enabled field"/>
+ </configsection>
+ </case>
+ </configswitch>
+
+ <configswitch name="virtualsconfig" desc="Virtual addresses table specification">default
+ <case name="default" desc="Use Vilma Defaults"/>
+ <case name="custom" desc="Custom parameters">
+ <configstring name="virtuals" required="true" desc="Virtuals table name"/>
+ <configsection name="virtuals_fields">
+ <configstring name="virtual_id" required="true" desc="Virtual Id field."/>
+ <configstring name="virtual_email" required="true" desc="Virtual email field."/>
+ <configstring name="virtual_destination" required="true" desc="Virtual
+ destination field."/>
+ </configsection>
+ </case>
+ </configswitch>
+
+ </configsection>
+ </configsection>
+ </case>
+ <case name="qmailldap" desc="Qmail-LDAP">
+ <configsection name="params">
+ <configsection name="ldap">
+ <configstring name="ldaphost" desc="The hostname of the LDAP
+ server">localhost</configstring>
+ <configstring name="basedn" desc="The base DN for the LDAP server"/>
+ <configstring name="binddn" required="false" desc="The DN used to bind to
+ the LDAP server"/>
+ <configstring name="bindpw" required="false" desc="The password used to
+ bind to the LDAP server"/>
+ <configenum name="version" desc="LDAP Protocol Version">3
+ <values>3
+ <value desc="LDAPv2 (Deprecated)">2</value>
+ <value desc="LDAPv3">3</value>
+ </values>
+ </configenum>
+ <configstring name="dn" desc="The object search key"/>
+ <configswitch name="filter_type" desc="How to specify a filter for the
+ user lists">objectclass
+ <case name="objectclass" desc="One or more objectclass filters">
+ <configlist name="objectclass" desc="The objectclass filter used to
+ search for users. Can be a single objectclass or a list."/>
+ </case>
+ <case name="free" desc="A complete LDAP filter expression">
+ <configstring name="filter" desc="The LDAP RFC formatted filter used to
+ search for users."/>
+ </case>
+ </configswitch>
+ </configsection>
+ <configsection name="sql">
+ <configsql switchname="driverconfig" />
+ </configsection>
+ </configsection>
+ </case>
+ </configswitch>
+ </configsection>
+ </configtab>
+
+ <configtab name="mta" desc="Mailbox Driver">
+ <configsection name="mailboxes">
+ <configheader>Mailbox settings</configheader>
+ <configswitch name="driver" desc="Driver used to create, delete, and check
+ the status of mailboxes">maildrop
+ <case name="maildrop" desc="Maildrop driver">
+ <configsection name="params" desc="Maildrop Parameters">
+ <configinteger name="uid" required="false" desc="The system UID for the
+ virtual user">1003</configinteger>
+ <configinteger name="gid" required="false" desc="The system GID for the
+ virtual user">1000</configinteger>
+ <configstring name="mail_dir_base" desc="The base directory for the
+ mailboxes">/home/vmail</configstring>
+ <configstring name="system_user" desc="User to run script to create mail
+ dir">vmail</configstring>
+ <configboolean name="usedomain" desc="Use virtual domain directory
+ (exploded) directory structure.">true</configboolean>
+ </configsection>
+ </case>
+ <case name="imap" desc="IMAP Admin driver">
+ <configsection name="params" desc="IMAP Admin Parameters">
+ <configstring name="admin_user" desc="The name of a user with admin
+ privileges"/>
+ <configstring name="admin_password" desc="The password of the
+ administrator"/>
+ <configstring name="hostspec" desc="The hostname or IP address of the
+ server">localhost</configstring>
+ <configstring name="port" desc="The server port to which we will
+ connect">143</configstring>
+ <configstring name="protocol" desc="The connection protocol
+ (e.g. 'imap', 'pop3', 'nntp'). Protocol is one of 'imap/notls' (or only
+ 'imap' if you have a c-client version 2000c or older), 'imap/ssl', or
+ 'imap/ssl/novalidate-cert' (for a self-signed
+ certificate)">imap</configstring>
+ <configstring name="userhierarchy" desc="The hierarchy where user
+ mailboxes are stored. If you are using Cyrus, make sure that you are
+ using the same hierarchy separator as in imap.conf">user.</configstring>
+ </configsection>
+ </case>
+ <case name="hooks" desc="Hooks (See Documentation)">
+ <configsection name="params" desc="Hooks Parameters">
+ <configplaceholder/>
+ </configsection>
+ </case>
+ <case name="null" desc="Null driver">
+ <configsection name="params" desc="Null Parameters">
+ <configplaceholder/>
+ </configsection>
+ </case>
+ </configswitch>
+ </configsection>
+
+ <configsection name="mta">
+ <configheader>MTA Settings</configheader>
+ <configlist name="transports" desc="List of available transports (according
+ to MTA)">maildrop</configlist>
+ </configsection>
+ </configtab>
+
+ <configtab name="menu" desc="Menu Settings">
+ <configsection name="menu">
+ <configmultienum name="apps" desc="Select any applications that should be
+ linked in Vilma's menu">
+ <values>
+ <configspecial name="list-horde-apps"/>
+ </values>
+ </configmultienum>
+ </configsection>
+ </configtab>
+</configuration>
--- /dev/null
+<?php
+/**
+ * Vilma Hooks configuration file.
+ *
+ * THE HOOKS PROVIDED IN THIS FILE ARE EXAMPLES ONLY. DO NOT ENABLE THEM
+ * BLINDLY IF YOU DO NOT KNOW WHAT YOU ARE DOING. YOU HAVE TO CUSTOMIZE THEM
+ * TO MATCH YOUR SPECIFIC NEEDS AND SYSTEM ENVIRONMENT.
+ *
+ * For more information please see the horde/config/hooks.php.dist file.
+ *
+ * $Horde: vilma/config/hooks.php.dist,v 1.3 2009/07/13 20:05:58 slusarz Exp $
+ */
+
+// Example hook for handling a new domain within Vilma. This can be used, for
+// example, to add the new domain to qmail's "control/locals" file, which will
+// tell qmail to begin receiving mail for this new domain.
+//
+// Note: for this example function to work, the "control/locals" and the
+// "control/" directory must be writeable by the webserver process user ID.
+// An alternative to this direct method would be to repopulate the
+// "control/locals" file on an interval from cron(8) using some kind of script
+// to pull a list of domains from Horde using (for example) XML-RPC.
+
+// if (!function_exists('_vilma_hook_savedomain')) {
+// function _vilma_hook_savedomain($info = null)
+// {
+// if ($info === null || !isset($info['domain_name'])) {
+// return false;
+// }
+// $domain = $info['domain_name'];
+//
+// $qmail_locals = '/tmp/locals';
+// $domainlist = file_get_contents($qmail_locals);
+// $domains = split("\n", $domainlist);
+//
+// if (!in_array($domain, $domains)) {
+// $domains[] = $domain;
+// } else {
+// return true;
+// }
+//
+// // Write to a temp file for safety and atomicity.
+// $tmp = tempnam(dirname($qmail_locals), "locals-");
+// $tmpfh = fopen($tmp, "w");
+// fwrite($tmpfh, implode("\n", $domains));
+// fclose($tmpfh);
+//
+// // Backup the previous version and move the new one into place.
+// unlink($qmail_locals . ".previous");
+// rename($qmail_locals, $qmail_locals . ".previous");
+// rename($tmp, $qmail_locals);
+//
+// return true;
+// }
+// }
+
+// This hook does the opposite of the above: Remove a domain from the
+// "control/locals" file.
+
+// if (!function_exists('_vilma_hook_deletedomain')) {
+// function _vilma_hook_deletedomain($domain = null)
+// {
+// if ($domain === null) {
+// return false;
+// }
+//
+// $qmail_locals = '/tmp/locals';
+// $domainlist = file_get_contents($qmail_locals);
+// $domains = split("\n", $domainlist);
+//
+// if ($key = array_search($domain, $domains)) {
+// unset($domains[$key]);
+// } else {
+// return false;
+// }
+//
+// // Write to a temp file for safety and atomicity.
+// $tmp = tempnam(dirname($qmail_locals), "locals-");
+// $tmpfh = fopen($tmp, "w");
+// fwrite($tmpfh, implode("\n", $domains));
+// fclose($tmpfh);
+//
+// // Backup the previous version and move the new one into place.
+// unlink($qmail_locals . ".previous");
+// rename($qmail_locals, $qmail_locals . ".previous");
+// rename($tmp, $qmail_locals);
+//
+// return true;
+// }
+// }
+
+// This function will turn an array of additional LDAP attributes that will be
+// added to the attributes created by the LDAP driver.
+//if (!function_exists('_vilma_hook_getldapattrs')) {
+// function _vilma_hook_getldapattrs($attrs)
+// {
+// $attrs['deliverymode'] = 'nolocal';
+// $attrs['qmailprogrampath'] = '/opt/maildrop/bin/maildrop /opt/maildrop/etc/maildroprc.dspam';
+// $attrs['qmaildotmode'] = 'ldapwithprog';
+//
+// return $attrs;
+// }
+//}
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/config/prefs.php.dist,v 1.1 2006/08/24 23:49:27 bklang Exp $
+ *
+ * See horde/config/prefs.php for documentation on the structure of this file.
+ */
+
+$prefGroups['display'] = array(
+ 'column' => _("Display listings"),
+ 'label' => _("Display details"),
+ 'desc' => _("Set default display parameters."),
+ 'members' => array('addresses_perpage'));
+
+// listing
+$_prefs['addresses_perpage'] = array(
+ 'value' => 20,
+ 'locked' => false,
+ 'shared' => false,
+ 'type' => 'number',
+ 'desc' => _("How many domain to display per page."));
--- /dev/null
+--------
+v0.1-cvs
+--------
+
+[bkl] Restructure application to have Users, Aliases, Groups and Forwards.
+[bkl] Add qmailldap backend support.
+[ben] Better support for MS-SQL.
+[jan] Allow to use custom table and column names (guilleva@gmail.com,
+ Request #3244).
+[cjh] Use bind variables in SQL driver (selsky@columbia.edu, Request #1795).
+[jmf] Downcase user and virtuals.
+[jmf] Support for virtuals with external (non-local) e-mail destinations.
+[jan] Add Spanish translation (Manuel Perez Ayala <mperaya@alcazaba.unex.es>).
+[jmf] Add support for creating mailboxes via IMAP protocol.
+[jan] Add Lithuanian translation (Vilius ¦umskas <vilius@lnk.lt>).
+[jan] Add German translation.
--- /dev/null
+=======================================
+|| Vilma Version 1.0 Development Team ||
+========================================
+
+===============
+Core Developers
+===============
+
+Marko Djukic <marko@oblo.com>
+- Initial authoring.
+
+Ben Klang <ben@alkaloid.net>
+- Rewrite for Aliases and Groups/Forwards
+
+
+============
+Localization
+============
+
+German Jan Schneider <jan@horde.org>
+Italian Marko Djukic <marko@oblo.com>
+Lithuanian Vilius ¦umskas <vilius@lnk.lt>
+Spanish Manuel Perez Ayala <mperaya@alcazaba.unex.es>
+
+
+$Horde: vilma/docs/CREDITS,v 1.7 2008/03/22 10:43:53 jan Exp $
--- /dev/null
+==============================
+|| INSTALLING Vilma 0.1 ||
+==============================
+
+* PLEASE SEE IMPORTANT NOTE in the README file about Vilma's status
+before you try to install it and are disappointed.
+
+This document contains instructions for installing the Vilma virtual mail
+domain management application.
+
+For information on the capabilities and features of Vilma, see the
+file README in the top-level directory of the Vilma distribution.
+
+
+OBTAINING VILMA
+-----------------
+
+Vilma can be obtained from the Horde website and FTP server, at
+
+ http://www.horde.org/vilma/
+ ftp://ftp.horde.org/pub/vilma/
+
+Bleeding-edge development versions of Vilma are available via CVS; see
+the file docs/HACKING in the Horde distribution for information on
+accessing the Horde CVS repository.
+
+
+PREREQUISITES
+-------------
+
+To function properly, Vilma requires the following:
+
+ 1. A working Horde installation.
+
+ Vilma runs within the Horde Application Framework, a set of
+ common tools for Web applications written in PHP. You must
+ install Horde before installing Vilma.
+
+ The Horde Framework can be obtained from the Horde website and
+ FTP server, at
+
+ http://www.horde.org/horde/
+ ftp://ftp.horde.org/pub/horde/
+
+ Many of Vilma's prerequisites are also Horde prerequisites.
+ Be sure to have completed all of the steps in the INSTALL
+ file for the Horde Framework before installing Vilma.
+
+ 2. SQL support in PHP.
+
+ Vilma store its data in an SQL database. Build PHP with whichever
+ SQL driver you require; see the Horde INSTALL file for details.
+
+
+INSTALLING VILMA
+------------------
+
+Vilma is written in PHP, and must be installed in a web-accessible
+directory. The precise location of this directory will differ from
+system to system. Conventionally, Vilma is installed directly underneath
+Horde in the webserver's document tree.
+
+Since Vilma is written in PHP, there is no compilation necessary;
+simply expand the distribution where you want it to reside and rename
+the root directory of the distribution to whatever you wish to appear
+in the URL. For example, with the Apache webserver's default document
+root of '/usr/local/apache/htdocs', you would type:
+
+ cd /usr/local/apache/htdocs/horde
+ tar zxvf /path/to/vilma-0.1.tar.gz
+ mv vilma-0.1 vilma
+
+and would then find Vilma at the URL
+
+ http://your-server/horde/vilma/
+
+
+CONFIGURING VILMA
+-------------------
+
+1. Configuring Horde for Vilma
+
+ a. Register the application
+
+ In horde/config/registry.php, find the applications['vilma'] stanza.
+ The default settings here should be okay, but you can change
+ them if desired. If you have changed the location of Vilma relative
+ to Horde, either in the URL, in the filesystem or both, you must
+ update the 'fileroot' and 'webroot' settings to their correct
+ values.
+
+2. Creating the database table
+
+ The specific steps to create the Vilma database table depend
+ on which database you've chosen to use.
+
+ First, look in scripts/drivers/ to see if a script already
+ exists for your database type. If so, you should be
+ able to simply execute that script as superuser in your
+ database. (Note that executing the script as the "horde" user will
+ probably fail when granting privileges.)
+
+ If such a script does not exist, you'll need to build your own, using
+ the file vilma.sql as a starting point. If you need
+ assistance in creating databases, you may wish to let us know on
+ the Vilma mailing list.
+
+3. Configuring Vilma.
+
+ To configure Vilma, change to the config/ directory of the
+ installed distribution, and make copies of all of the configuration
+ "dist" files without the "dist" suffix:
+
+ cd config/
+ for foo in *.dist; do cp $foo `basename $foo .dist`; done
+
+ Documentation on the format of those files can be found in each
+ file. With the exception of the conf.* files (see below),
+ the other files in config/ need only be modified if you wish
+ to customize Vilma's appearance or behavior, as the defaults will
+ be correct for most sites.
+
+ You must login to Horde as a Horde Administrator to finish the
+ configuring of Vilma. Use the Horde "Administration" menu item to get
+ to the Administration page, and then click on the "Configuration"
+ icon to get the Configuration page. Select "Tasks" from the selection
+ list of applications, and click on the "Configure" button. Fill in or
+ change any configuration values as needed. When done click on "Generate
+ Tasks Configuration" to generate the conf.php file. If your web server
+ doesn't have write permissions to the Vilma configuration directory or
+ file, it will not be able to write the file. In this case, cut and
+ paste the returned configuration information into the file
+ vilma/config/conf.php.
+
+ Note for international users: Vilma uses GNU gettext to provide local
+ translations of text displayed by applications; the translations are
+ found in the po/ directory. If a translation is not yet available
+ for your locale (and you wish to create one), or if you're having
+ trouble using a provided translation, please see the horde/docs/TRANSLATIONS
+ file for instructions.
+
+4. Testing Vilma
+
+ Use Vilma to create, modify, and delete forms. Test at
+ least the following:
+
+ - Creating a form
+ - Modifying a form
+ - Viewing and submitting a form
+ - Deleting a form
+
+
+SAMPLE USAGE
+------------
+
+Vilma can be embedded internally within Horde in any application which
+supports the Horde Blocks API.
+
+Otherwise Vilma can be called from any web page with the following simple
+php code:
+
+ <?php
+ $form_id = 2;
+ include <pathtovilma> . '/display.php';
+ ?>
+
+
+OBTAINING SUPPORT
+-----------------
+
+If you encounter problems with Vilma, help is available!
+
+The Horde Frequently Asked Questions List (FAQ), available on the Web
+at
+
+ http://www.horde.org/faq/
+
+The Horde Project runs a number of mailing lists, for individual
+applications and for issues relating to the project as a whole.
+Information, archives, and subscription information can be found at
+
+ http://www.horde.org/mail/
+
+Lastly, Horde developers, contributors and users may also be found on IRC,
+on the channel #horde on the Freenode Network (irc.freenode.net).
+
+Please keep in mind that Vilma is free software written by volunteers.
+For information on reasonable support expectations, please read
+
+ http://www.horde.org/support.php
+
+Thanks for using Vilma!
+
+The Vilma team
+
+$Horde: vilma/docs/INSTALL,v 1.6 2007/08/30 05:10:06 chuck Exp $
--- /dev/null
+===========================
+Vilma Development TODO List
+===========================
+
+* Implement an audit trail so that we know when and by whom accounts were
+ created, deleted, modified, etc.
+
+* Integrate with Beatnik to allow DNS zone and MX records to be created upon
+ domain creation
+
+* Abstract domains driver from accounts driver
+
+* Create Beatnik-integrated domains driver
+
+* Throw proper error if MySQL module not installed in PHP
+
+$Horde: vilma/docs/TODO,v 1.7 2007/08/06 00:08:29 mp Exp $
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/domains/delete.php,v 1.28 2009/06/10 17:33:45 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Form.php';
+require_once VILMA_BASE . '/lib/Forms/DeleteDomainForm.php';
+
+/* Only admin should be using this. */
+if (!Vilma::hasPermission($domain)) {
+ Horde::authenticationFailureRedirect();
+}
+
+$vars = Horde_Variables::getDefaultVariables();
+$form = new DeleteDomainForm($vars);
+
+if ($vars->get('submitbutton') == _("Delete")) {
+ if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ $delete = $vilma_driver->deleteDomain($info['domain_id']);
+ if (is_a($delete, 'PEAR_Error')) {
+ Horde::logMessage($delete, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error deleting domain. %s."), $delete->getMessage()), 'horde.error');
+ } else {
+ $notification->push(_("Domain deleted."), 'horde.success');
+ $url = Horde::applicationUrl('domains/index.php', true);
+ header('Location: ' . $url);
+ exit;
+ }
+ }
+} elseif ($vars->get('submitbutton') == _("Do not delete")) {
+ $notification->push(_("Domain not deleted."), 'horde.message');
+ header('Location: ' . Horde::applicationUrl('domains/index.php'));
+ exit;
+}
+
+/* Render the form. */
+require_once 'Horde/Form/Renderer.php';
+$renderer = new Horde_Form_Renderer();
+$main = Horde_Util::bufferOutput(array($form, 'renderActive'), $renderer, $vars, 'delete.php', 'post');
+
+$template->set('main', $main);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/main/main.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/domains/edit.php,v 1.28 2009/06/10 17:33:45 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Form.php';
+require_once VILMA_BASE . '/lib/Forms/EditDomainForm.php';
+
+/* Only admin should be using this. */
+if (!Vilma::hasPermission($domain)) {
+ Horde::authenticationFailureRedirect();
+}
+
+//$domain_id = Horde_Util::getFormData('domain_id');
+$vars = Horde_Variables::getDefaultVariables();
+$form = new EditDomainForm($vars);
+
+if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ $info['name'] = Horde_String::lower($info['name']);
+ $domain_id = $vilma_driver->saveDomain($info);
+ if (is_a($domain_id, 'PEAR_Error')) {
+ Horde::logMessage($domain_id, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error saving domain: %s."), $domain_id->getMessage()), 'horde.error');
+ } else {
+ $notification->push(_("Domain saved."), 'horde.success');
+ $url = Horde::applicationUrl('domains/index.php', true);
+ header('Location: ' . $url);
+ exit;
+ }
+}
+
+/* Render the form. */
+require_once 'Horde/Form/Renderer.php';
+$renderer = &new Horde_Form_Renderer();
+$main = Horde_Util::bufferOutput(array($form, 'renderActive'), $renderer, $vars, 'edit.php', 'post');
+
+$template->set('main', $main);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/main/main.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/domains/index.php,v 1.28 2009/06/10 05:25:22 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+
+/* Only admin should be using this. */
+if (!Vilma::hasPermission($domain)) {
+ Horde::authenticationFailureRedirect();
+}
+
+// Having a current domain doesn't make sense on this page
+Vilma::setCurDomain(false);
+
+$domains = $vilma_driver->getDomains();
+if (is_a($domains, 'PEAR_Error')) {
+ $notification->push($domains, 'horde.error');
+ $domains = array();
+}
+foreach ($domains as $id => $domain) {
+ $url = Horde::applicationUrl('domains/edit.php');
+ $domains[$id]['edit_url'] = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']);
+ $url = Horde::applicationUrl('domains/delete.php');
+ $domains[$id]['del_url'] = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']);
+ $url = Horde::applicationUrl('users/index.php');
+ $domains[$id]['view_url'] = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']);
+}
+
+/* Set up the template fields. */
+$template->set('domains', $domains, true);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+/* Set up the field list. */
+$images = array('delete' => Horde::img('delete.png', _("Delete Domain"), '', $registry->getImageDir('horde')),
+ 'edit' => Horde::img('edit.png', _("Edit Domain"), '', $registry->getImageDir('horde')));
+$template->set('images', $images);
+
+/* Render the page. */
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/domains/index.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/index.php,v 1.19 2009/01/06 18:02:26 jan Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__));
+require_once VILMA_BASE . '/lib/base.php';
+
+$vilma_configured = (@is_readable(VILMA_BASE . '/config/conf.php') &&
+ @is_readable(VILMA_BASE . '/config/prefs.php'));
+
+if (!$vilma_configured) {
+ require VILMA_BASE . '/../lib/Test.php';
+ Horde_Test::configFilesMissing('Vilma', VILMA_BASE, array('conf.php', 'prefs.php'));
+}
+
+require VILMA_BASE . '/domains/index.php';
--- /dev/null
+<?php
+/**
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Driver.php,v 1.54 2009/05/27 23:57:31 bklang Exp $
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @package Vilma
+ */
+class Vilma_Driver {
+
+ /**
+ * A hash containing any parameters for the current driver.
+ *
+ * @var array
+ */
+ var $_params = array();
+
+ /**
+ * Constructor
+ *
+ * @param array $params Any parameters needed for this driver.
+ */
+ function Vilma_Driver($params)
+ {
+ $this->_params = $params;
+ }
+
+ /**
+ * Returns all the users sorted by domain and as arrays of each domain.
+ *
+ * @return array An array of domains then users for each domain.
+ */
+ function getAllUsers()
+ {
+ /* Get all users from backend. */
+ $users = &$this->getUsers();
+
+ /* Determine the domain for each user and plug into array by domain. */
+ $users_by_domain = array();
+ foreach ($users as $user) {
+ $domain_name = Vilma::stripDomain($user['user_name']);
+ $users_by_domain[$domain_name][] = $user;
+ }
+
+ /* Sort by domain. */
+ ksort($users_by_domain);
+ /* Sort each domain's users by user name. */
+ require_once 'Horde/Array.php';
+ foreach ($users_by_domain as $key => $val) {
+ Horde_Array::arraySort($users_by_domain[$key], 'user_name');
+ }
+
+ return $users_by_domain;
+ }
+
+ /**
+ * Checks if the given domain is below the maximum allowed users.
+ *
+ * @param string $domain The domain name to check.
+ *
+ * @return boolean True if the domain does not have a maximum limit (0) or
+ * current number of users is below the maximum number
+ * allowed. Otherwise false.
+ */
+ function isBelowMaxUsers($domain)
+ {
+ /* Get the maximum number of users for this domain. */
+ $max_users = $this->getDomainMaxUsers($domain);
+ if ($max_users == '0') {
+ /* No maximum. */
+ return true;
+ }
+
+ /* Get the current number of users. */
+ $num_users = $this->getDomainNumUsers($domain);
+
+ return ($num_users < $max_users);
+ }
+
+ /**
+ * Gets an array of information related to the address passed in.
+ * This method may be overridden by the backend driver if there is a more
+ * efficient way to do this than a linear array search
+ *
+ * @param string $address Address for which information will be pulled
+ * @param string $type Address type to request
+ * One of 'user', 'alias', 'grpfwd' or 'any'
+ * Defaults to 'any'
+ *
+ * @return mixed Array of user information on success, empty array
+ * if the user does not exist, PEAR_Error on failure
+ */
+ function getAddressInfo($address, $type = 'all')
+ {
+ $domain = Vilma::stripDomain($address);
+ $addresses = $this->getAddresses($domain, $type);
+ foreach($addresses as $addrinfo) {
+ if ($addrinfo['id'] == $address) {
+ return $addrinfo;
+ } else if ($addrinfo['address'] == $address) {
+ return $addrinfo;
+ }
+ }
+ return PEAR::raiseError(sprintf(_("No such address %s of type %s found."), $address, $type));
+ }
+
+ /**
+ * Does a series of checks for a given user to determine the status.
+ *
+ * @param array $user The user's details in an array as returned by the
+ * getUser() function.
+ *
+ * @return array Either an array of error messages found during the checks
+ * or an array with a single element stating that the user
+ * is ready.
+ */
+ function getUserStatus($user)
+ {
+ /* Some needed vars. */
+ $no_error = true;
+ $status = array();
+ $domain_name = Vilma::stripDomain($user['user_name']);
+ $user_name = Vilma::stripUser($user['user_name']);
+
+ /* Check if user enabled. */
+ if ($user['user_enabled'] !== 'active') {
+ $no_error = false;
+ $err_msg = _("User disabled.");
+ $status[] = Horde::img('alerts/error.png', $err_msg, 'align="middle"', $GLOBALS['registry']->getImageDir('horde')) . ' ' . $err_msg;
+ }
+
+ /* Check if mailbox exists. */
+ $mailboxes = &Vilma::getMailboxDriver();
+ if (is_a($mailboxes, 'PEAR_Error')) {
+ $no_error = false;
+ $err_msg = $mailboxes->getMessage();
+ $status[] = Horde::img('alerts/warning.png', $err_msg, 'align="middle"', $GLOBALS['registry']->getImageDir('horde')) . ' ' . $err_msg;
+ }
+ $result = $mailboxes->checkMailbox($user_name, $domain_name);
+ if (is_a($result, 'PEAR_Error')) {
+ $no_error = false;
+ $err_msg = $result->getMessage();
+ $status[] = Horde::img('alerts/warning.png', $err_msg, 'align="middle"', $GLOBALS['registry']->getImageDir('horde')) . ' ' . $err_msg;
+ }
+
+ /* TODO: Quota checking would be nice too. */
+
+ /* If no errors have been found output a success message for this
+ * user's status. */
+ if ($no_error) {
+ $msg = _("User ready.");
+ $status = array(Horde::img('alerts/success.png', $msg, 'align="middle"', $GLOBALS['registry']->getImageDir('horde')) . ' ' . $msg);
+ }
+ return $status;
+ }
+
+ function saveUser(&$info)
+ {
+ $create = false;
+ if (empty($info['user_id'])) {
+ $create = true;
+ }
+
+ $result = $this->_saveUser($info);
+ if (is_a($result, 'PEAR_Error')) {
+ return $result;
+ }
+
+ if ($create) {
+ $mailboxes = &Vilma::getMailboxDriver();
+ if (is_a($mailboxes, 'PEAR_Error')) {
+ $this->_deleteUser($result['user_id']);
+ return $mailboxes;
+ }
+
+ $mailbox = $mailboxes->createMailbox(Vilma::stripUser($info['user_name']), Vilma::stripDomain($info['user_name']));
+ if (is_a($mailbox, 'PEAR_Error')) {
+ //echo $mailbox->getMessage() . '<br />';
+ //No 'system_user' parameter specified to maildrop driver.
+ //$this->_deleteUser($result['user_id']);
+ return $mailbox;
+ }
+ }
+
+ if (isset($GLOBALS['conf']['mta']['auth_update_script']) &&
+ !empty($info['password'])) {
+ $cmd = sprintf('%s set %s %s 2>&1',
+ $GLOBALS['conf']['mta']['auth_update_script'],
+ escapeshellarg($info['user_name']),
+ escapeshellarg($info['password']));
+ $msg = system($cmd, $ec);
+ if ($msg === false) {
+ return PEAR::raiseError(_("Error running authentication update script."));
+ }
+ if ($ec != 0) {
+ if (empty($msg)) {
+ $msg = _("Unknown error running authentication update script.");
+ }
+ return PEAR::raiseError($msg);
+ }
+ }
+
+ return true;
+ }
+
+ function deleteUser($user_id)
+ {
+ return PEAR::raiseError(_("Vilma_Driver::deleteUser(): Method Not Implemented."));
+ }
+
+ /**
+ * Saves a given domain with the provided information.
+ *
+ * @param array $info Array of details to save the domain
+ *
+ * @return mixed True on success, or PEAR_Error on failure.
+ */
+ function saveDomain(&$info)
+ {
+ $domain_id = $this->_saveDomain($info);
+ if (is_a($domain_id, 'PEAR_Error')) {
+ return $domain_id;
+ }
+
+ $ret = Horde::callHook('_vilma_hook_savedomain', array($info), 'vilma');
+ if (!$ret) {
+ return PEAR::raiseError(_("Domain added but an error was encountered while calling the configured hook. Contact your administrator for futher assistance."));
+ }
+
+ return $domain_id;
+ }
+
+ /**
+ * Saves the domain record.
+ *
+ * @abstract
+ * @param array $info Information to save the domain
+ *
+ * @return mixed True on success, or PEAR_Error on failure.
+ */
+ function _saveDomain(&$info)
+ {
+ return PEAR::raiseError(_("Not implemented."));
+ }
+
+ /**
+ * Deletes a given domain and all the users and virtuals under it.
+ *
+ * @param integer $domain_id The id of the domain to delete.
+ *
+ * @return mixed True on success, or PEAR_Error on failure.
+ */
+ function deleteDomain($domain_id)
+ {
+ $domain_record = $this->getDomain($domain_id);
+ if (is_a($domain_record, 'PEAR_Error')) {
+ return $domain_record;
+ }
+
+ $users = $this->getUsers($domain_record['domain_name']);
+ if (is_a($users, 'PEAR_Error')) {
+ return $users;
+ }
+
+ foreach ($users as $user) {
+ $this->_deleteUser($user['user_id']);
+ }
+
+ $ret = $this->_deleteDomain($domain_id);
+ if (is_a($ret, 'PEAR_Error')) {
+ return $ret;
+ }
+
+ $ret = Horde::callHook('_vilma_hook_deletedomain',
+ array($domain_record['domain_name']),
+ 'vilma');
+ if (!$ret) {
+ return PEAR::raiseError(_("Error while calling hook to delete domain."));
+ }
+ }
+
+ /**
+ * Deletes the domain record.
+ *
+ * @abstract
+ * @param integer $domain_id The ID of the domain to delete.
+ *
+ * @return mixed True on success, or PEAR_Error on failure.
+ */
+ function _deleteDomain($domain_id)
+ {
+ return PEAR::raiseError(_("Not implemented."));
+ }
+
+ /**
+ * Get the user who is the domain admin.
+ *
+ * @todo This should be replaced by moving all permissions into Horde
+ * permissions.
+ */
+ function getDomainAdmin($domain_name)
+ {
+ $domain = $this->getDomainByName($domain_name);
+ if (is_a($domain, 'PEAR_Error')) {
+ return $domain;
+ }
+ return $domain['domain_admin'];
+ }
+
+ /**
+ * Returns the configured quota for this domain.
+ *
+ * @param string $domain_name The name of the domain for which to
+ * return the quota.
+ *
+ * @return integer The domain's quota.
+ */
+ function getDomainQuota($domain_name)
+ {
+ $domain = $this->getDomainByName($domain_name);
+ if (is_a($domain, 'PEAR_Error')) {
+ return $domain;
+ }
+ return $domain['domain_quota'];
+ }
+
+ /**
+ * Returns the maximum number of users allowed for a given domain.
+ *
+ * @param string $domain_name The name of the domain for which to
+ * return the maximum users.
+ *
+ * @return integer The maximum number of allowed users or PEAR_Error on
+ * failure.
+ */
+ function getDomainMaxUsers($domain_name)
+ {
+ $domain = $this->getDomainByName($domain_name);
+ if (is_a($domain, 'PEAR_Error')) {
+ return $domain;
+ }
+ return $domain['max_users'];
+ }
+
+ /**
+ * Attempts to return a concrete Vilma_Driver instance based on $driver.
+ *
+ * @param string $driver The type of concrete Vilma_Driver subclass to
+ * return.
+ * @param array $params A hash containing any additional configuration or
+ * connection parameters a subclass might need.
+ *
+ * @return Vilma_Driver The newly created concrete Vilma_Driver instance,
+ * or false on error.
+ */
+ function factory($driver = null, $params = null)
+ {
+ if (is_null($driver)) {
+ $driver = $GLOBALS['conf']['storage']['driver'];
+ }
+ $driver = basename($driver);
+
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('storage', $driver);
+ }
+
+ include_once dirname(__FILE__) . '/Driver/' . $driver . '.php';
+ $class = 'Vilma_Driver_' . $driver;
+ if (class_exists($class)) {
+ return new $class($params);
+ } else {
+ Horde::fatal(PEAR::raiseError(sprintf(_("No such backend \"%s\" found"), $driver)), __FILE__, __LINE__);
+ }
+ }
+
+ /**
+ * Attempts to return a reference to a concrete Vilma_Driver instance
+ * based on $driver.
+ *
+ * It will only create a new instance if no Vilma_Driver instance with the
+ * same parameters currently exists.
+ *
+ * This should be used if multiple storage sources are required.
+ *
+ * This method must be invoked as: $var = &Vilma_Driver::singleton()
+ *
+ * @param string $driver The type of concrete Vilma_Driver subclass to
+ * return.
+ * @param array $params A hash containing any additional configuration or
+ * connection parameters a subclass might need.
+ *
+ * @return mixed The created concrete Vilma_Driver instance, or false on
+ * error.
+ */
+ function &singleton($driver = null, $params = null)
+ {
+ static $instances;
+
+ if (is_null($driver)) {
+ $driver = $GLOBALS['conf']['storage']['driver'];
+ }
+
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('storage', $driver);
+ }
+
+ if (!isset($instances)) {
+ $instances = array();
+ }
+
+ $signature = serialize(array($driver, $params));
+ if (!isset($instances[$signature])) {
+ $instances[$signature] = Vilma_Driver::factory($driver, $params);
+ }
+
+ return $instances[$signature];
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2006-2007 Alkaloid Networks <http://www.alkaloid.net>
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Driver/qmailldap.php,v 1.26 2009/07/08 20:16:22 bklang Exp $
+ *
+ * @author Ben Klang <bklang@alkaloid.net>
+ * @author David Cummings <davidcummings@acm.org>
+ * @package Vilma
+ */
+
+require_once 'Horde/SQL.php';
+
+class Vilma_Driver_qmailldap extends Vilma_Driver {
+
+ /**
+ * @var _LDAP Reference to initialized LDAP driver
+ */
+ var $_ldap;
+
+ /**
+ * @var _dbparams Configuration parameters for the LDAP driver
+ */
+ var $_ldapparams;
+
+ /**
+ * @var _db Reference to the initialized database driver
+ */
+ var $_db;
+
+ /**
+ * @var _dbparams Configuration parameters for the database driver
+ */
+ var $_dbparams;
+
+ function Vilma_Driver_qmailldap($params)
+ {
+ parent::Vilma_Driver($params);
+ $this->_ldapparams = $this->_params['ldap'];
+ $this->_sqlparams = Horde::getDriverConfig('storage', 'sql');
+ $res = $this->_connect();
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ /* Connect to the backend for tracking domains. */
+ $this->_dbinit();
+ }
+
+ /**
+ * Gets the list of domains from the backend.
+ *
+ * @return array All the domains and their data in an array.
+ */
+ function getDomains()
+ {
+ $sql = 'SELECT domain_id, domain_name, domain_transport, ' .
+ 'domain_max_users, domain_quota FROM vilma_domains ' .
+ 'ORDER BY domain_name';
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Gets the specified domain information from the backend.
+ *
+ * @param integer $domain_id The id of the domain to fetch.
+ *
+ * @return array The domain's information in an array.
+ */
+ function getDomain($domain_id)
+ {
+ $sql = 'SELECT domain_id, domain_name, domain_transport, ' .
+ 'domain_max_users, domain_quota FROM vilma_domains ' .
+ 'WHERE domain_id=? ORDER BY domain_name';
+ $values = array($domain_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getRow($sql, $values, DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Given a domain name returns the information from the backend.
+ *
+ * @param string $name The name of the domain to fetch.
+ *
+ * @return array The domain's information in an array.
+ */
+ function getDomainByName($domain_name)
+ {
+ $sql = 'SELECT domain_id, domain_name, domain_transport, ' .
+ 'domain_max_users, domain_quota FROM vilma_domains ' .
+ 'WHERE domain_name=?';
+ $values = array($domain_name);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getRow($sql, $values, DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Returns a list of all users, aliases, or groups and forwards for a
+ * domain.
+ *
+ * @param string $domain Domain on which to search.
+ * @param string $type Only return a specific type. One of 'all',
+ * 'user', 'alias','forward', or 'group'.
+ * @param string $key Sort list by this key.
+ * @param integer $direction Sort direction.
+ *
+ * @return array Account information for this domain
+ */
+ function getAddresses($domain, $type = 'all', $key = 'user_name',
+ $direction = 0)
+ {
+ $addresses = array();
+ if ($type == 'all' || $type == 'user') {
+ $users = $this->_getUsers($domain);
+ $addresses = array_merge($addresses, $users);
+ }
+ if ($type == 'all' || $type == 'alias') {
+ $aliases = $this->_getAliases($domain);
+ $addresses = array_merge($addresses, $aliases);
+ }
+ if (($type == 'all') || ($type == 'forward')) {
+ $forwards = $this->_getGroupsAndForwards('forward',$domain);
+ $addresses = array_merge($addresses, $forwards);
+ }
+ if (($type == 'all') || ($type == 'group')) {
+ $groups = $this->_getGroupsAndForwards('group',$domain);
+ $addresses = array_merge($addresses, $groups);
+ }
+ // Sort the results
+ require_once 'Horde/Array.php';
+ Horde_Array::arraySort($addresses, $key, $direction, true);
+ return $addresses;
+ }
+
+ function getUser($user_id) {
+ $user = $this->getUserStatus($user_id);
+
+ if (is_a($user, 'PEAR_Error')) {
+ return PEAR::raiseError(sprintf(_("Unable to qualify address: %s"), $user->getMessage()));
+ }
+ if(isset($user) && is_array($user)) {
+ return $user;
+ } else {
+ return PEAR::raiseError(_("Unable to qualify address."));
+ }
+ }
+
+ /**
+ * Returns an array of all users, aliases, groups and forwards for this
+ * domain.
+ *
+ * @param string $domain Domain on which to search
+ * @param optional string $type Only return a specific type
+ *
+ * @return array Account information for this domain
+ */
+ function _getUsers($domain = null)
+ {
+ //$domain = $domain['domain_name'];
+ // Cache for multiple calls
+ static $users = array();
+ if (is_null($domain) && isset($users['_all'])) {
+ return $users['_all'];
+ }
+
+ if (!is_null($domain)
+ && isset($users[$domain])) {
+ return $users[$domain];
+ }
+
+ $filter = '(&';
+ if (!is_null($domain)) {
+ $filter .= '(mail=*@' . $domain . ')';
+ } else {
+ $domain = '_all';
+ }
+
+ // Make sure we don't get any forwards
+ $filter .= '(!(mailForwardingAddress=*))';
+
+ // FIXME: Check/add configured filter instead of objectclasses
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ $filter .= '(objectClass=' . $objectclass . ')';
+ }
+ $filter .= ')';
+
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error in LDAP search: %s"), ldap_error($this->LDAP)));
+ }
+
+ $res = ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error in LDAP search: %s"), ldap_error($this->LDAP)));
+ }
+
+ $users[$domain] = array();
+ $i = 0;
+ // Can't use foreach because of the array format returned by LDAP driver
+ while ($user = @$res[$i]) {
+ $users[$domain][$i]['id'] = $user['dn'];
+ $users[$domain][$i]['address'] = $user[$this->_getAttrByField('address')][0];
+ $users[$domain][$i]['type'] = 'user';
+ $users[$domain][$i]['user_name'] =
+ $user[$this->_getAttrByField('user_name')][0];
+ // We likely don't have read permission on the crypted password so
+ // avoid any warnings/errors about missing array elements
+ if (isset($user[$this->_getAttrByField('user_crypt')])) {
+ $users[$domain][$i]['user_crypt'] =
+ $user[$this->_getAttrByField('user_crypt')][0];
+ } else {
+ $users[$domain][$i]['user_crypt'] = '';
+ }
+ $users[$domain][$i]['user_full_name'] =
+ $user[$this->_getAttrByField('user_full_name')][0];
+ // Mute assignment errors on the following optional fields
+ // These may not be present if the mail is only forwarded
+ $users[$domain][$i]['user_uid'] =
+ @$user[$this->_getAttrByField('user_uid')][0];
+ $users[$domain][$i]['user_gid'] =
+ @$user[$this->_getAttrByField('user_gid')][0];
+ $users[$domain][$i]['user_home_dir'] =
+ @$user[$this->_getAttrByField('user_home_dir')][0];
+ $users[$domain][$i]['user_mail_dir'] =
+ @$user[$this->_getAttrByField('user_mail_dir')][0];
+ $users[$domain][$i]['user_mail_quota_bytes'] =
+ @$user[$this->_getAttrByField('user_mail_quota_bytes')][0];
+ $users[$domain][$i]['user_mail_quota_count'] =
+ @$user[$this->_getAttrByField('user_mail_quota_count')][0];
+
+ // If accountStatus is blank it's the same as active
+ if (!isset($user[$this->_getAttrByField('user_enabled')][0]) ||
+ ($user[$this->_getAttrByField('user_enabled')][0] == 'active')) {
+ $users[$domain][$i]['user_enabled'] = 'active';
+ } else {
+ // accountStatus can also be:
+ // noaccess (receives but cannot pick up mail)
+ // disabled (bounce incoming and deny pickup)
+ // deleted (bounce incoming but allow pickup)
+ $users[$domain][$i]['user_enabled'] =
+ $user[$this->_getAttrByField('user_enabled')][0];
+ }
+
+ $i++;
+ }
+
+ return $users[$domain];
+ }
+
+ function _getFields()
+ {
+ // LDAP attributes are always returned lower case!
+ static $fields = array(
+ 'address' => 'mail',
+ 'user_name' => 'uid',
+ 'user_crypt' => 'userpassword',
+ 'user_full_name' => 'cn',
+ 'user_uid' => 'qmailuid',
+ 'user_gid' => 'qmailgid',
+ 'user_home_dir' => 'homedirectory',
+ 'user_mail_dir' => 'mailmessagestore',
+ 'user_mail_quota_bytes' => 'mailquotasize',
+ 'user_mail_quota_count' => 'mailquotacount',
+ 'user_enabled' => 'accountstatus',
+ );
+
+ return $fields;
+
+ }
+
+ function _getAttrByField($field) {
+ $fields = $this->_getFields();
+ return $fields[$field];
+ }
+
+ function _getFieldByAttr($attr) {
+ $attrs = array_flip($this->_getFields());
+ return $attrs[$attr];
+ }
+
+ /**
+ * Returns available email address aliases. This method should not be
+ * called directly but rather by way of getAddresses().
+ *
+ * @access private
+ *
+ * @param string $target If passed a domain then return all alias emails
+ * for the domain, otherwise if passed a user name
+ * return all virtual emails for that user.
+ *
+ * @return array The used email aliases
+ */
+ function _getAliases($target = null)
+ {
+ // FIXME: Add static cache
+
+ $filter = '(&'; // Begin filter (cumulative AND)
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ // Add each objectClass from parameters
+ $filter .= '(objectClass=' . $objectclass . ')';
+ }
+ // FIXME: Add preconfigured filter from $this->_ldapparams
+
+ // Check if filtering only for domain.
+ if (($pos = strpos($target, '@')) === false && !empty($target)) {
+ $filter .= '(mailAlternateAddress=*@' . $target . ')';
+ // Otherwise filter for all aliases
+ } else {
+ $filter .= '(mailAlternateAddress=*)';
+ // Restrict the results to $target
+ if (!empty($target)) {
+ $filter .= '(mail=' . $target . ')'; // Add user's email
+ }
+ }
+ $filter .= ')'; // End filter
+
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"),
+ @ldap_error($this->_ldap)));
+ }
+
+ $res = @ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap)));
+ }
+
+ $aliases = array();
+ // Can't use foreach because of the array format returned by LDAP driver
+ $i = 0; // Virtual address index
+ $e = 0; // Entry counter
+ while ($entry = @$res[$e]) {
+ // If accountStatus is blank it's the same as active
+ if (!isset($entry[$this->_getAttrByField('user_enabled')][0]) ||
+ ($entry[$this->_getAttrByField('user_enabled')][0] == 'active')) {
+ $curstatus = 'active';
+ } else {
+ // accountStatus can also be:
+ // noaccess (receives but cannot pick up mail)
+ // disabled (bounce incoming and deny pickup)
+ // deleted (bounce incoming but allow pickup)
+ $curstatus = $entry[$this->_getAttrByField('user_enabled')][0];
+ }
+ $a = 0; // Attribute counter
+ while ($mail = @$entry['mailalternateaddress'][$a]) {
+ $aliases[$i]['id'] = $mail;
+ $aliases[$i]['type'] = 'alias';
+ $aliases[$i]['user_name'] = $mail;
+ $aliases[$i]['user_full_name'] = sprintf(_("Alias for %s"), $entry['mail'][0]);
+ $aliases[$i]['destination'] = $entry['mail'][0];
+ $aliases[$i]['user_enabled'] = $curstatus;
+ $a++;
+ $i++;
+ }
+ $e++;
+ }
+
+ return $aliases;
+ }
+
+ /**
+ * Returns all available groups and forwards unless otherwise specified.
+ * If a domain name is passed then limit the results to groups or forwards
+ * in that domain. This method should not be called directly, but rather by
+ * way of getAddresses()
+ *
+ * @access private
+ *
+ * @param string $acquire The default behavior is to acquire both
+ * groups and forwards; a value of 'group'
+ * will return only groups and a value of
+ * 'forward' will return only forwards.
+ * @param string $domain The name of the domain from which to fetch
+ *
+ * @return array The available groups and forwards with details
+ */
+ function _getGroupsAndForwards($acquire = null, $domain = null)
+ {
+ // Cache
+ static $grpfwds;
+ // TODO ?
+ /*
+ if (is_null($domain) && isset($grpfwds['_all'])) {
+ return $grpfwds['_all'];
+ }
+ if (!is_null($domain) && isset($grpfwds[$domain])) {
+ return $grpfwds[$domain];
+ }
+ */
+ $filter = '(&'; // Begin filter (cumulative AND)
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ // Add each objectClass from parameters
+ $filter .= '(objectClass=' . $objectclass . ')';
+ }
+ // FIXME: Add preconfigured filter from $this->_ldapparams
+
+ // Only return results which have a forward configured
+ $filter .= '(mailForwardingAddress=*)';
+
+ if (!empty($domain)) {
+ $filter .= '(|'; // mail or mailAlternateAddress
+ $filter .= '(mail=*@' . $domain . ')';
+ $filter .= '(mailAlternateAddress=*@' . $domain . ')';
+ $filter .= ')'; // end mail or mailAlternateAddress
+ } else {
+ $domain = '_all';
+ }
+ $filter .= ')'; // End filter
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"),
+ @ldap_error($this->_ldap)));
+ }
+
+ $res = @ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap)));
+ }
+
+ $grpfwds[$domain] = array();
+ // Can't use foreach because of the array format returned by LDAP driver
+ $i = 0; // Address index
+ $e = 0; // Entry counter
+
+ while ($entry = @$res[$e]) {
+ $targets = array();
+ $a = 0; // Attribute counter
+ while ($attr = @$res[$e]['mailforwardingaddress'][$a]) {
+ $targets[] = $attr;
+ $a++;
+ }
+ $type = $entry['mailforwardingaddress']["count"];
+ if($type > 1) {
+ $type = 'group';
+ } else {
+ $type = 'forward';
+ }
+ if(($acquire == 'all') || ($type == $acquire)) {
+ $grpfwds[$domain][$i] = array(
+ 'id' => $entry['dn'],
+ 'type' => $type,
+ 'address' => $entry[$this->_getAttrByField('address')][0],
+ 'targets' => $targets,
+ 'user_name' => $entry[$this->_getAttrByField('user_name')][0],
+ 'user_full_name' => @$entry[$this->_getAttrByField('user_name')][0],
+ );
+ // If accountStatus is blank it's the same as active
+ if (!isset($entry[$this->_getAttrByField('user_enabled')][0]) ||
+ ($entry[$this->_getAttrByField('user_enabled')][0] == 'active')) {
+ $grpfwds[$domain][$i]['user_enabled'] = 'active';
+ } else {
+ // accountStatus can also be:
+ // noaccess (receives but cannot pick up mail)
+ // disabled (bounce incoming and deny pickup)
+ // deleted (bounce incoming but allow pickup)
+ $grpfwds[$domain][$i]['user_enabled'] =
+ $entry[$this->_getAttrByField('user_enabled')][0];
+ }
+ } else {
+ $e++;
+ continue;
+ }
+ $e++;
+ $i++;
+ }
+ return $grpfwds[$domain];
+ }
+
+ /**
+ * Returns information for an email alias
+ *
+ * @param string $id The email alias id for which to return information.
+ *
+ * @return array The virtual email information.
+ */
+ function getAddressInfo($address, $type = 'all')
+ {
+ if ($type != 'alias') {
+ return parent::getAddressInfo($address, $type);
+ } else {
+ // FIXME: Which is faster? A linear array search or an LDAP search?
+ // I think LDAP in this case because we can't assume the domain.
+ $filter = '(&'; // Begin filter (cumulative AND)
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ // Add each objectClass from parameters
+ $filter .= '(objectClass=' . $objectclass . ')';
+ }
+ $filter .= '(mailAlternateAddress= ' . $address . ')';
+ $filter .= ')'; // End filter
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"),
+ @ldap_error($this->_ldap)));
+ }
+ $res = @ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap)));
+ }
+
+ if ($res['count'] !== 1) {
+ return PEAR::raiseError(_("More than one DN returned for this alias. Please contact an administrator to resolve this error."));
+ }
+
+ return array(
+ 'id' => $res[0]['dn'],
+ 'address' => $address,
+ 'destination' => $res[0]['mail'][0],
+ );
+ }
+ }
+
+ /**
+ * Returns the current number of set up users for a domain.
+ *
+ * @param string $domain_name The name of the domain for which to
+ * get the current number of users.
+ *
+ * @return integer The current number of users.
+ */
+ function getDomainNumUsers($domain_name)
+ {
+ return count($this->_getUsers($domain_name));
+ }
+
+ /**
+ * Saves a domain to the backend.
+ *
+ * @param array $info The domain information to save to the backend.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function _saveDomain(&$info)
+ {
+ // We store the records within Horde's configured SQL database for
+ // Vilma because LDAP has no mechanism for tracking domains
+ // that are valid for this system.
+ $values = array($info['name'], $info['transport'],
+ (int)$info['max_users'], (int)$info['quota']);
+
+ if (empty($info['domain_id'])) {
+ $nextid = $this->_db->nextId('vilma_domains');
+ $sql = 'INSERT INTO vilma_domains (domain_id, domain_name, ' .
+ 'domain_transport, domain_max_users, domain_quota) VALUES ' .
+ '(?, ?, ?, ?, ?)';
+ array_unshift($values, $nextid);
+ } else {
+ $sql = 'UPDATE vilma_domains SET domain_name=?, ' .
+ 'domain_transport=?, domain_max_users=?, domain_quota=? ' .
+ 'WHERE domain_id=?';
+ array_push($values, $info['domain_id']);
+ }
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->query($sql, $values);
+ }
+
+ /**
+ * Deletes a given domain.
+ *
+ * @param string $domain_id The id of the domain to delete.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function _deleteDomain($domain_id)
+ {
+ $domain_record = $this->getDomain($domain_id);
+ if (is_a($domain_record, 'PEAR_Error')) {
+ return $domain_record;
+ }
+
+ $domain_name = $domain_record['domain_name'];
+
+ // FIXME: Add logic to remove all users, aliases, and grpfwds for this
+ // domain
+
+ /* Finally delete the domain. */
+ $sql = 'DELETE FROM vilma_domains WHERE domain_id=?';
+ $values = array((int)$domain_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->query($sql, $values);
+ }
+
+ /**
+ * Searchs for a given email account.
+ *
+ * @param string $email_id The id of the account to be searched for.
+ *
+ * @return Array of data for given email account on success or no
+ * information found; and for an error a PEAR::Error otherwise.
+ */
+ function searchForAliases($email_id) {
+ // Get the user's DN
+ $filter = '(&'; // Begin filter (cumulative AND)
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ // Add each objectClass from parameters
+ $filter .= '(objectClass=' . $objectclass . ')';
+ }
+ /*
+ // Check if filtering only for domain.
+ if (($pos = strpos($target, '@')) === false && !empty($email_id)) {
+ $filter .= '(mailAlternateAddress=*@' . $email_id . ')';
+ // Otherwise filter for all aliases
+ } else {
+ $filter .= '(mailAlternateAddress=*)';
+ // Restrict the results to $target
+ if (!empty($email_id)) {
+ $filter .= '(mail=' . $email_id . ')'; // Add user's email
+ }
+ }
+ */
+ $filter .= '(mailAlternateAddress=' . $email_id . ')';
+ $filter .= ')'; // End filter
+
+ //echo $filter;
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"),
+ @ldap_error($this->_ldap)));
+ }
+ $res = @ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap)));
+ }
+
+ return $res;
+ }
+
+ /**
+ * Searchs for a given email account.
+ *
+ * @param string $email_id The id of the account to be searched for.
+ *
+ * @return Array of data for given email account on success or no
+ * information found; and for an error a PEAR::Error otherwise.
+ */
+ function searchForUser($email_id)
+ {
+ // Get the user's DN
+ $filter = '(&';
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ // Add each objectClass from parameters
+ $filter .= '(objectclass=' . $objectclass . ')';
+ }
+ $filter .= '(mail=' . $email_id . '))';
+
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"),
+ @ldap_error($this->_ldap)));
+ }
+ $res = @ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap)));
+ }
+
+ if ($res['count'] === 0) {
+ return PEAR::raiseError(_("Unable to acquire handle on DN. Aborting delete operation."));
+ } else if($res['count'] !== 1) {
+ return PEAR::raiseError(_("More than one DN returned. Aborting delete operation."));
+ }
+ return $res;
+ }
+
+ /**
+ * Deletes a given email account.
+ *
+ * @param string $email_id The id of the account to delete (not an alias)
+ *
+ * @return mixed True on success or PEAR::Error otherwise.
+ */
+ function deleteUser($email_id)
+ {
+ // Get the user's DN
+ $filter = '(&';
+ foreach ($this->_ldapparams['objectclass'] as $objectclass) {
+ // Add each objectClass from parameters
+ $filter .= '(objectclass=' . $objectclass . ')';
+ }
+ $filter .= '(mail=' . $email_id . ')';
+ //echo $email_id . '<br>';
+ $filter .= ')';
+ Horde::logMessage($filter, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"),
+ @ldap_error($this->_ldap)));
+ }
+ $res = @ldap_get_entries($this->_ldap, $res);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap)));
+ }
+
+ if ($res['count'] === 0) {
+ return PEAR::raiseError(_("Unable to acquire handle on DN. Aborting delete operation."));
+ } else if($res['count'] !== 1) {
+ return PEAR::raiseError(_("More than one DN returned. Aborting delete operation."));
+ }
+ // We now have one unique DN to delete.
+ $res = @ldap_delete($this->_ldap, $res[0]['dn']);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error deleting account from LDAP: %s"), @ldap_error($this->_ldap)));
+ }
+
+ return true;
+ }
+
+ /**
+ * Modifies alias data on the backend.
+ *
+ * @param mixed $info The alias, or an array containing the alias and supporting data.
+ * @param string $mode The operation requested: add, update, delete.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function _savealias($info,$mode = null)
+ {
+ if ($mode == 'delete') {
+ $address = $info;
+
+ $user_info = $this->searchForAliases($address);
+ $aliasesList = $user_info[0]['mailalternateaddress'];
+ if (is_a($user_info, 'PEAR_Error') || ($res['count'] === 0) ) {
+ return PEAR::raiseError(_("Error reading address information from backend."));
+ }
+ $addrinfo = $this->getAddressInfo($address);
+ if (is_a($addrinfo, 'PEAR_Error')) {
+ return $addrinfo;
+ }
+ $type = $addrinfo['type'];
+ $addrinfo = $this->getAddressInfo($address,$type);
+ if (is_a($addrinfo, 'PEAR_Error')) {
+ return $addrinfo;
+ }
+ $objectClassData = null;
+ if(isset($user_info[0]['objectclass'])) {
+ $objectClassData = $user_info[0]['objectclass'];
+ }
+ if ($this->_ldap) {
+ // bind with appropriate dn to give update access
+ $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'],
+ $this->_ldapparams['bindpw']);
+ if (!$res) {
+ return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials."));
+ }
+ $tmp = array();
+ $key = null;
+ foreach($aliasesList as $key => $val) {
+ if($val != $address) {
+ array_push($tmp,$val);
+ }
+ }
+ $entry["mailalternateaddress"] = $tmp;
+
+ $rdn = 'mail=' . $addrinfo['destination'];
+ $dn = $rdn . ',' . $this->_ldapparams['basedn'];
+ $res = @ldap_modify($this->_ldap, $dn, $entry);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap)));
+ } else {
+ return TRUE;
+ }
+ }
+ }
+
+ return PEAR::raiseError(_("Unable to save user information."));
+ }
+
+ function _saveUser(&$info)
+ {
+ if ($info['mode'] == 'edit') {
+ $address = $info['address'];
+ if(!isset($address) || empty($address)) {
+ $user_name = $info['user_name'];
+ $domain = $info['domain'];
+ if(!(!isset($user_name) || empty($user_name)) && !(!isset($user_name) || empty($user_name))) {
+ $address = $info['user_name'] . $info['domain'];
+ } else {
+ return PEAR::raiseError(_("Unable to acquire handle on address."));
+ }
+ }
+ $addrinfo = $this->getAddressInfo($address);
+ if (is_a($addrinfo, 'PEAR_Error')) {
+ return $addrinfo;
+ }
+ $type = $addrinfo['type'];
+ if($type == 'user') {
+ //continue, this is a user.
+ } else {
+ //return PEAR::raiseError(_("Unable to save account of type " . $type));
+ }
+
+ $user_info = $this->searchForUser($address);
+ if (is_a($user_info, 'PEAR_Error') || ($res['count'] === 0) ) {
+ return PEAR::raiseError(_("Error reading address information from backend."));
+ }
+
+ $objectClassData = null;
+ if(isset($user_info[0]['objectclass'])) {
+ $objectClassData = $user_info[0]['objectclass'];
+ }
+
+ unset($info['mode']); // Don't want to save this to LDAP
+ // Special case for the password: If it was provided, it needs
+ // to be crypted. Otherwise, ignore it.
+ if (isset($info['password'])) {
+ if (!empty($user['password'])) {
+ // FIXME: Allow choice of hash
+ $info['user_password'] = Horde_Auth::getCryptedPassowrd($info['password'], '', 'ssha', true);
+ }
+ unset($info['password']);
+ }
+
+ $tmp['dn'] = $addrinfo['id'];
+ foreach ($info as $key => $val) {
+ $attr = $this->_getAttrByField($key);
+ $tmp[$attr] = $val;
+ }
+
+ if ($this->_ldap) {
+ // bind with appropriate dn to give update access
+ $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'],
+ $this->_ldapparams['bindpw']);
+ if (!$res) {
+ return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials."));
+ }
+
+ // prepare data
+ $entry['cn'] = $info['user_full_name'];
+ // sn is not used operationally but we make an effort to be
+ // something sensical. No guarantees, though.
+ $entry['sn'] = array_pop(explode(' ', $info['user_full_name']));
+// The next two lines were reversed: which is right?
+ $entry['mail'] = $info['user_name'] . $info['domain'];
+ // $tmp['mail'];
+ $entry['uid'] = $entry['mail'];
+ $entry['homeDirectory'] = '/srv/vhost/mail/' . $info['domain'] .'/' . $info['user_name'];
+ if(($type != 'group') && ($type != 'forward')) {
+ $entry["qmailUID"] = 8;
+ $entry["qmailGID"] = 8;
+ }
+ $entry["accountstatus"] = $info["user_enabled"];
+ if(isset($info['password']) && !empty($info['password'])) {
+ // FIXME: Allow choice of hash
+ $entry["userPassword"] = Horde_Auth::getCryptedPassword($info['password'], '', 'ssha', true);
+ }
+ if(isset($objectClassData)) {
+ array_shift($objectClassData);
+ $entry['objectclass'] = $objectClassData;
+ } else {
+ $entry['objectclass'] = array();
+ $entry['objectclass'][] = 'top';
+ $entry['objectclass'][] = 'person';
+ $entry['objectclass'][] = 'organizationalPerson';
+ $entry['objectclass'][] = 'inetOrgPerson';
+ $entry['objectclass'][] = 'hordePerson';
+ $entry['objectclass'][] = 'qmailUser';
+ }
+
+ // Stir in any site-local custom LDAP attributes
+ $entry = Horde::callHook('_vilma_hook_getldapattrs',
+ array($entry), 'vilma');
+
+ $rdn = 'mail=' . $entry['mail'];
+ $dn = $rdn . ',' . $this->_ldapparams['basedn'];
+ $res = @ldap_modify($this->_ldap, $dn, $entry);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap)));
+ } else {
+ return TRUE;
+ }
+ }
+ } else if($info['mode'] == 'new') {
+ if ($this->_ldap) {
+ // bind with appropriate dn to give update access
+ $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'],
+ $this->_ldapparams['bindpw']);
+ if (!$res) {
+ return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials."));
+ }
+
+ // prepare data
+ $entry['cn'] = $info['user_full_name'];
+ // sn is not used operationally but we make an effort to be
+ // something sensical. No guarantees, though.
+ $entry['sn'] = array_pop(explode(' ', $info['user_full_name']));
+ $entry['mail'] = $info['user_name'] . '@' . $info['domain'];
+ // uid must match mail or SMTP auth fails
+ $entry['uid'] = $entry['mail'];
+ $entry['homeDirectory'] = '/srv/vhost/mail/' . $info['domain'] .'/' . $info['user_name'];
+ $entry['qmailUID'] = 8;
+ $entry['qmailGID'] = 8;
+ $entry['objectclass'] = array();
+ $entry['objectclass'][] = 'top';
+ $entry['objectclass'][] = 'person';
+ $entry['objectclass'][] = 'organizationalPerson';
+ $entry['objectclass'][] = 'inetOrgPerson';
+ $entry['objectclass'][] = 'hordePerson';
+ $entry['objectclass'][] = 'qmailUser';
+ $entry["accountstatus"] = $info["user_enabled"];
+ // FIXME: Allow choice of hash
+ $entry["userPassword"] = Horde_Auth::getCryptedPassword($info['password'], '', 'ssha', true);
+
+ // Stir in any site-local custom LDAP attributes
+ $entry = Horde::callHook('_vilma_hook_getldapattrs',
+ array($entry), 'vilma');
+
+ $rdn = 'mail=' . $entry['mail'];
+ $dn = $rdn . ',' . $this->_ldapparams['basedn'];
+ $res = @ldap_add($this->_ldap, $dn, $entry);
+ if ($res === false) {
+ return PEAR::raiseError(sprintf(_("Error adding account to LDAP: %s"), @ldap_error($this->_ldap)));
+ } else {
+ return TRUE;
+ }
+ } else {
+ return PEAR::raiseError(_("Unable to connect to LDAP server"));
+ }
+ }
+
+ return PEAR::raiseError(_("Unable to save user information."));
+ }
+
+ /**
+ * Deletes a virtual email.
+ *
+ * @param integer $virtual_id The id of the virtual email to delete.
+ */
+ function deleteVirtual($virtual_id)
+ {
+ die("deleteVirtual()");
+ }
+
+ function getUserFormAttributes()
+ {
+ $attrs = array();
+ $attrs[] = array(
+ 'label' => _("Account Status"),
+ 'name' => 'user_enabled',
+ 'type' => 'enum',
+ 'required' => true,
+ 'readonly' => false,
+ 'description' => null,
+ 'params' => array(
+ array(
+ 'active' => _("Account is active"),
+ 'noaccess' => _("Disable Delivery Only"),
+ 'disabled' => _("Bounce Incoming Only"),
+ 'deleted' => _("Account is disabled"),
+ ),
+ ),
+ 'default' => 'active',
+ );
+
+ return $attrs;
+ }
+
+ function _connect()
+ {
+ if (!is_null($this->_ldap)) {
+ return true;
+ }
+
+ Horde::assertDriverConfig($this->_ldapparams, 'storage',
+ array('ldaphost', 'basedn', 'binddn', 'dn'));
+
+ if (!isset($this->_ldapparams['bindpw'])) {
+ $this->_ldapparams['bindpw'] = '';
+ }
+
+ $port = (isset($this->_ldapparams['port'])) ?
+ $this->_ldapparams['port'] : 389;
+
+ $this->_ldap = ldap_connect($this->_ldapparams['ldaphost'], $port);
+ if (!$this->_ldap) {
+ Horde::fatal("Unable to connect to LDAP server $hostname on $port",
+ __FILE__, __LINE__);
+ }
+ $res = ldap_set_option($this->_ldap, LDAP_OPT_PROTOCOL_VERSION,
+ $this->_ldapparams['version']);
+ if (!$res) {
+ return PEAR::raiseError(_("Unable to set LDAP protocol version"));
+ }
+ $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'],
+ $this->_ldapparams['bindpw']);
+ if (!$res) {
+ return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials."));
+ }
+
+ }
+
+ /**
+ * Initialise this backend, connect to the SQL database.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function _dbinit()
+ {
+ global $registry;
+
+ Horde::assertDriverConfig($this->_sqlparams, 'storage',
+ array('phptype'));
+
+ if (!isset($this->_sqlparams['database'])) {
+ $this->_sqlparams['database'] = '';
+ }
+ if (!isset($this->_sqlparams['username'])) {
+ $this->_sqlparams['username'] = '';
+ }
+ if (!isset($this->_sqlparams['hostspec'])) {
+ $this->_sqlparams['hostspec'] = '';
+ }
+
+ /* Connect to the SQL server using the supplied parameters. */
+ require_once 'DB.php';
+ $this->_db = &DB::connect($this->_sqlparams,
+ array('persistent' => !empty($this->_sqlparams['persistent'])));
+ if (is_a($this->_db, 'PEAR_Error')) {
+ return $this->_db;
+ }
+
+ // Set DB portability options.
+ switch ($this->_db->phptype) {
+ case 'mssql':
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Driver/sql.php,v 1.54 2009/01/06 18:02:27 jan Exp $
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @package Vilma
+ */
+class Vilma_Driver_sql extends Vilma_Driver {
+
+ /**
+ * @var DB
+ */
+ var $_db;
+
+ function Vilma_Driver_sql($params)
+ {
+ parent::Vilma_Driver($params);
+ $this->initialise();
+ }
+
+ /**
+ * Construct an SQL WHERE fragment to filter domains by domain key.
+ *
+ * @access private
+ *
+ * @param string $join Keyword to join expression to rest of SQL statement
+ * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'.
+ *
+ * @return array An SQL fragment and a list of values suitable for
+ * binding.
+ */
+ function _getDomainKeyFilter($join = 'WHERE')
+ {
+ if (empty($this->_params['tables']['domainkey'])) {
+ return array('', array());
+ }
+
+ return array(' ' . $join . ' domain_key = ?',
+ array($this->_params['tables']['domainkey']));
+ }
+
+ /**
+ * Construct an SQL WHERE fragment to filter users by domain key.
+ *
+ * @access private
+ *
+ * @param string $join Keyword to join expression to rest of SQL statement
+ * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'.
+ *
+ * @return array An SQL fragment and a list of values suitable for
+ * binding.
+ */
+ function _getUserKeyFilter($join = 'WHERE')
+ {
+ if (empty($this->_params['tables']['domainkey'])) {
+ return array('', array());
+ }
+ $binds = $this->_getDomainKeyFilter('AND');
+
+ return array(' ' . $join . ' EXISTS (SELECT domain_name' .
+ ' FROM ' . $this->_params['tables']['domains'] .
+ ' WHERE ' . $this->_getTableField('users', 'user_name') .
+ ' LIKE ? || ' . $this->_getTableField('domains', 'domain_name') .
+ ' ' . $binds[0] . ' )',
+ array_unshift($binds[1], '%@'));
+ }
+
+ /**
+ * Construct an SQL WHERE fragment to filter virtuals by domain key.
+ *
+ * @access private
+ *
+ * @param string $join Keyword to join expression to rest of SQL statement
+ * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'.
+ *
+ * @return string An SQL fragment.
+ */
+ function _getVirtualKeyFilter($join = 'WHERE')
+ {
+ if (empty($this->_params['tables']['domainkey'])) {
+ return array('', array());
+ }
+ $binds = $this->_getDomainKeyFilter('AND');
+
+ return array(' ' . $join . ' EXISTS (SELECT domain_name' .
+ ' FROM ' . $this->_params['tables']['domains'] .
+ ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') .
+ ' LIKE ? || ' . $this->_getTableField('domains', 'domain_name') .
+ ' ' . $binds[0] . ' )',
+ array_unshift($binds[1], '%@'));
+ }
+
+ /**
+ * Gets the list of fields from specific table for sql statement.
+ *
+ * @return string
+ */
+ function _getTableFields($table)
+ {
+ if (empty($this->_params['tables'][$table . '_fields'])){
+ return '*';
+ }
+
+ $domainsFields = $this->_params['tables'][$table . '_fields'];
+ foreach ($domainsFields as $defaultName => $customName) {
+ $fields[] = $customName . ' as ' . $defaultName;
+ }
+ return implode(', ', $fields);
+ }
+
+ /**
+ * Gets the real name of the field from specific table for sql statement.
+ *
+ * @return string
+ */
+ function _getTableField($table, $field)
+ {
+ if (empty($this->_params['tables'][$table . '_fields'])) {
+ return $field;
+ } else {
+ return $this->_params['tables'][$table . '_fields'][$field];
+ }
+ }
+
+ /**
+ *
+ *
+ * @return array
+ */
+ function _prepareRecord($table, $record)
+ {
+ if (empty($this->_params['tables'][$table . '_fields'])){
+ return $record;
+ }
+
+ $domainsFields = $this->_params['tables'][$table . '_fields'];
+ $newRecord = array();
+ foreach ($record as $defaultName => $value) {
+ $newRecord[$domainsFields[$defaultName]] = $record[$defaultName];
+ }
+ return $newRecord;
+ }
+
+ /**
+ * Gets the list of domains from the backend.
+ *
+ * @return array All the domains and their data in an array.
+ */
+ function getDomains()
+ {
+ $binds = $this->_getDomainKeyFilter();
+ $sql = 'SELECT '. $this->_getTableFields('domains') . ' FROM ' . $this->_params['tables']['domains'] .
+ $binds[0] . ' ORDER BY domain_name';
+ $values = $binds[1];
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Gets the specified domain information from the backend.
+ *
+ * @param integer $domain_id The id of the domain to fetch.
+ *
+ * @return array The domain's information in an array.
+ */
+ function getDomain($domain_id)
+ {
+ $binds = $this->_getDomainKeyFilter('AND');
+ $sql = 'SELECT '. $this->_getTableFields('domains') . ' FROM ' . $this->_params['tables']['domains'] .
+ ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?' . $binds[0];
+ array_unshift($binds[1], (int)$domain_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Given a domain name returns the information from the backend.
+ *
+ * @param string $name The name of the domain to fetch.
+ *
+ * @return array The domain's information in an array.
+ */
+ function getDomainByName($domain_name)
+ {
+ $binds = $this->_getDomainKeyFilter('AND');
+ $sql = 'SELECT '. $this->_getTableFields('domains') . ' FROM ' . $this->_params['tables']['domains'] .
+ ' WHERE ' . $this->_getTableField('domains', 'domain_name') . ' = ?' . $binds[0];
+ array_unshift($binds[1], $domain_name);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Returns all available users, if a domain name is passed then limit the
+ * list of users only to those users.
+ *
+ * @param string $domain The name of the domain for which to fetch the
+ * users.
+ *
+ * @return array The available users and their stored information.
+ */
+ function getUsers($domain = null)
+ {
+ /* Put together the SQL statement. */
+ if (is_null($domain)) {
+ /* Fetch all users. */
+ $binds = $this->_getUserKeyFilter();
+ $sql = 'SELECT '. $this->_getTableFields('users') . ' FROM ' . $this->_params['tables']['users'] .
+ $binds[0];
+ $values = $binds[1];
+ } else {
+ /* Fetch only users for a domain. */
+ $binds = $this->_getUserKeyFilter('AND');
+ $sql = 'SELECT '. $this->_getTableFields('users') . ' FROM ' . $this->_params['tables']['users'] .
+ ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?' . $binds[0] .
+ ' ORDER BY user_name';
+ array_unshift($binds[1], '%@' . $domain);
+ $values = $binds[1];
+ }
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Returns the user information for a given user id.
+ *
+ * @param integer $user_id The id of the user for which to fetch
+ * information.
+ *
+ * @return array The user information.
+ */
+ function getUser($user_id)
+ {
+ $binds = $this->_getUserKeyFilter('AND');
+ $sql = 'SELECT '. $this->_getTableFields('users') . ' FROM ' . $this->_params['tables']['users'] .
+ ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?' . $binds[0];
+ array_unshift($binds[1], (int)$user_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Returns available virtual emails.
+ *
+ * @param string $filter If passed a domain then return all virtual emails
+ * for the domain, otherwise if passed a user name
+ * return all virtual emails for that user.
+ *
+ * @return array The available virtual emails.
+ */
+ function getVirtuals($filter)
+ {
+ /* Check if filtering only for domain. */
+ if (($pos = strpos($filter, '@')) === false) {
+ $where = $this->_getTableField('virtuals', 'virtual_email') . ' LIKE ?';
+ $values = array('%@' . $filter);
+ } else {
+ $where = $this->_getTableField('virtuals', 'virtual_destination') . ' = ?';
+ $values = array($filter);
+ }
+
+ $binds = $this->_getVirtualKeyFilter('AND');
+ $sql = 'SELECT '. $this->_getTableFields('virtuals') . ' FROM ' . $this->_params['tables']['virtuals'] .
+ ' WHERE ' . $where . $binds[0] .
+ ' ORDER BY virtual_destination, virtual_email';
+ $values = array_merge($values, $binds[1]);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Returns information for a virtual id.
+ *
+ * @param integer $virtual_id The virtual id for which to return
+ * information.
+ *
+ * @return array The virtual email information.
+ */
+ function getVirtual($virtual_id)
+ {
+ $binds = $this->_getVirtualKeyFilter('AND');
+ $sql = 'SELECT '. $this->_getTableFields('virtuals') . ' FROM ' . $this->_params['tables']['virtuals'] .
+ ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?' . $binds[0];
+ array_unshift($binds[1], (int)$virtual_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $virtual = $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC);
+ $virtual['stripped_email'] = Vilma::stripUser($virtual['virtual_email']);
+
+ return $virtual;
+ }
+
+ /**
+ * Returns the current number of set up users for a domain.
+ *
+ * @param string $domain_name The name of the domain for which to
+ * get the current number of users.
+ *
+ * @return integer The current number of users.
+ */
+ function getDomainNumUsers($domain_name)
+ {
+ $binds = $this->_getUserKeyFilter('AND');
+ $sql = 'SELECT count(' . $this->_getTableField('users', 'user_name') . ')' .
+ ' FROM ' . $this->_params['tables']['users'] .
+ ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?' . $binds[0];
+ array_unshift($binds[1], '%@' . $domain_name);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->getOne($sql, $binds[1]);
+ }
+
+ /**
+ * Saves a domain to the backend.
+ *
+ * @param array $info The domain information to save to the backend.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function _saveDomain($info)
+ {
+ require_once 'Horde/SQL.php';
+
+ $record = array('domain_name' => $info['name'],
+ 'domain_transport' => $info['transport'],
+ 'domain_max_users' => (int)$info['max_users'],
+ 'domain_quota' => (int)$info['quota']);
+
+ if (empty($info['domain_id'])) {
+ $record['domain_id'] = $this->_db->nextId($this->_params['tables']['domains']);
+ if (!empty($this->_params['tables']['domainkey'])) {
+ $record['domain_key'] = $this->_params['tables']['domainkey'];
+ }
+
+ $sql = 'INSERT INTO ' . $this->_params['tables']['domains'] .
+ ' ' . Horde_SQL::insertValues($this->_db, $this->_prepareRecord('domains', $record));
+ $values = array();
+ } else {
+ $binds = $this->_getDomainKeyFilter('AND');
+ $sql = 'UPDATE ' . $this->_params['tables']['domains'] .
+ ' SET ' . Horde_SQL::updateValues($this->_db, $this->_prepareRecord('domains', $record)) .
+ ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?' . $binds[0];
+ array_unshift($binds[1], $info['domain_id']);
+ $values = $binds[1];
+ }
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->query($sql, $values);
+ }
+
+ /**
+ * Deletes a given domain.
+ *
+ * @param integer $domain_id The id of the domain to delete.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function _deleteDomain($domain_id)
+ {
+ $domain_record = $this->getDomain($domain_id);
+ if (is_a($domain_record, 'PEAR_Error')) {
+ return $domain_record;
+ }
+
+ $domain_name = $domain_record['domain_name'];
+
+ /* Delete all virtual emails for this domain. */
+ $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] .
+ ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') . ' LIKE ?';
+ $values = array('%@' . $domain_name);
+ $delete = $this->_db->query($sql, $values);
+ if (is_a($delete, 'PEAR_Error')) {
+ return $delete;
+ }
+
+ /* Delete all users for this domain. */
+ $sql = 'DELETE FROM ' . $this->_params['tables']['users'] .
+ ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?';
+ $values = array('%@' . $domain_name);
+ $delete = $this->_db->query($sql, $values);
+ if (is_a($delete, 'PEAR_Error')) {
+ return $delete;
+ }
+
+ /* Finally delete the domain. */
+ $sql = 'DELETE FROM ' . $this->_params['tables']['domains'] .
+ ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?';
+ $values = array((int)$domain_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->query($sql, $values);
+ }
+
+ /**
+ * Saves a user to the backend.
+ *
+ * @param array $info The user information to save.
+ *
+ * @return array The user information.
+ */
+ function _saveUser($info)
+ {
+ global $conf;
+
+ require_once 'Horde/SQL.php';
+
+ /* Access check (for domainkey). */
+ $res = $this->getDomainByName(Vilma::stripDomain($info['user_name']));
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ $mailboxes = &Vilma::getMailboxDriver();
+ if (is_a($mailboxes, 'PEAR_Error')) {
+ return $mailboxes;
+ }
+
+ if (empty($info['user_id'])) {
+ $info['user_id'] = $this->_db->nextId($this->_params['tables']['users']);
+ $create = true;
+ } else {
+ $create = false;
+ }
+
+ // Slightly hackish.
+ $mail_dir_base = isset($mailboxes->_params['mail_dir_base']) ?
+ $mailboxes->_params['mail_dir_base'] : '?';
+
+ $tuple = array('user_id' => (int)$info['user_id'],
+ 'user_name' => $info['user_name'],
+ 'user_full_name' => $info['user_full_name'],
+ 'user_home_dir' => $mail_dir_base,
+ 'user_mail_dir' => Vilma::stripDomain($info['user_name']) . '/' . Vilma::stripUser($info['user_name']) . '/',
+ 'user_mail_quota' => $this->getDomainQuota(Vilma::stripDomain($info['user_name'])) * 1024 * 1024,
+ 'user_enabled' => (int)$info['user_enabled']);
+
+ // UID and GID are slightly hackish (specific to maildrop driver), too
+ if (!isset($mailboxes->_params['uid'])) {
+ $tuple['user_uid'] = -1;
+ } else {
+ $tuple['user_uid'] = $mailboxes->_params['uid'];
+ }
+ if (!isset($mailboxes->_params['gid'])) {
+ $tuple['user_gid'] = -1;
+ } else {
+ $tuple['user_gid'] = $mailboxes->_params['gid'];
+ }
+
+ if (!empty($info['password'])) {
+ $tuple['user_clear'] = $info['password'];
+ $tuple['user_crypt'] = crypt($info['password'],
+ substr($info['password'], 0, 2));
+ } elseif ($create) {
+ return PEAR::raiseError(_("Password must be supplied when creating a new user."));
+ }
+
+ if ($create) {
+ $sql = 'INSERT INTO ' .
+ $this->_params['tables']['users'] . ' ' .
+ Horde_SQL::insertValues($this->_db, $this->_prepareRecord('users', $tuple));
+ } else {
+ $sql = sprintf('UPDATE %s SET %s WHERE ' . $this->_getTableField('users', 'user_id') . ' = %d',
+ $this->_params['tables']['users'],
+ Horde_SQL::updateValues($this->_db, $this->_prepareRecord('users', $tuple)),
+ (int)$info['user_id']);
+ }
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $result = $this->_db->query($sql);
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return $result;
+ }
+
+ return $info;
+ }
+
+ /**
+ * Deletes a requested user.
+ *
+ * @param integer $user_id The id of the user to delete.
+ *
+ * @return mixed True, or PEAR_Error on failure.
+ */
+ function _deleteUser($user_id)
+ {
+ $user = $this->getUser($user_id);
+ if (is_a($user, 'PEAR_Error')) {
+ return $user;
+ }
+
+ /* Delete all virtual emails for this user. */
+ $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] .
+ ' WHERE ' . $this->_getTableField('virtuals', 'virtual_destination') . ' = ?';
+ $values = array($user['user_name']);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $delete = $this->_db->query($sql, $values);
+ if (is_a($delete, 'PEAR_Error')) {
+ return $delete;
+ }
+
+ /* Delete the actual user. */
+ $sql = 'DELETE FROM ' . $this->_params['tables']['users'] .
+ ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?';
+ $values = array((int)$user_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ $result = $this->_db->query($sql, $values);
+ if (is_a($result, 'PEAR_Error')) {
+ return $result;
+ }
+
+ $mailboxes = &Vilma::getMailboxDriver();
+ if (is_a($mailboxes, 'PEAR_Error')) {
+ return $mailboxes;
+ }
+
+ return $mailboxes->deleteMailbox(Vilma::stripUser($user['user_name']),
+ Vilma::stripDomain($user['user_name']));
+ }
+
+ /**
+ * Saves virtual email address to the backend.
+ *
+ * @param array $info The virtual email data.
+ * @param string $domain The name of the domain for this virtual email.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function saveVirtual(&$info, $domain)
+ {
+ /* Access check (for domainkey) */
+ $res = $this->getDomainByName($domain);
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ if (empty($info['virtual_id'])) {
+ $info['virtual_id'] = $this->_db->nextId($this->_params['tables']['virtuals']);
+ $sql = 'INSERT INTO ' . $this->_params['tables']['virtuals'] .
+ ' (' . $this->_getTableField('virtuals', 'virtual_email') . ', ' .
+ $this->_getTableField('virtuals', 'virtual_destination') . ', ' .
+ $this->_getTableField('virtuals', 'virtual_id') . ') VALUES (?, ?, ?)';
+ } else {
+ $sql = 'UPDATE ' . $this->_params['tables']['virtuals'] .
+ ' SET ' . $this->_getTableField('virtuals', 'virtual_email') . ' = ?, '.
+ $this->_getTableField('virtuals', 'virtual_destination') . ' = ?' .
+ ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?';
+ }
+ $values = array($info['stripped_email'] . '@' . $domain,
+ $info['virtual_destination'],
+ $info['virtual_id']);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->query($sql, $values);
+ }
+
+ /**
+ * Deletes a virtual email.
+ *
+ * @param integer $virtual_id The id of the virtual email to delete.
+ */
+ function deleteVirtual($virtual_id)
+ {
+ $binds = $this->_getVirtualKeyFilter('AND');
+ $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] .
+ ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?' . $binds[0];
+ array_unshift($binds[1], $virtual_id);
+
+ Horde::logMessage($sql, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $this->_db->query($sql, $binds[1]);
+ }
+
+ /**
+ * Initialise this backend, connect to the SQL database.
+ *
+ * @return mixed True on success or PEAR error otherwise.
+ */
+ function initialise()
+ {
+ global $registry;
+
+ Horde::assertDriverConfig($this->_params, 'storage',
+ array('phptype'));
+
+ if (!isset($this->_params['database'])) {
+ $this->_params['database'] = '';
+ }
+ if (!isset($this->_params['username'])) {
+ $this->_params['username'] = '';
+ }
+ if (!isset($this->_params['hostspec'])) {
+ $this->_params['hostspec'] = '';
+ }
+
+ /* Use default table names if these are not set. */
+ if (!isset($this->_params['tables']['domains'])) {
+ $this->_params['tables']['domains'] = 'vilma_domains';
+ }
+ if (!isset($this->_params['tables']['users'])) {
+ $this->_params['tables']['users'] = 'vilma_users';
+ }
+ if (!isset($this->_params['tables']['virtuals'])) {
+ $this->_params['tables']['virtuals'] = 'vilma_virtuals';
+ }
+
+ /* Connect to the SQL server using the supplied parameters. */
+ require_once 'DB.php';
+ $this->_db = &DB::connect($this->_params,
+ array('persistent' => !empty($this->_params['persistent'])));
+ if (is_a($this->_db, 'PEAR_Error')) {
+ return $this->_db;
+ }
+
+ // Set DB portability options.
+ switch ($this->_db->phptype) {
+ case 'mssql':
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2006-2007 Alkaloid Networks <http://www.alkaloid.net>
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Forms/DeleteDomainForm.php,v 1.1 2008/03/12 02:52:34 bklang Exp $
+ *
+ * @author Ben Klang <ben@alkaloid.net>
+ * @package Vilma
+ */
+class DeleteDomainForm extends Horde_Form {
+
+ function DeleteDomainForm(&$vars)
+ {
+ parent::Horde_Form($vars, _("Delete Domain"));
+
+ $domain_record = $GLOBALS['vilma_driver']->getDomain($vars->get('domain_id'));
+ if (is_a($domain_record, 'PEAR_Error')) {
+ return $domain_record;
+ }
+
+ $domain = $domain_record['domain_name'];
+
+ /* Set up the form. */
+ $this->setButtons(array(_("Delete"), _("Do not delete")));
+ $this->addHidden('', 'domain_id', 'text', false);
+ $this->addVariable(sprintf(_("Delete domain \"%s\" and all associated email addresses?"), $domain), 'description', 'description', false);
+ }
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2006-2007 Alkaloid Networks <http://www.alkaloid.net>
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Forms/EditDomainForm.php,v 1.10 2009/07/14 18:43:46 selsky Exp $
+ *
+ * @author Ben Klang <ben@alkaloid.net>
+ * @package Vilma
+ */
+
+class EditDomainForm extends Horde_Form {
+
+ function EditDomainForm(&$vars)
+ {
+ /* Check if a form is being edited. */
+ $editing = $vars->exists('domain_id');
+ $domain = $_SESSION['vilma']['domain'];
+ parent::Horde_Form($vars, $editing ? _("Edit Domain") : _("New Domain"));
+ if ($editing && !$this->isSubmitted()) {
+ $domain = $GLOBALS['vilma_driver']->getDomain($vars->get('domain_id'));
+ if (is_a($domain, 'PEAR_Error')) {
+ return $domain;
+ }
+ $vars = new Horde_Variables($domain);
+ }
+ $vars->add('name', $domain['domain_name']);
+ $vars->add('transport', $domain['domain_transport']);
+ $vars->add('max_users', $domain['domain_max_users']);
+ $vars->add('quota', $domain['domain_quota']);
+ /* Set up the form. */
+ $this->setButtons(true, true);
+ $this->addHidden('', 'domain_id', 'text', false);
+ $this->addVariable(_("Domain"), 'name', 'text', true);
+ require_once 'Horde/Array.php';
+ $this->addVariable(_("Transport"), 'transport', 'enum', false, false, null, array(Horde_Array::valuesToKeys($GLOBALS['conf']['mta']['transports'])));
+ $this->addVariable(_("Max users"), 'max_users', 'int', false);
+ $this->addVariable(_("Quota"), 'quota', 'int', false, false, _("Value in MB"));
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2006-2007 Alkaloid Networks <http://www.alkaloid.net>
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Forms/EditUserForm.php,v 1.6 2009/05/27 23:57:32 bklang Exp $
+ *
+ * @author Ben Klang <ben@alkaloid.net>
+ * @package Vilma
+ */
+
+class EditUserForm extends Horde_Form {
+
+ function EditUserForm(&$vars)
+ {
+ global $vilma_driver;
+
+ $type = $vars->get('type');
+ $editing = ($vars->get('mode') == 'edit');
+ if ($editing) {
+ if($type == 'group') {
+ $title = sprintf(_("Edit Group for \"%s\""), $vars->get('domain'));
+ } else if($type == 'forward') {
+ $title = sprintf(_("Edit Forward for \"%s\""), $vars->get('domain'));
+ } else {
+ $title = sprintf(_("Edit User for \"%s\""), $vars->get('domain'));
+ }
+ } else {
+ $title = sprintf(_("New User @%s"), $vars->get('domain'));
+ }
+ parent::Horde_Form($vars, $title);
+
+ /* Set up the form. */
+ $this->setButtons(true, true);
+ $this->addHidden('', 'address', 'text', false);
+ $this->addHidden('', 'mode', 'text', false);
+ $this->addHidden('', 'domain', 'text', false);
+ $this->addHidden('', 'id', 'text', false);
+ if ($editing) {
+ $this->addHidden('', 'user_name', 'text', false);
+ }
+ $name = "User Name";
+ $type = $vars->get('type');
+ if($type == 'group') {
+ $name = "Group Name";
+ } else if($type == 'forward') {
+ $name = "Forward Name";
+ }
+ $this->addVariable(_($name), 'user_name', 'text', true, $editing, _("Name must begin with an alphanumeric character, must contain only alphanumeric and '._-' characters, and must end with an alphanumeric character."), array('~^[a-zA-Z0-9]{1,1}[a-zA-Z0-9._-]*[a-zA-Z0-9]$~'));
+ if ($editing) {
+ $this->addVariable(_("Password"), 'password', 'passwordconfirm', false, false, _("Only enter a password if you wish to change this user's password"));
+ } else {
+ $this->addVariable(_("Password"), 'password', 'passwordconfirm', true);
+ }
+ $this->addVariable(_("Full Name"), 'user_full_name', 'text', true);
+ $attrs = $vilma_driver->getUserFormAttributes();
+ foreach ($attrs as $attr) {
+ $v = &$this->addVariable($attr['label'], $attr['name'],
+ $attr['type'], $attr['required'],
+ $attr['readonly'], $attr['description'],
+ $attr['params']);
+
+ if (!isset($attr['default'])) {
+ $v->setDefault($attr['default']);
+ }
+ }
+ //$this->addVariable(_("Target(s)"), 'target', 'text', false);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/MailboxDriver.php,v 1.15 2009/01/06 18:02:27 jan Exp $
+ *
+ * @author Jason M. Felice <jason.m.felice@gmail.com>
+ * @package Vilma
+ */
+class Vilma_MailboxDriver {
+
+ var $_params;
+
+ /**
+ * Constructor.
+ *
+ * @access private
+ */
+ function Vilma_MailboxDriver($params = array())
+ {
+ $this->_params = $params;
+ }
+
+ /**
+ * Creates a new mailbox driver instance.
+ *
+ * @param string $driver The name of the driver to create an instance of.
+ * @param array $params Driver-specific parameters.
+ *
+ * @return Vilma_MailboxDriver The new driver instance or a PEAR_Error.
+ */
+ function &factory($driver, $params = array())
+ {
+ require_once VILMA_BASE . '/lib/MailboxDriver/' . $driver . '.php';
+ $class = 'Vilma_MailboxDriver_' . $driver;
+ $mailbox = &new $class($params);
+ return $mailbox;
+ }
+
+ /**
+ * Returns a mailbox driver instance with the specified params, creating
+ * it if necessary.
+ *
+ * @param string $driver The name of the driver to create an instance of.
+ * @param array $params Driver-specific parameters.
+ *
+ * @return Vilma_MailboxDriver The new driver instance or a PEAR_Error.
+ */
+ function &singleton($driver, $params = array())
+ {
+ static $cache;
+ $key = serialize(array($driver, $params));
+ if (!isset($cache[$key])) {
+ $ret = &Vilma_MailboxDriver::factory($driver, $params);
+ if (is_a($ret, 'PEAR_Error')) {
+ return $ret;
+ }
+ $cache[$key] = &$ret;
+ }
+ return $cache[$key];
+ }
+
+ /**
+ * Creates a new mailbox.
+ *
+ * This default implementation only returns an error.
+ *
+ * @param string $user The name of the mailbox to create
+ * @param string $domain The name of the domain in which to create the
+ * mailbox
+ * @return mixed True or PEAR_Error:: instance.
+ */
+ function createMailbox($user, $domain)
+ {
+ return PEAR::raiseError(_("This driver cannot create mailboxes."));
+ }
+
+ /**
+ * Deletes an existing mailbox.
+ *
+ * This default implementation only returns an error.
+ *
+ * @param string $user The name of the mailbox to delete
+ * @param string $domain The name of the domain in which to delete the
+ * mailbox
+ *
+ * @return mixed True or PEAR_Error:: instance.
+ */
+ function deleteMailbox($user, $domain)
+ {
+ return PEAR::raiseError(_("This driver cannot delete mailboxes."));
+ }
+
+ /**
+ * Checks whether a mailbox exists and is set up properly.
+ *
+ * @param string $user The name of the mailbox to check
+ * @param string $domain The mailbox's domain
+ *
+ * @return mixed True or PEAR_Error:: instance.
+ */
+ function checkMailbox($user, $domain)
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2006-2007 Alkaloid Networks <http://www.alkaloid.net/>
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/MailboxDriver/hooks.php,v 1.7 2007/09/10 22:28:57 jan Exp $
+ *
+ * @author Ben Klang <bklang@alkaloid.net>
+ * @package Vilma
+ */
+
+class Vilma_MailboxDriver_hooks extends Vilma_MailboxDriver {
+
+ function Vilma_MailboxDriver_hooks($params)
+ {
+ Horde::loadConfiguration('hooks.php', null, 'vilma');
+ }
+
+
+ function checkMailbox($user, $domain)
+ {
+ if (function_exists('_vilma_hook_checkMailbox')) {
+ return call_user_func('_vilma_hook_checkMailbox', $user, $domain);
+ } else {
+ return true;
+ }
+ }
+
+ function createMailbox($user, $domain)
+ {
+ if (function_exists('_vilma_hook_createMailbox')) {
+ return call_user_func('_vilma_hook_createMailbox', $user, $domain);
+ } else {
+ return true;
+ }
+ }
+
+ function deleteMailbox($user, $domain)
+ {
+ if (function_exists('_vilma_hook_deleteMailbox')) {
+ return call_user_func('_vilma_hook_deleteMailbox', $user, $domain);
+ } else {
+ return true;
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/MailboxDriver/imap.php,v 1.12 2009/01/06 18:02:28 jan Exp $
+ *
+ * @author Jason M. Felice <jason.m.felice@gmail.com>
+ * @package Vilma
+ */
+class Vilma_MailboxDriver_imap extends Vilma_MailboxDriver {
+
+ var $_imapAdmin = null;
+
+ function _connect()
+ {
+ if (!is_null($this->_imapAdmin)) {
+ return false;
+ }
+
+ // Catch c-client errors.
+ register_shutdown_function('imap_errors');
+ register_shutdown_function('imap_alerts');
+
+ require_once 'Horde/IMAP/Admin.php';
+ $admin = &new IMAP_Admin($this->_params);
+ if (is_a($admin, 'PEAR_Error')) {
+ return $admin;
+ }
+
+ $this->_imapAdmin = $admin;
+ return true;
+ }
+
+ function checkMailbox($user, $domain)
+ {
+ $res = $this->_connect();
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ if (!$this->_imapAdmin->mailboxExists($user . '@' . $domain)) {
+ return PEAR::raiseError(sprintf(_("Mailbox '%s@%s' does not exist."), $user, $domain));
+ }
+ }
+
+ function createMailbox($user, $domain)
+ {
+ $res = $this->_connect();
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ $mbox = $user . '@' . $domain;
+
+ $res = $this->_imapAdmin->addMailbox($mbox);
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ return true;
+ }
+
+ function deleteMailbox($user, $domain)
+ {
+ $res = $this->_connect();
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ $res = $this->_imapAdmin->removeMailbox($user . '@' . $domain);
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/MailboxDriver/maildrop.php,v 1.17 2009/05/27 23:57:32 bklang Exp $
+ *
+ * @author Jason M. Felice <jason.m.felice@gmail.com>
+ * @package Vilma
+ */
+class Vilma_MailboxDriver_maildrop extends Vilma_MailboxDriver {
+
+ function _getMailboxDir($user, $domain)
+ {
+ if (empty($this->_params['mail_dir_base'])) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError(_("No 'mail_dir_base' parameter specified to maildrop driver."));
+ }
+ $dir = $this->_params['mail_dir_base'];
+ $usedomain = isset($this->_params['usedomain']) ? $this->_params['usedomain'] : false;
+ if ($usedomain) {
+ $dir .= '/' . $domain;
+ }
+
+ return $dir . '/' . $user;
+ }
+
+ function checkMailbox($user, $domain)
+ {
+ static $exists;
+
+ $dir = $this->_getMailboxDir($user, $domain);
+ if (is_a($dir, 'PEAR_Error')) {
+ return $dir;
+ }
+
+ if (!isset($exists[$dir])) {
+ $exists[$dir] = is_dir($dir);
+ }
+
+ if (!$exists[$dir]) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError(sprintf(_("Maildrop directory \"%s\" does not exist."), $dir));
+ }
+
+ return true;
+ }
+
+ function createMailbox($user, $domain)
+ {
+ $dir = $this->_getMailboxDir($user, $domain);
+ if (is_a($dir, 'PEAR_Error')) {
+ return $dir;
+ }
+ if (empty($this->_params['system_user'])) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError(_("No 'system_user' parameter specified to maildrop driver."));
+ }
+
+ $create_function = sprintf('sudo -u %s maildirmake %s',
+ escapeshellarg($this->_params['system_user']),
+ escapeshellarg($dir));
+ exec($create_function);
+ return true;
+ }
+
+ /**
+ * @TODO: Implement
+ */
+ function deleteMailbox($user, $domain)
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/MailboxDriver/null.php,v 1.1 2009/05/28 00:33:00 bklang Exp $
+ *
+ * @author David Cummings <davidcummings@acm.org>
+ * @package Vilma
+ */
+class Vilma_MailboxDriver_null extends Vilma_MailboxDriver {
+
+ function _getMailboxDir($user, $domain)
+ {
+ /*
+ if (empty($this->_params['mail_dir_base'])) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError(_("No 'mail_dir_base' parameter specified to maildrop driver."));
+ }
+ $dir = $this->_params['mail_dir_base'];
+ $usedomain = isset($this->_params['usedomain']) ? $this->_params['usedomain'] : false;
+ if ($usedomain) {
+ $dir .= '/' . $domain;
+ }
+
+ return $dir . '/' . $user;
+ */
+ }
+
+ function checkMailbox($user, $domain)
+ {
+ /*
+ static $exists;
+
+ $dir = $this->_getMailboxDir($user, $domain);
+ if (is_a($dir, 'PEAR_Error')) {
+ return $dir;
+ }
+
+ if (!isset($exists[$dir])) {
+ $exists[$dir] = is_dir($dir);
+ }
+
+ if (!$exists[$dir]) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError(sprintf(_("Maildrop directory \"%s\" does not exist."), $dir));
+ }
+ */
+
+ return true;
+ }
+
+ function createMailbox($user, $domain)
+ {
+ $dir = $this->_getMailboxDir($user, $domain);
+ if (is_a($dir, 'PEAR_Error')) {
+ return $dir;
+ }
+ if (empty($this->_params['system_user'])) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError(_("No 'system_user' parameter specified to maildrop driver."));
+ }
+
+ $create_function = sprintf('sudo -u %s maildirmake %s',
+ escapeshellarg($this->_params['system_user']),
+ escapeshellarg($dir));
+ exec($create_function);
+ return true;
+ }
+
+ /**
+ * @TODO: Implement
+ */
+ function deleteMailbox($user, $domain)
+ {
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/Vilma.php,v 1.34 2009/07/08 18:30:03 slusarz Exp $
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @author David Cummings <davidcummings@acm.org>
+ * @package Vilma
+ */
+class Vilma {
+
+ /**
+ * Check whether the current user has administrative permissions over
+ * the requested domain at the given permissions level.
+ * Also checks to see if the user is a Vilma superadmin.
+ * If the user is a Horde admin they automatically have permission.
+ *
+ * @param string $domain Domain for which to check permissions
+ * @param int $permmask Permissions that must be set for the user
+ *
+ * @return boolean True if the user has the requested permission
+ */
+ function hasPermission($domain, $permmask = null)
+ {
+ // FIXME Should this really be the case? Superadmin is more granular
+ if (Horde_Auth::isAdmin()) {
+ return true;
+ }
+
+ if ($permmask === null) {
+ $permmask = PERMS_SHOW|PERMS_READ;
+ }
+
+ # Default deny all permissions
+ $user = 0;
+ $superadmin = 0;
+
+ $superadmin = $GLOBALS['perms']->hasPermission('vilma:domains',
+ Horde_Auth::getAuth(), $permmask);
+
+ $user = $GLOBALS['perms']->hasPermission($permname, Horde_Auth::getAuth(),
+ $permmask);
+
+ return ($superadmin | $user);
+ }
+
+ function getUserMgrTypes()
+ {
+ return array(
+ 'all' => array(
+ 'singular' => _("All"),
+ 'plural' => _("All") ),
+ 'user' => array(
+ 'singular' => _("User"),
+ 'plural' => _("Users"), ),
+ 'alias' => array(
+ 'singular' => _("Alias"),
+ 'plural' => _("Aliases"), ),
+ //'grpfwd' => array(
+ // 'singular' => _("Group/Forward"),
+ // 'plural' => _("Groups and Forwards"), ), );
+ 'group' => array(
+ 'singular' => _("Group"),
+ 'plural' => _("Groups"), ),
+ 'forward' => array(
+ 'singular' => _("Forward"),
+ 'plural' => _("Forwards"),), );
+ }
+
+ /**
+ * Create tabs to navigate the user manager area
+ *
+ * return object Horde_UI_Tabs object
+ */
+ function getUserMgrTabs(&$vars)
+ {
+ $url = Horde::applicationUrl('users/index.php');
+ $tabs = &new Horde_UI_Tabs('section', $vars);
+ foreach (Vilma::getUserMgrTypes() as $section => $desc) {
+ $tabs->addTab($desc['plural'], $url, $section);
+ }
+ return $tabs;
+ }
+
+ /**
+ * Attempt to determine the current domain name based on current user or
+ * a domain_id passed in by form.
+ *
+ * @return mixed string domain on success, false on failure, PEAR::Error on error
+ */
+ function getCurDomain()
+ {
+ // Domain is passed in by ID, which may or may not be the
+ // the same as the actual DNS domain name
+ $domain_id = Horde_Util::getFormData('domain_id');
+
+ if (!empty($domain_id)) {
+ // FIXME: Make sure this only runs once per page-load
+ $domain = $GLOBALS['vilma_driver']->getDomain($domain_id);
+ if (is_a($domain, 'PEAR_Error')) {
+ return $domain;
+ }
+ if (empty($domain['domain_name'])) {
+ $domain = false;
+ }
+ Vilma::setCurDomain($domain);
+ } elseif (isset($_SESSION['vilma']['domain'])) {
+ $domain = $_SESSION['vilma']['domain'];
+ }
+
+ return $domain;
+ }
+
+ /**
+ * Set the current domain
+ */
+ function setCurDomain($domain)
+ {
+ $_SESSION['vilma']['domain'] = $domain;
+ }
+
+ /**
+ * Strip the domain from an email address (leaving the Username)
+ *
+ * @param string $email Email address to strip (leaving the Username)
+ *
+ * @return string Username portion of supplied email address
+ */
+ function stripUser($email)
+ {
+ list($user, $domain) = explode('@', $email);
+ return $user;
+ }
+
+ /**
+ * Strip the username from an email address (leaving the domain)
+ *
+ * @param string $email Email address to strip (leaving the domain)
+ *
+ * @return string Domain portion of supplied email address
+ */
+ function stripDomain($email)
+ {
+ $parts = explode('@', $email);
+ if (count($parts) == 2) {
+ $parts = explode(',', $parts[1]);
+ return $parts[0];
+ }
+ return null;
+ }
+
+ function &getMailboxDriver()
+ {
+ global $conf;
+
+ require_once VILMA_BASE . '/lib/MailboxDriver.php';
+ $driver = &Vilma_MailboxDriver::singleton($conf['mailboxes']['driver'],
+ $conf['mailboxes']['params']);
+ return $driver;
+ }
+
+ /**
+ * Build Vilma's list of menu items.
+ */
+ function getMenu($returnType = 'object')
+ {
+ $menu = new Horde_Menu();
+
+ $menu->add(Horde::applicationUrl('domains/index.php'), _("_Domains"), 'domain.png');
+
+ if (Vilma::getCurDomain()) {
+ $domain = $_SESSION['vilma']['domain'];
+ $url = Horde::applicationUrl('users/index.php');
+ $tmp = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']);
+ $menu->add(Horde::applicationUrl($tmp), _($domain['domain_name']), 'domain.png');
+ $menu->add(Horde::applicationUrl('users/edit.php'), _("New _Address"), 'user.png', $GLOBALS['registry']->getImageDir('horde'));
+ } else {
+ $menu->add(Horde::applicationUrl('domains/edit.php'), _("_New Domain"), 'domain.png');
+ }
+
+ if ($returnType == 'object') {
+ return $menu;
+ } else {
+ return $menu->render();
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Vilma external API interface.
+ *
+ * This file defines Vilma's external API interface. Other applications
+ * can interact with Vilma through this API.
+ *
+ * Copyright 2006-2007 Alkaloid Networks <http://www.alkaloid.net/>
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/api.php,v 1.10 2007/06/27 17:24:16 jan Exp $
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Ben Klang <bklang@alkaloid.net>
+ * @package Vilma
+ */
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+
+$_services['perms'] = array(
+ 'args' => array(),
+ 'type' => '{urn:horde}stringArray');
+
+
+$_services['listDomains'] = array(
+ 'args' => array(),
+ 'type' => '{urn:horde}stringArray');
+
+function _vilma_perms()
+{
+ static $perms = array();
+ if (!empty($perms)) {
+ return $perms;
+ }
+
+ require_once VILMA_BASE . '/lib/base.php';
+ global $vilma_driver;
+
+ $perms['tree']['vilma']['superadmin'] = false;
+ $perms['title']['vilma:superadmin'] = _("Super Administrator");
+
+ $domains = $vilma_driver->getDomains();
+
+ // Run through every domain
+ foreach ($domains as $domain) {
+ $d = $domain['domain_id'];
+ $perms['tree']['vilma']['domains'][$d] = false;
+ $perms['title']['vilma:domains:' . $d] = $domain['name'];
+ }
+
+ return $perms;
+}
+
+function _vilma_listDomains()
+{
+ require_once VILMA_BASE . '/lib/base.php';
+ global $vilma_driver;
+
+ return $vilma_driver->getDomains();
+ $domains = array();
+ foreach ($vilma_driver->getDomains() as $domain) {
+ $domains[] = $domain['domain_name'];
+ }
+ return $domains;
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * $Horde: vilma/lib/base.php,v 1.37 2009/07/13 20:05:58 slusarz Exp $
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @author Ben Klang <ben@alkaloid.net>
+ * @package Vilma
+ */
+
+/* Check for a prior definition of HORDE_BASE (perhaps by an auto_prepend_file
+ * definition for site customization). */
+if (!defined('HORDE_BASE')) {
+ @define('HORDE_BASE', dirname(__FILE__) . '/../..');
+}
+
+/* Load the Horde Framework core, and set up inclusion paths. */
+require_once HORDE_BASE . '/lib/core.php';
+
+/* Registry. */
+$registry = Horde_Registry::singleton();
+try {
+ $registry->pushApp('vilma', !defined('AUTH_HANDLER'));
+} catch (Horde_Exception $e) {
+ if ($e->getCode() == 'permission_denied') {
+ Horde::authenticationFailureRedirect();
+ }
+ Horde::fatal($e, __FILE__, __LINE__, false);
+}
+$conf = &$GLOBALS['conf'];
+@define('VILMA_TEMPLATES', $registry->get('templates'));
+
+/* Find the base file path of Vilma */
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+
+/* Vilma base library */
+require_once VILMA_BASE . '/lib/Vilma.php';
+require_once VILMA_BASE . '/lib/Driver.php';
+
+/* Templates */
+$template = &new Horde_Template();
+
+/* Notification system. */
+$notification = &Horde_Notification::singleton();
+$notification->attach('status');
+
+/* Navigation Tabs */
+require_once 'Horde/UI/Tabs.php';
+
+/* Vilma driver. */
+$GLOBALS['vilma_driver'] = &Vilma_Driver::singleton();
+
+// Get the currently active domain, possibly storing a change into the session
+$curdomain = Vilma::getCurDomain();
--- /dev/null
+--TEST--
+Vilma_Driver_sql::
+--FILE--
+<?php
+
+echo "Load... ";
+
+define('AUTH_HANDLER', false);
+define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+
+echo "ok\n";
+
+checkConstruction();
+
+/* Delete our test domains in case we bombed on an earlier trial. */
+ob_start();
+checkDeleteDomain();
+ob_end_clean();
+
+checkSaveDomain();
+checkDeleteDomain();
+
+function checkConstruction()
+{
+ global $conf;
+
+ echo "Checking construction... ";
+
+ $unfiltered_params = $conf['storage']['params'];
+ if (isset($unfiltered_params['tables']['domainkey'])) {
+ unset($unfiltered_params['tables']['domainkey']);
+ }
+
+ $GLOBALS['unfiltered'] = &Vilma_Driver::singleton('sql', $unfiltered_params);
+ if (is_a($GLOBALS['unfiltered'], 'PEAR_Error')) {
+ printf(_("ERROR(1): %s\n"), $GLOBALS['unfiltered']->getMessage());
+ return;
+ }
+
+ $filtered_params = $conf['storage']['params'];
+ $filtered_params['tables']['domainkey'] = '__FOO';
+
+ $GLOBALS['filtered'] = &Vilma_Driver::singleton('sql', $filtered_params);
+ if (is_a($GLOBALS['filtered'], 'PEAR_Error')) {
+ printf(_("ERROR(2): %s\n"), $GLOBALS['filtered']->getMessage());
+ return;
+ }
+
+ echo "ok\n";
+}
+
+function checkSaveDomain()
+{
+ global $filtered, $unfiltered;
+
+ echo "Checking saveDomain()... ";
+
+ $domain = array('domain_name' => 'filtered.example.com',
+ 'domain_transport' => 'cyrus',
+ 'domain_admin' => 'test@filtered.example.com',
+ 'domain_max_users' => 15,
+ 'domain_quota' => 0);
+
+ $res = $filtered->saveDomain($domain);
+ if (is_a($res, 'PEAR_Error')) {
+ var_dump($res);
+ printf(_("ERROR(1): %s\n"), $res->getMessage());
+ return;
+ }
+
+ $res = $filtered->getDomainByName('filtered.example.com');
+ if (is_a($res, 'PEAR_Error')) {
+ printf(_("ERROR(2): %s\n"), $res->getMessage());
+ return;
+ }
+
+ if ($res['domain_name'] != 'filtered.example.com') {
+ echo _("ERROR(3): got wrong domain.\n");
+ return;
+ }
+ if ($res['domain_transport'] != $domain['domain_transport'] ||
+ $res['domain_admin'] != $domain['domain_admin'] ||
+ $res['domain_max_users'] != $domain['domain_max_users'] ||
+ $res['domain_quota'] != $domain['domain_quota']) {
+ echo _("ERROR(4): got some wrong info.\n");
+ return;
+ }
+
+ $domain['domain_name'] = 'unfiltered.example.com';
+ $res = $unfiltered->saveDomain($domain);
+ if (is_a($res, 'PEAR_Error')) {
+ printf(_("ERROR(5): %s\n"), $res->getMessage());
+ return;
+ }
+
+ $res = $unfiltered->getDomainByName('unfiltered.example.com');
+ if (is_a($res, 'PEAR_Error')) {
+ printf(_("ERROR(6): %s\n"), $res->getMessage());
+ return;
+ }
+
+ if ($res['domain_name'] != 'unfiltered.example.com') {
+ echo _("ERROR(7): got wrong domain.\n");
+ return;
+ }
+ if ($res['domain_transport'] != $domain['domain_transport'] ||
+ $res['domain_admin'] != $domain['domain_admin'] ||
+ $res['domain_max_users'] != $domain['domain_max_users'] ||
+ $res['domain_quota'] != $domain['domain_quota']) {
+ echo _("ERROR(8): got some wrong info.\n");
+ return;
+ }
+
+ echo "ok\n";
+}
+
+function checkDeleteDomain()
+{
+ global $filtered, $unfiltered;
+
+ echo "Checking deleteDomain()... ";
+
+ $domain = $filtered->getDomainByName('filtered.example.com');
+ if (is_a($domain, 'PEAR_Error')) {
+ printf(_("ERROR(1): %s\n"), $domain->getMessage());
+ return;
+ }
+
+ $res = $filtered->deleteDomain($domain['domain_id']);
+ if (is_a($res, 'PEAR_Error')) {
+ printf(_("ERROR(2): %s\n"), $res->getMessage());
+ return;
+ }
+
+ $domain = $unfiltered->getDomainByName('unfiltered.example.com');
+ if (is_a($domain, 'PEAR_Error')) {
+ printf(_("ERROR(3): %s\n"), $domain->getMessage());
+ return;
+ }
+
+ $res = $unfiltered->deleteDomain($domain['domain_id']);
+ if (is_a($res, 'PEAR_Error')) {
+ printf(_("ERROR(4): %s\n"), $res->getMessage());
+ return;
+ }
+
+ echo "ok\n";
+}
+
+--EXPECT--
+Load... ok
+Checking construction... ok
+Checking saveDomain()... ok
+Checking deleteDomain()... ok
--- /dev/null
+<?php define('VILMA_VERSION', 'H4 (1.0-cvs)') ?>
--- /dev/null
+messages.po
--- /dev/null
+see horde/po/README
--- /dev/null
+# German translations for Vilma.
+# Copyright 2004-2009 The Horde Project
+# This file is distributed under the same license as the Vilma package.
+# Jan Schneider <jan@horde.org>, 2004-2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vilma 0.1-cvs\n"
+"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
+"POT-Creation-Date: 2008-04-01 14:58+0200\n"
+"PO-Revision-Date: 2008-04-01 15:15+0200\n"
+"Last-Translator: Jan Schneider <jan@horde.org>\n"
+"Language-Team: i18n@lists.horde.org\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: users/edit.php:53
+#, php-format
+msgid "\"%s\" already has the maximum number of users allowed."
+msgstr "\"%s\" hat bereits die maximale Benutzerzahl erreicht."
+
+#: lib/Driver/qmailldap.php:647
+msgid "Account Status"
+msgstr "Kontostatus"
+
+#: lib/Driver/qmailldap.php:655
+msgid "Account is active"
+msgstr "Konto ist aktiviert"
+
+#: lib/Driver/qmailldap.php:658
+msgid "Account is disabled"
+msgstr "Konto ist deaktiviert"
+
+#: templates/users/index.html:13
+msgid "Address"
+msgstr "Adresse"
+
+#: lib/Vilma.php:60
+msgid "Alias"
+msgstr "Spitzname"
+
+#: lib/Driver/qmailldap.php:332
+#, php-format
+msgid "Alias for %s"
+msgstr "Alias für %s"
+
+#: lib/Vilma.php:61
+msgid "Aliases"
+msgstr "Aliase"
+
+#: lib/Vilma.php:54 lib/Vilma.php:55
+msgid "All"
+msgstr "Alle"
+
+#: lib/Driver/qmailldap.php:657
+msgid "Bounce Incoming Only"
+msgstr "Nur Eingehendes abweisen"
+
+#: domains/delete.php:27 users/delete.php:34 users/delete.php:38
+#: virtuals/delete.php:34 virtuals/delete.php:38
+#: lib/Forms/DeleteDomainForm.php:27
+msgid "Delete"
+msgstr "Löschen"
+
+#: domains/index.php:44 lib/Forms/DeleteDomainForm.php:17
+msgid "Delete Domain"
+msgstr "Domain löschen"
+
+#: users/index.php:83 users/delete.php:31 virtuals/index.php:55
+msgid "Delete User"
+msgstr "Benutzer löschen"
+
+#: virtuals/delete.php:31
+msgid "Delete Virtual Email Address"
+msgstr "Virtuelle E-Mail-Adresse löschen"
+
+#: lib/Forms/DeleteDomainForm.php:29
+#, php-format
+msgid "Delete domain \"%s\" and all associated email addresses?"
+msgstr "Domain \"%s\" und alle dazugehörigen E-Mail-Adressen löschen?"
+
+#: virtuals/delete.php:36
+#, php-format
+msgid "Delete the virtual email address \"%s\" => \"%s\"?"
+msgstr "Virtuelle E-Mail-Adresse \"%s\" => \"%s\" löschen?"
+
+#: users/delete.php:36
+#, php-format
+msgid "Delete user \"%s\" and all associated virtual email addresses?"
+msgstr ""
+"Benutzer \"%s\" und alle dazugehörigen virtuellen E-Mail-Adressen löschen?"
+
+#: virtuals/edit.php:64 templates/virtuals/index.html:20
+msgid "Destination"
+msgstr "Ziel"
+
+#: virtuals/edit.php:54
+msgid "Destination type"
+msgstr "Zieltyp"
+
+#: lib/Driver/qmailldap.php:656
+msgid "Disable Delivery Only"
+msgstr "Nur Ausgehendes abweisen"
+
+#: config/prefs.php.dist:10
+msgid "Display details"
+msgstr "Anzeigedetails"
+
+#: config/prefs.php.dist:9
+msgid "Display listings"
+msgstr "Anzeigelisten"
+
+#: domains/delete.php:41 users/delete.php:34 users/delete.php:52
+#: virtuals/delete.php:34 virtuals/delete.php:52
+#: lib/Forms/DeleteDomainForm.php:27
+msgid "Do not delete"
+msgstr "Nicht löschen"
+
+#: lib/Forms/EditDomainForm.php:32 templates/domains/index.html:16
+msgid "Domain"
+msgstr "Domain"
+
+#: lib/Driver.php:229
+msgid ""
+"Domain added but an error was encountered while calling the configured "
+"hook. Contact your administrator for futher assistance."
+msgstr ""
+"Die Domain wurde hinzugefügt, aber beim Aufruf des konfigurierten Hooks ist "
+"ein Fehler aufgetreten. Bitte wenden Sie sich an Ihren Systemadministrator "
+"für weitere Hilfe."
+
+#: domains/delete.php:35
+msgid "Domain deleted."
+msgstr "Domain gelöscht."
+
+#: domains/delete.php:42
+msgid "Domain not deleted."
+msgstr "Domain nicht gelöscht."
+
+#: domains/edit.php:35
+msgid "Domain saved."
+msgstr "Domain gespeichert."
+
+#: domains/index.php:45 lib/Forms/EditDomainForm.php:20
+msgid "Edit Domain"
+msgstr "Domain bearbeiten"
+
+#: users/index.php:84 virtuals/index.php:56
+msgid "Edit User"
+msgstr "Benutzer bearbeiten"
+
+#: lib/Forms/EditUserForm.php:22
+#, php-format
+msgid "Edit User for \"%s\""
+msgstr "Benutzer von \"%s\" bearbeiten"
+
+#: virtuals/edit.php:47
+msgid "Edit Virtual Email Address"
+msgstr "Virtuelle E-Mail-Adresse bearbeiten"
+
+#: virtuals/edit.php:53
+#, php-format
+msgid ""
+"Enter a virtual email address @%s and then indicate below where mail sent to "
+"that address is to be delivered. The address must begin with an "
+"alphanumerical character, it must contain only alphanumerical and '._-' "
+"characters, and must end with an alphanumerical character."
+msgstr ""
+"Geben Sie eine virtuelle E-Mail-Adresse für die \"@%s\" Domain an und tragen "
+"Sie unten ein, wohin Nachrichten, die an diese Adresse geschickt werden, "
+"ausgeliefert werden sollen. E-Mail-Adressen müssen mit einem "
+"alphanumerischen Zeichen beginnen und enden und dürfen nur alphanumerische "
+"und die Zeichen \"._-\" enthalten."
+
+#: lib/Driver/qmailldap.php:593
+#, php-format
+msgid "Error deleting account from LDAP: %s"
+msgstr "Fehler beim Löschen des Kontos in LDAP: %s"
+
+#: domains/delete.php:33
+#, php-format
+msgid "Error deleting domain. %s."
+msgstr "Fehler beim Löschen der Domain. %s."
+
+#: users/delete.php:44
+#, php-format
+msgid "Error deleting user. %s."
+msgstr "Fehler beim Löschen des Benutzers. %s."
+
+#: virtuals/delete.php:44
+#, php-format
+msgid "Error deleting virtual email. %s."
+msgstr "Fehler beim Löschen der virtuellen E-Mail-Adresse. %s."
+
+#: lib/Driver/qmailldap.php:170 lib/Driver/qmailldap.php:175
+#, php-format
+msgid "Error in LDAP search: %s"
+msgstr "Fehler bei LDAP-Suche: %s"
+
+#: users/edit.php:35
+#, php-format
+msgid "Error reading address information from backend: %s"
+msgstr "Fehler beim Lesen der der Adressinformationen vom Backend: %s"
+
+#: lib/Driver/qmailldap.php:583
+#, php-format
+msgid "Error retrieving LDAP results: %s"
+msgstr "Fehler beim Lesen LDAP-Ergebnisse: %s"
+
+#: lib/Driver/qmailldap.php:308 lib/Driver/qmailldap.php:396
+#: lib/Driver/qmailldap.php:468
+#, php-format
+msgid "Error returning LDAP results: %s"
+msgstr "Fehler bei der Rückgabe der LDAP-Ergebnisse: %s"
+
+#: lib/Driver.php:195
+msgid "Error running authentication update script."
+msgstr "Fehler beim Ausführen des Update-Skripts."
+
+#: domains/edit.php:33
+#, php-format
+msgid "Error saving domain: %s."
+msgstr "Fehler beim Speichern der Domain: %s."
+
+#: users/edit.php:64
+#, php-format
+msgid "Error saving user. %s"
+msgstr "Fehler beim Speichern des Benutzers. %s"
+
+#: virtuals/edit.php:77
+#, php-format
+msgid "Error saving virtual email. %s."
+msgstr "Fehler beim Speichern der virtuellen E-Mail-Adresse. %s."
+
+#: lib/Driver/qmailldap.php:302 lib/Driver/qmailldap.php:390
+#: lib/Driver/qmailldap.php:462 lib/Driver/qmailldap.php:577
+#, php-format
+msgid "Error searching LDAP: %s"
+msgstr "Fehler bei der LDAP-Suche: %s"
+
+#: lib/Driver.php:280
+msgid "Error while calling hook to delete domain."
+msgstr "Fehler beim Aufruf des Hooks zum Löschen der Domain."
+
+#: lib/Forms/EditUserForm.php:41 templates/users/index.html:16
+msgid "Full Name"
+msgstr "Vollständiger Name"
+
+#: lib/Vilma.php:63
+msgid "Group/Forward"
+msgstr "Gruppe/Weiterleitung"
+
+#: lib/Vilma.php:64
+msgid "Groups and Forwards"
+msgstr "Gruppen und Weiterleitungen"
+
+#: config/prefs.php.dist:20
+msgid "How many domain to display per page."
+msgstr "Anzahl der Domains pro Seite."
+
+#: virtuals/edit.php:56
+msgid "Local user"
+msgstr "Lokaler Benutzer"
+
+#: lib/MailboxDriver/imap.php:45
+#, php-format
+msgid "Mailbox '%s@%s' does not exist."
+msgstr "Die Mailbox '%s@%s' existiert nicht."
+
+#: lib/MailboxDriver/maildrop.php:45
+#, php-format
+msgid "Maildrop directory \"%s\" does not exist."
+msgstr "Das Maildrop-Verzeichnis \"%s\" existiert nicht."
+
+#: templates/domains/index.html:19
+msgid "Max Users"
+msgstr "Maximale Benutzerzahl"
+
+#: lib/Forms/EditDomainForm.php:35
+msgid "Max users"
+msgstr "Maximale Benutzerzahl"
+
+#: users/index.php:70
+msgid "Maximum Users"
+msgstr "Maximale Benutzerzahl"
+
+#: lib/Driver/qmailldap.php:472
+msgid ""
+"More than one DN returned for this alias. Please contact an administrator "
+"to resolve this error."
+msgstr ""
+"Mehr als eine DN für diesen Alias gefunden. Bitte wenden Sie sich an einen "
+"Administrator, um diesen Fehler zu beheben."
+
+#: lib/Driver/qmailldap.php:587
+msgid "More than one DN returned. Aborting delete operation."
+msgstr "Mehr als eine DN zurückgeliefert. Löschvorgang abgebrochen."
+
+#: lib/Forms/EditUserForm.php:35
+msgid ""
+"Name must begin with an alphanumeric character, must contain only "
+"alphanumeric and '._-' characters, and must end with an alphanumeric "
+"character."
+msgstr ""
+"Der Name muss mit einem alphanumerischen Zeichen beginnen und enden und darf "
+"nur alphanumerische und die Zeichen \"._-\" enthalten."
+
+#: lib/Forms/EditDomainForm.php:20
+msgid "New Domain"
+msgstr "Neue Domain"
+
+#: lib/Forms/EditUserForm.php:24
+#, php-format
+msgid "New User @%s"
+msgstr "Neuer Benutzer für Domain @%s"
+
+#: virtuals/index.php:48
+msgid "New Virtual Email"
+msgstr "Neue virtuelle E-Mail-Adresse"
+
+#: virtuals/edit.php:47
+msgid "New Virtual Email Address"
+msgstr "Neue virtuelle E-Mail-Adresse"
+
+#: lib/Vilma.php:169
+msgid "New _Address"
+msgstr "Neue _Adresse"
+
+#: lib/MailboxDriver/maildrop.php:19
+msgid "No 'mail_dir_base' parameter specified to maildrop driver."
+msgstr ""
+"Kein 'mail_dir_base' Parameter in der Maildrop-Treiber-Konfiguration "
+"angegeben."
+
+#: lib/MailboxDriver/maildrop.php:60
+msgid "No 'system_user' parameter specified to maildrop driver."
+msgstr ""
+"Kein 'system_user' Parameter in der Maildrop-Treiber-Konfiguration angegeben."
+"<"
+
+#: lib/Driver.php:108
+#, php-format
+msgid "No such address %s of type %s found."
+msgstr "Adresse %s vom Typ %s nicht gefunden."
+
+#: lib/Driver.php:374
+#, php-format
+msgid "No such backend \"%s\" found"
+msgstr "Ein Backend namens \"%s\" konnte nicht gefunden werden"
+
+#: users/edit.php:74
+msgid ""
+"No virtual email address set up for this user. You should set up at least "
+"one virtual email address if this user is to receive any emails."
+msgstr ""
+"Für diesen Benutzer wurden keine virtuellen E-Mail-Adressen eingerichtet. "
+"Sie sollten mindestens eine E-Mail-Adresse einrichten, wenn dieser Benutzer "
+"E-Mails empfangen können soll."
+
+#: lib/Driver.php:245 lib/Driver.php:294
+msgid "Not implemented."
+msgstr "Nicht implementiert."
+
+#: lib/Forms/EditUserForm.php:37
+msgid "Only enter a password if you wish to change this user's password"
+msgstr ""
+"Geben Sie nur ein Passwort ein, wenn Sie das Passwort dieses Benutzers "
+"ändern möchten"
+
+#: lib/Forms/EditUserForm.php:37 lib/Forms/EditUserForm.php:39
+msgid "Password"
+msgstr "Passwort"
+
+#: lib/Driver/sql.php:465
+msgid "Password must be supplied when creating a new user."
+msgstr "Passwort muss beim Erstellen eines neuen Benutzers angegeben werden."
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Quota"
+msgstr "Speicherplatz-Kontingent"
+
+#: virtuals/edit.php:57
+msgid "Remote address"
+msgstr "Externe Adresse"
+
+#: virtuals/edit.php:61
+msgid "Remote e-mail address"
+msgstr "Externe E-Mail-Adresse"
+
+#: config/prefs.php.dist:11
+msgid "Set default display parameters."
+msgstr "Legen Sie Ihre Standard-Anzeigeeinstellungen fest."
+
+#: templates/users/index.html:22
+msgid "Status"
+msgstr "Status"
+
+#: lib/api.php:43
+msgid "Super Administrator"
+msgstr "Super-Administrator"
+
+#: lib/MailboxDriver.php:78
+msgid "This driver cannot create mailboxes."
+msgstr "Dieses Treiber kann keine Mailboxen anlegen."
+
+#: lib/MailboxDriver.php:94
+msgid "This driver cannot delete mailboxes."
+msgstr "Dieser Treiber kann keine Mailboxen löschen."
+
+#: lib/Forms/EditDomainForm.php:34
+msgid "Transport"
+msgstr "Transport"
+
+#: templates/users/index.html:19
+msgid "Type"
+msgstr "Typ"
+
+#: lib/Driver/qmailldap.php:696
+msgid "Unable to bind to the LDAP server. Check authentication credentials."
+msgstr ""
+"Anbindung an LDAP-Server fehlgeschlagen. Überprüfen Sie die "
+"Authentifizierungsdaten."
+
+#: lib/Driver/qmailldap.php:691
+msgid "Unable to set LDAP protocol version"
+msgstr "Die LDAP-Protokollversion konnte nicht gesetzt werden"
+
+#: lib/Driver.php:199
+msgid "Unknown error running authentication update script."
+msgstr "Unbekannter Fehler beim Ausführen des Update-Skripts."
+
+#: lib/Vilma.php:57
+msgid "User"
+msgstr "Benutzer"
+
+#: lib/Forms/EditUserForm.php:35
+msgid "User Name"
+msgstr "Benutzername"
+
+#: users/delete.php:46
+msgid "User deleted."
+msgstr "Benutzer gelöscht."
+
+#: users/edit.php:66
+msgid "User details saved."
+msgstr "Benutzerdetails gespeichert."
+
+#: lib/Driver.php:132
+msgid "User disabled."
+msgstr "Benutzer deaktiviert."
+
+#: users/delete.php:53
+msgid "User not deleted."
+msgstr "Benutzer wurde nicht gelöscht."
+
+#: lib/Driver.php:155
+msgid "User ready."
+msgstr "Benutzer bereit."
+
+#: virtuals/index.php:51 lib/Vilma.php:58
+msgid "Users"
+msgstr "Benutzer"
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Value in MB"
+msgstr "Wert in MB"
+
+#: lib/Driver.php:210
+msgid "Vilma_Driver::deleteUser(): Method Not Implemented."
+msgstr "Vilma_Driver::deleteUser(): Methode nicht implementiert."
+
+#: virtuals/edit.php:53
+msgid "Virtual Email"
+msgstr "Virtuelle E-Mail-Adresse"
+
+#: templates/virtuals/index.html:17
+msgid "Virtual Email Address"
+msgstr "Virtuelle E-Mail-Adresse"
+
+#: virtuals/delete.php:46
+msgid "Virtual email deleted."
+msgstr "Virtuelle E-Mail-Adresse gelöscht."
+
+#: virtuals/delete.php:53
+msgid "Virtual email not deleted."
+msgstr "Virtuelle E-Mail-Adresse nicht gelöscht."
+
+#: virtuals/edit.php:79
+msgid "Virtual email saved."
+msgstr "Virtuelle E-Mail-Adresse gespeichert."
+
+#: lib/Vilma.php:166
+msgid "_Domains"
+msgstr "_Domains"
+
+#: lib/Vilma.php:171
+msgid "_New Domain"
+msgstr "_Neue Domain"
--- /dev/null
+# Spanish translations for vilma package
+# Traducciones al español para el paquete vilma.
+# Copyright 2008-2009 The Horde Project
+# This file is distributed under the same license as the vilma package.
+# Automatically generated, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vilma 0.2-cvs\n"
+"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
+"POT-Creation-Date: 2008-03-20 09:49+0100\n"
+"PO-Revision-Date: 2008-03-20 09:49+0100\n"
+"Last-Translator: Manuel P. Ayala <mayala@unex.es>\n"
+"Language-Team: i18n@lists.horde.org\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: users/edit.php:53
+#, php-format
+msgid "\"%s\" already has the maximum number of users allowed."
+msgstr "\"%s\" ha alcanzado ya el número máximo de usuarios permitidos."
+
+#: lib/Driver/qmailldap.php:647
+msgid "Account Status"
+msgstr "Estado de la cuenta"
+
+#: lib/Driver/qmailldap.php:655
+msgid "Account is active"
+msgstr "La cuenta está activa"
+
+#: lib/Driver/qmailldap.php:658
+msgid "Account is disabled"
+msgstr "La cuenta está deshabilitada"
+
+#: templates/users/index.html:13
+msgid "Address"
+msgstr "Dirección"
+
+#: lib/Vilma.php:60
+msgid "Alias"
+msgstr "Apodo"
+
+#: lib/Driver/qmailldap.php:332
+#, php-format
+msgid "Alias for %s"
+msgstr "Apodo de %s"
+
+#: lib/Vilma.php:61
+msgid "Aliases"
+msgstr "Apodos"
+
+#: lib/Vilma.php:54 lib/Vilma.php:55
+msgid "All"
+msgstr "Todos"
+
+#: lib/Driver/qmailldap.php:657
+msgid "Bounce Incoming Only"
+msgstr "Rebotar sólo entrantes"
+
+#: virtuals/delete.php:34 virtuals/delete.php:38 users/delete.php:34
+#: users/delete.php:38 domains/delete.php:27 lib/Forms/DeleteDomainForm.php:27
+msgid "Delete"
+msgstr "Eliminar"
+
+#: domains/index.php:44 lib/Forms/DeleteDomainForm.php:17
+msgid "Delete Domain"
+msgstr "Eliminar dominio"
+
+#: virtuals/index.php:55 users/index.php:83 users/delete.php:31
+msgid "Delete User"
+msgstr "Eliminar usuario"
+
+#: virtuals/delete.php:31
+msgid "Delete Virtual Email Address"
+msgstr "Eliminar dirección electrónica virtual"
+
+#: lib/Forms/DeleteDomainForm.php:29
+#, php-format
+msgid "Delete domain \"%s\" and all associated email addresses?"
+msgstr ""
+"¿Eliminar el dominio \"%s\" y todas las direcciones electrónicas asociadas?"
+
+#: virtuals/delete.php:36
+#, php-format
+msgid "Delete the virtual email address \"%s\" => \"%s\"?"
+msgstr "¿Eliminar la dirección electrónica virtual \"%s\" => \"%s\"?"
+
+#: users/delete.php:36
+#, php-format
+msgid "Delete user \"%s\" and all associated virtual email addresses?"
+msgstr ""
+"¿Eliminar el usuario \"%s\" y todas sus direcciones electrónicas virtuales "
+"asociadas?"
+
+#: virtuals/edit.php:64 templates/virtuals/index.html:20
+msgid "Destination"
+msgstr "Destinatario"
+
+#: virtuals/edit.php:54
+msgid "Destination type"
+msgstr "Tipo de destinatario"
+
+#: lib/Driver/qmailldap.php:656
+msgid "Disable Delivery Only"
+msgstr "Desactivar sólo la distribución"
+
+#: config/.bak/prefs.php.dist:10
+msgid "Display details"
+msgstr "Mostrar detalles"
+
+#: config/.bak/prefs.php.dist:9
+msgid "Display listings"
+msgstr "Mostrar listados"
+
+#: virtuals/delete.php:34 virtuals/delete.php:52 users/delete.php:34
+#: users/delete.php:52 domains/delete.php:41 lib/Forms/DeleteDomainForm.php:27
+msgid "Do not delete"
+msgstr "No eliminar"
+
+#: lib/Forms/EditDomainForm.php:32 templates/domains/index.html:16
+msgid "Domain"
+msgstr "Dominio"
+
+#: lib/Driver.php:229
+msgid ""
+"Domain added but an error was encountered while calling the configured "
+"hook. Contact your administrator for futher assistance."
+msgstr ""
+"Se añadió el dominio pero se produjo un error al llamar al gancho "
+"configurado. Para más información póngase en contacto con el administrador."
+
+#: domains/delete.php:35
+msgid "Domain deleted."
+msgstr "Se ha eliminado el dominio."
+
+#: domains/delete.php:42
+msgid "Domain not deleted."
+msgstr "No se ha eliminado el dominio."
+
+#: domains/edit.php:35
+msgid "Domain saved."
+msgstr "Se ha guardado el dominio."
+
+#: domains/index.php:45 lib/Forms/EditDomainForm.php:20
+msgid "Edit Domain"
+msgstr "Modificar dominio"
+
+#: virtuals/index.php:56 users/index.php:84
+msgid "Edit User"
+msgstr "Modificar usuario"
+
+#: lib/Forms/EditUserForm.php:22
+#, php-format
+msgid "Edit User for \"%s\""
+msgstr "Modificar usuario de \"%s\""
+
+#: virtuals/edit.php:47
+msgid "Edit Virtual Email Address"
+msgstr "Modificar dirección electrónica virtual"
+
+#: virtuals/edit.php:53
+#, php-format
+msgid ""
+"Enter a virtual email address @%s and then indicate below where mail sent to "
+"that address is to be delivered. The address must begin with an "
+"alphanumerical character, it must contain only alphanumerical and '._-' "
+"characters, and must end with an alphanumerical character."
+msgstr ""
+"Introduzca una dirección de correo virtual @%s e indique a continuación a "
+"dónde enviar el correo de esa dirección. Las direcciones tienen que empezar "
+"por un carácter alfanumérico, sólo pueden contener caracteres alfanuméricos "
+"y '._-' , y tienen que acabar por un carácter alfanumérico."
+
+#: lib/Driver/qmailldap.php:593
+#, php-format
+msgid "Error deleting account from LDAP: %s"
+msgstr "Error al eliminar la cuenta de LDAP: %s"
+
+#: domains/delete.php:33
+#, php-format
+msgid "Error deleting domain. %s."
+msgstr "Error al eliminar el dominio. %s."
+
+#: users/delete.php:44
+#, php-format
+msgid "Error deleting user. %s."
+msgstr "Error al eliminar el usuario. %s."
+
+#: virtuals/delete.php:44
+#, php-format
+msgid "Error deleting virtual email. %s."
+msgstr "Error al eliminar la dirección de correo virtual. %s."
+
+#: lib/Driver/qmailldap.php:170 lib/Driver/qmailldap.php:175
+#, php-format
+msgid "Error in LDAP search: %s"
+msgstr "Error en la búsqueda LDAP: %s"
+
+#: users/edit.php:35
+#, php-format
+msgid "Error reading address information from backend: %s"
+msgstr "Error leyendo la información de la dirección desde el motor: %s"
+
+#: lib/Driver/qmailldap.php:583
+#, php-format
+msgid "Error retrieving LDAP results: %s"
+msgstr "Error recuperando los resultados LDAP: %s"
+
+#: lib/Driver/qmailldap.php:308 lib/Driver/qmailldap.php:396
+#: lib/Driver/qmailldap.php:468
+#, php-format
+msgid "Error returning LDAP results: %s"
+msgstr "Error en la devolución de los resultados LDAP: %s"
+
+#: lib/Driver.php:195
+msgid "Error running authentication update script."
+msgstr "Error al ejecutar el guión de actualización de autentificación."
+
+#: domains/edit.php:33
+#, php-format
+msgid "Error saving domain: %s."
+msgstr "Error al guardar el dominio: %s."
+
+#: users/edit.php:64
+#, php-format
+msgid "Error saving user. %s"
+msgstr "Error al guardar el usuario. %s"
+
+#: virtuals/edit.php:77
+#, php-format
+msgid "Error saving virtual email. %s."
+msgstr "Error al guardar la dirección electrónica virtual. %s."
+
+#: lib/Driver/qmailldap.php:302 lib/Driver/qmailldap.php:390
+#: lib/Driver/qmailldap.php:462 lib/Driver/qmailldap.php:577
+#, php-format
+msgid "Error searching LDAP: %s"
+msgstr "Error buscando en LDAP: %s"
+
+#: lib/Driver.php:280
+msgid "Error while calling hook to delete domain."
+msgstr "Error al llamar al gancho de eliminación del dominio."
+
+#: lib/Forms/EditUserForm.php:41 templates/users/index.html:16
+msgid "Full Name"
+msgstr "Nombre completo"
+
+#: lib/Vilma.php:63
+msgid "Group/Forward"
+msgstr "Grupo/Reenvío"
+
+#: lib/Vilma.php:64
+msgid "Groups and Forwards"
+msgstr "Grupos y reenvíos"
+
+#: config/.bak/prefs.php.dist:20
+msgid "How many domain to display per page."
+msgstr "Cuántos dominios mostrar por página."
+
+#: virtuals/edit.php:56
+msgid "Local user"
+msgstr "Usuario local"
+
+#: lib/MailboxDriver/imap.php:45
+#, php-format
+msgid "Mailbox '%s@%s' does not exist."
+msgstr "No existe el buzón '%s@%s'."
+
+#: lib/MailboxDriver/maildrop.php:45
+#, php-format
+msgid "Maildrop directory \"%s\" does not exist."
+msgstr "No existe el directorio maildrop \"%s\"."
+
+#: templates/domains/index.html:19
+msgid "Max Users"
+msgstr "Número máximo de usuarios"
+
+#: lib/Forms/EditDomainForm.php:35
+msgid "Max users"
+msgstr "Número máximo de usuarios"
+
+#: users/index.php:70
+msgid "Maximum Users"
+msgstr "Número máximo de usuarios"
+
+#: lib/Driver/qmailldap.php:472
+msgid ""
+"More than one DN returned for this alias. Please contact an administrator "
+"to resolve this error."
+msgstr ""
+"Este apodo devolvió más de un DN. Póngase en contacto con el administrador "
+"para resolver este error."
+
+#: lib/Driver/qmailldap.php:587
+msgid "More than one DN returned. Aborting delete operation."
+msgstr "Se ha devuelto más de un DN. Anulando la operación de eliminación."
+
+#: lib/Forms/EditUserForm.php:35
+msgid ""
+"Name must begin with an alphanumeric character, must contain only "
+"alphanumeric and '._-' characters, and must end with an alphanumeric "
+"character."
+msgstr ""
+"El nombre tiene que empezar por un carácter alfanumérico, tiene que contener "
+"sólo caracteres alfanuméricos o '._-' y tiene que terminar por un carácter "
+"alfanumérico."
+
+#: lib/Forms/EditDomainForm.php:20
+msgid "New Domain"
+msgstr "Añadir dominio"
+
+#: lib/Forms/EditUserForm.php:24
+#, php-format
+msgid "New User @%s"
+msgstr "Añadir usuario @%s"
+
+#: virtuals/index.php:48
+msgid "New Virtual Email"
+msgstr "Añadir correo virtual"
+
+#: virtuals/edit.php:47
+msgid "New Virtual Email Address"
+msgstr "Añadir dirección de correo virtual"
+
+#: lib/Vilma.php:169
+msgid "New _Address"
+msgstr "Añadir _dirección"
+
+#: lib/MailboxDriver/maildrop.php:19
+msgid "No 'mail_dir_base' parameter specified to maildrop driver."
+msgstr ""
+"No se ha especificado el parámetro 'mail_dir_base' en el controlador de "
+"descarga de correo."
+
+#: lib/MailboxDriver/maildrop.php:60
+msgid "No 'system_user' parameter specified to maildrop driver."
+msgstr ""
+"No se ha especificado el parámetro 'system_user' en el controlador de "
+"descarga de correo."
+
+#: lib/Driver.php:108
+#, php-format
+msgid "No such address %s of type %s found."
+msgstr "No se encontró una dirección %s de tipo %s."
+
+#: lib/Driver.php:374
+#, php-format
+msgid "No such backend \"%s\" found"
+msgstr "No se encontró el motor \"%s\""
+
+#: users/edit.php:74
+msgid ""
+"No virtual email address set up for this user. You should set up at least "
+"one virtual email address if this user is to receive any emails."
+msgstr ""
+"A este usuario no se le ha configurado una dirección de correo vitual. Tiene "
+"que configurar al menos una si este usuario va a recibir correo."
+
+#: lib/Driver.php:245 lib/Driver.php:294
+msgid "Not implemented."
+msgstr "Sin desarrollar."
+
+#: lib/Forms/EditUserForm.php:37
+msgid "Only enter a password if you wish to change this user's password"
+msgstr ""
+"Introduzca un a contraseña sólo si desea cambiar la contraseña de este "
+"usuario"
+
+#: lib/Forms/EditUserForm.php:37 lib/Forms/EditUserForm.php:39
+msgid "Password"
+msgstr "Contraseña"
+
+#: lib/Driver/sql.php:465
+msgid "Password must be supplied when creating a new user."
+msgstr "Al crear un usuario hay que introducir una contraseña."
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Quota"
+msgstr "Espacio asignado"
+
+#: virtuals/edit.php:57
+msgid "Remote address"
+msgstr "Dirección remota"
+
+#: virtuals/edit.php:61
+msgid "Remote e-mail address"
+msgstr "Dirección electrónica remota"
+
+#: config/.bak/prefs.php.dist:11
+msgid "Set default display parameters."
+msgstr "Define parámetros de visualización por omisión."
+
+#: templates/users/index.html:22
+msgid "Status"
+msgstr "Estado"
+
+#: lib/api.php:43
+msgid "Super Administrator"
+msgstr "Super administrador"
+
+#: lib/MailboxDriver.php:78
+msgid "This driver cannot create mailboxes."
+msgstr "Este controlador no puede crear buzones."
+
+#: lib/MailboxDriver.php:94
+msgid "This driver cannot delete mailboxes."
+msgstr "Este controlador no puede eliminar buzones."
+
+#: lib/Forms/EditDomainForm.php:34
+msgid "Transport"
+msgstr "Transporte"
+
+#: templates/users/index.html:19
+msgid "Type"
+msgstr "Tipo"
+
+#: lib/Driver/qmailldap.php:696
+msgid "Unable to bind to the LDAP server. Check authentication credentials."
+msgstr ""
+"No se pudo vincular al servidor LDAP. Compruebe las credenciales de "
+"autentificación."
+
+#: lib/Driver/qmailldap.php:691
+msgid "Unable to set LDAP protocol version"
+msgstr "No se puede establecer la versión del protocolo LDAP"
+
+#: lib/Driver.php:199
+msgid "Unknown error running authentication update script."
+msgstr ""
+"Se ha producido un error desconocido al ejecutar el guión de actualización "
+"de autentificación."
+
+#: lib/Vilma.php:57
+msgid "User"
+msgstr "Usuario"
+
+#: lib/Forms/EditUserForm.php:35
+msgid "User Name"
+msgstr "Nombre del usuario"
+
+#: users/delete.php:46
+msgid "User deleted."
+msgstr "Se ha eliminado el usuario."
+
+#: users/edit.php:66
+msgid "User details saved."
+msgstr "Se han guardado los detalles del usuario."
+
+#: lib/Driver.php:132
+msgid "User disabled."
+msgstr "Usuario deshabilitado."
+
+#: users/delete.php:53
+msgid "User not deleted."
+msgstr "No se ha eliminado el usuario"
+
+#: lib/Driver.php:155
+msgid "User ready."
+msgstr "El usuario está listo."
+
+#: virtuals/index.php:51 lib/Vilma.php:58
+msgid "Users"
+msgstr "Usuarios"
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Value in MB"
+msgstr "Valor en MB"
+
+#: lib/Driver.php:210
+msgid "Vilma_Driver::deleteUser(): Method Not Implemented."
+msgstr "Vilma_Driver::deleteUser(): Método no desarrollado."
+
+#: virtuals/edit.php:53
+msgid "Virtual Email"
+msgstr "Correo virtual"
+
+#: templates/virtuals/index.html:17
+msgid "Virtual Email Address"
+msgstr "Dirección de correo virtual"
+
+#: virtuals/delete.php:46
+msgid "Virtual email deleted."
+msgstr "Dirección virtual eliminada."
+
+#: virtuals/delete.php:53
+msgid "Virtual email not deleted."
+msgstr "No se ha eliminado la dirección virtual."
+
+#: virtuals/edit.php:79
+msgid "Virtual email saved."
+msgstr "Se ha guardado la dirección virtual."
+
+#: lib/Vilma.php:166
+msgid "_Domains"
+msgstr "_Dominios"
+
+#: lib/Vilma.php:171
+msgid "_New Domain"
+msgstr "_Añadir dominio"
--- /dev/null
+# Italian translations for Mailadmin package.
+# Copyright 2003-2009 The Horde Project
+# This file is distributed under the same license as the Mailadmin package.
+# Automatically generated, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Mailadmin 0.1-cvs\n"
+"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
+"POT-Creation-Date: 2004-08-30 14:11+0200\n"
+"PO-Revision-Date: 2004-02-11 18:15-0100\n"
+"Last-Translator: Marko Djukic <marko@oblo.com>\n"
+"Language-Team: Italian <tech@oblo.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: users/edit.php:47
+#, php-format
+msgid "'%s' already has the maximum number of users allowed."
+msgstr "'%s' gia' ha il numero massimo di utenti permessi."
+
+#: templates/domains/index.html:35
+msgid "Admin"
+msgstr "Admin"
+
+#: users/index.php:53
+msgid "All Virtual Emails"
+msgstr "Tutti gli Indirizzi Email Virtuali"
+
+#: virtuals/delete.php:37 virtuals/delete.php:41 users/delete.php:33
+#: users/delete.php:37 domains/delete.php:28 domains/delete.php:32
+msgid "Delete"
+msgstr "Elimina"
+
+#: domains/delete.php:25 domains/index.php:48
+msgid "Delete Domain"
+msgstr "Elimina Dominio"
+
+#: virtuals/index.php:52 users/delete.php:30 users/index.php:63
+msgid "Delete User"
+msgstr "Elimina Utente"
+
+#: virtuals/delete.php:34
+msgid "Delete Virtual Email Address"
+msgstr "Elimina Indirizzo Email Virtuale"
+
+#: domains/delete.php:30
+#, php-format
+msgid "Delete domain '%s', all the users and virtual email addresses?"
+msgstr "Elimina dominio '%s', tutti gli utenti e gli indirizzi email virtuali?"
+
+#: virtuals/delete.php:39
+#, php-format
+msgid "Delete the virtual email address '%s' => '%s'?"
+msgstr "Elimina l'indirizzo email virtuale '%s' => '%s'?"
+
+#: users/delete.php:35
+#, php-format
+msgid "Delete user '%s' and all associated virtual email addresses?"
+msgstr "Elimina l'utente '%s' e tutti i relativi indirizzi email virtuali?"
+
+#: templates/virtuals/index.html:37
+msgid "Destination"
+msgstr "Destinazione"
+
+#: virtuals/edit.php:55
+msgid "Destination user"
+msgstr "Utente di destinazione"
+
+#: virtuals/delete.php:37 virtuals/delete.php:55 users/delete.php:33
+#: users/delete.php:51 domains/delete.php:28 domains/delete.php:46
+msgid "Do not delete"
+msgstr "Non eliminare"
+
+#: domains/edit.php:40 templates/domains/index.html:33
+msgid "Domain"
+msgstr "Dominio"
+
+#: domains/edit.php:43
+msgid "Domain admin"
+msgstr "Amministratore dominio"
+
+#: domains/delete.php:40
+msgid "Domain deleted."
+msgstr "Dominio eliminato."
+
+#: domains/delete.php:47
+msgid "Domain not deleted."
+msgstr "Dominio non eliminato."
+
+#: domains/edit.php:54
+msgid "Domain saved."
+msgstr "Dominio salvato."
+
+#: domains/edit.php:34 domains/index.php:49
+msgid "Edit Domain"
+msgstr "Modifica Dominio"
+
+#: virtuals/index.php:53 users/index.php:64
+msgid "Edit User"
+msgstr "Modifica Utente"
+
+#: users/edit.php:52
+#, php-format
+msgid "Edit User for '%s'"
+msgstr "Modifica Utente per '%s'"
+
+#: virtuals/edit.php:48
+msgid "Edit Virtual Email Address"
+msgstr "Modifica Indirizzo Email Virtuale"
+
+#: virtuals/edit.php:54 templates/virtuals/index.html:35
+msgid "Email"
+msgstr "Email"
+
+#: users/edit.php:66
+msgid "Enabled?"
+msgstr "Attivato?"
+
+#: virtuals/edit.php:54
+#, php-format
+msgid ""
+"Enter a virtual email address for the '@%s' domain. Address must begin with "
+"an alphanumerical character, it must contain only alphanumerical and '._-' "
+"characters, and must end with an alphanumerical character."
+msgstr ""
+"Inserisci un indirizzo email virtuale per il '@%s' dominio. L'indirizzo deve "
+"iniziare con un carattere alfanumerico, deve avere solo caratteri "
+"alfanumerici e '._-' caratteri, e deve finire con un carattere alfanumerico."
+
+#: domains/delete.php:38
+#, php-format
+msgid "Error deleting domain. %s."
+msgstr "Errore durante l'eliminazione del dominio. %s."
+
+#: users/delete.php:43
+#, php-format
+msgid "Error deleting user. %s."
+msgstr "Errore durante l'eliminazione dell'utente. %s."
+
+#: virtuals/delete.php:47
+#, php-format
+msgid "Error deleting virtual email. %s."
+msgstr "Errore durante l'eliminazione del indirizzo email virtuale. %s."
+
+#: lib/Driver.php:254 lib/Driver.php:288
+msgid "Error running authentication update script."
+msgstr ""
+
+#: domains/edit.php:52
+#, php-format
+msgid "Error saving domain. %s."
+msgstr "Errore durante il salvataggio del dominio. %s."
+
+#: users/edit.php:76
+#, fuzzy, php-format
+msgid "Error saving user. %s"
+msgstr "Errore durante il salvataggio dell'utente. %s."
+
+#: virtuals/edit.php:62
+#, php-format
+msgid "Error saving virtual email. %s."
+msgstr "Errore durante il salvataggio indirizzo email virtuale. %s."
+
+#: templates/users/index.html:39
+msgid "Full Name"
+msgstr "Nome Completo"
+
+#: lib/MailboxDriver/imap.php:42
+#, fuzzy, php-format
+msgid "Mailbox '%s@%s' does not exist."
+msgstr "Messaggio inesistente."
+
+#: lib/MailboxDriver/maildrop.php:49
+#, fuzzy, php-format
+msgid "Maildrop directory '%s' does not exist."
+msgstr "Cartella VFS non esiste."
+
+#: templates/domains/index.html:37
+#, fuzzy
+msgid "Max Users"
+msgstr "Utenti max"
+
+#: domains/edit.php:44
+msgid "Max users"
+msgstr "Utenti max"
+
+#: users/index.php:46
+msgid "Maximum Users"
+msgstr "Utenti massimi"
+
+#: users/edit.php:65
+msgid "Name"
+msgstr "Nome"
+
+#: users/edit.php:59
+msgid ""
+"Name must begin with an alphanumerical character, it must contain only "
+"alphanumerical and '._-' characters, and must end with an alphanumerical "
+"character."
+msgstr ""
+"Il nome deve iniziare con un carattere alfanumerico, deve avere solo "
+"caratteri alfanumerici e '._-' caratteri, e deve finire con un carattere "
+"alfanumerico."
+
+#: domains/edit.php:34 domains/index.php:44
+msgid "New Domain"
+msgstr "Nuovo Dominio"
+
+#: users/index.php:43
+msgid "New User"
+msgstr "Nuovo Utente"
+
+#: users/edit.php:52
+#, php-format
+msgid "New User for '%s'"
+msgstr "Nuovo Utente per '%s'"
+
+#: virtuals/index.php:45 users/index.php:50
+msgid "New Virtual Email"
+msgstr "Dettagli Email Virtuale"
+
+#: virtuals/edit.php:48
+msgid "New Virtual Email Address"
+msgstr "Nuovo Indirizzo Email Virtuale"
+
+#: lib/MailboxDriver/maildrop.php:20
+msgid "No 'mail_dir_base' parameter specified to maildrop driver."
+msgstr ""
+
+#: lib/MailboxDriver/maildrop.php:64
+msgid "No 'system_user' parameter specified to maildrop driver."
+msgstr ""
+
+#: lib/Driver.php:172
+#, php-format
+msgid "No such backend '%s' found"
+msgstr "Nessun backend '%s' trovato"
+
+#: users/edit.php:86
+msgid ""
+"No virtual email address set up for this user. You should set up at least "
+"one virtual email address if this user is to receive any emails."
+msgstr ""
+"Nessun indirizzo email virtuale impostato per questo utente. Dovresti "
+"impostare al meno un indirizzo email virtuale se questo utente e' da "
+"ricevere gli email."
+
+#: lib/Driver.php:114
+msgid "No virtual emails set."
+msgstr "Nessun indirizzo email virtuale inserito."
+
+#: users/edit.php:61
+msgid "Only enter a password if you wish to change this user's password"
+msgstr ""
+"Inserisci una password solo nel caso in cui vuoi cambiare la password di "
+"questo utente."
+
+#: users/edit.php:61 users/edit.php:63
+msgid "Password"
+msgstr "Password"
+
+#: lib/Driver/sql.php:337
+msgid "Password must be supplied when creating a new user."
+msgstr ""
+
+#: domains/edit.php:45 templates/users/index.html:41
+msgid "Quota"
+msgstr "Quota"
+
+#: templates/index/notconfigured.inc:39
+#, fuzzy
+msgid "Some of Vilma's configuration files are missing:"
+msgstr "Mancano alcuni file di configurazione di Nag:"
+
+#: templates/users/index.html:43
+msgid "Status"
+msgstr "Statis"
+
+#: lib/MailboxDriver.php:77
+msgid "This driver cannot create mailboxes."
+msgstr ""
+
+#: lib/MailboxDriver.php:93
+#, fuzzy
+msgid "This driver cannot delete mailboxes."
+msgstr "Non era possibile eliminare il file:"
+
+#: templates/index/notconfigured.inc:44
+#, fuzzy
+msgid ""
+"This is the main Vilma configuration file. It contains options for all Vilma "
+"scripts."
+msgstr ""
+"Questo è il file principale di configurazione di Nag. Contiene le opzioni "
+"per tutti gli scripts di Nag."
+
+#: domains/edit.php:42
+msgid "Transport"
+msgstr "Trasporto"
+
+#: lib/Driver.php:258 lib/Driver.php:292
+msgid "Unknown error running authentication update script."
+msgstr ""
+
+#: users/edit.php:59
+msgid "User"
+msgstr "Utente"
+
+#: templates/users/index.html:37
+#, fuzzy
+msgid "User Name"
+msgstr "Nome Utente"
+
+#: users/delete.php:45
+msgid "User deleted."
+msgstr "Utente eliminato."
+
+#: users/edit.php:78
+msgid "User details saved."
+msgstr "Dettagli utente salvati."
+
+#: lib/Driver.php:107
+msgid "User disabled."
+msgstr "Utente disattivato."
+
+#: users/edit.php:67
+msgid "User is disabled"
+msgstr "L'utente e' disattivato."
+
+#: users/edit.php:66
+msgid "User is enabled"
+msgstr "L'utente e' attivato."
+
+#: users/delete.php:52
+msgid "User not deleted."
+msgstr "Utente non eliminato."
+
+#: lib/Driver.php:137
+msgid "User ready."
+msgstr "Utente pronto."
+
+#: virtuals/index.php:48
+msgid "Users"
+msgstr "Utenti"
+
+#: domains/edit.php:45
+msgid "Value in MB"
+msgstr "Valore in MB"
+
+#: templates/index/notconfigured.inc:4
+#, fuzzy
+msgid "Vilma is not properly configured"
+msgstr "Nag non è configurato correttamente."
+
+#: virtuals/delete.php:49
+msgid "Virtual email deleted."
+msgstr "Indirizzo email virtuale eliminato."
+
+#: virtuals/delete.php:56
+msgid "Virtual email not deleted."
+msgstr "Indirizzo email virtuale non eliminato."
+
+#: virtuals/edit.php:64
+msgid "Virtual email saved."
+msgstr "Indirizzo email virtuale salvato."
--- /dev/null
+# Lithuanian translations for Vilma package.
+# Copyright 2007-2009 The Horde Project
+# This file is distributed under the same license as the Vilma package.
+# Vilius Sumskas <vilius@lnk.lt>, 2004, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vilma 0.2-cvs\n"
+"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
+"POT-Creation-Date: 2007-11-02 15:40+0200\n"
+"PO-Revision-Date: 2007-11-11 20:02+0200\n"
+"Last-Translator: Vilius Sumskas <vilius@lnk.lt>\n"
+"Language-Team: Lithuanian <vilius@lnk.lt>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-13\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%"
+"100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: users/edit.php:53
+#, php-format
+msgid "\"%s\" already has the maximum number of users allowed."
+msgstr "\"%s\" jau pasiekë maksimalø vartotojø skaièiø."
+
+#: lib/Driver/qmailldap.php:670
+msgid "Account Status"
+msgstr "Paðto dëþutës bûsena"
+
+#: lib/Driver/qmailldap.php:678
+msgid "Account is active"
+msgstr "Paðto dëþutë ájungta"
+
+#: lib/Driver/qmailldap.php:681
+msgid "Account is disabled"
+msgstr "Paðto dëþutë iðjungta"
+
+#: templates/users/index.html:13
+msgid "Address"
+msgstr "Adresas"
+
+#: lib/Vilma.php:60
+msgid "Alias"
+msgstr "Pravardë"
+
+#: lib/Driver/qmailldap.php:371
+#, php-format
+msgid "Alias for %s"
+msgstr "Su %s susieti adresai"
+
+#: lib/Vilma.php:61
+msgid "Aliases"
+msgstr "Susieti adresai"
+
+#: lib/Vilma.php:54 lib/Vilma.php:55
+msgid "All"
+msgstr "Viskà"
+
+#: lib/Driver/qmailldap.php:680
+msgid "Bounce Incoming Only"
+msgstr "Tik persiøsti gaunamus"
+
+#: domains/delete.php:29 domains/delete.php:33 users/delete.php:34
+#: users/delete.php:38 virtuals/delete.php:34 virtuals/delete.php:38
+msgid "Delete"
+msgstr "Iðtrinti"
+
+#: domains/index.php:44 domains/delete.php:26
+msgid "Delete Domain"
+msgstr "Iðtrinti domenà"
+
+#: users/index.php:82 users/delete.php:31 virtuals/index.php:55
+msgid "Delete User"
+msgstr "Iðtrinti vartotojà"
+
+#: virtuals/delete.php:31
+msgid "Delete Virtual Email Address"
+msgstr "Iðtrinti virtualø el. paðto adresà"
+
+#: domains/delete.php:31
+#, php-format
+msgid "Delete domain \"%s\", all the users and virtual email addresses?"
+msgstr ""
+"Iðtrinti domenà \"%s\", visus vartotojus ir virtualius el. paðto adresus?"
+
+#: virtuals/delete.php:36
+#, php-format
+msgid "Delete the virtual email address \"%s\" => \"%s\"?"
+msgstr "Iðtrinti virtualø el. paðto adresà \"%s\" => \"%s\"?"
+
+#: users/delete.php:36
+#, php-format
+msgid "Delete user \"%s\" and all associated virtual email addresses?"
+msgstr ""
+"Iðtrinti vartotojà \"%s\" ir visus susijusius virtualius el. paðto adresus?"
+
+#: virtuals/edit.php:64 templates/virtuals/index.html:20
+msgid "Destination"
+msgstr "Gavëjas"
+
+#: virtuals/edit.php:54
+msgid "Destination type"
+msgstr "Gavëjo tipas"
+
+#: lib/Driver/qmailldap.php:679
+msgid "Disable Delivery Only"
+msgstr "Tik iðjungti pristatymà"
+
+#: config/prefs.php.dist:10
+msgid "Display details"
+msgstr "Vaizdavimo nustatymai"
+
+#: config/prefs.php.dist:9
+msgid "Display listings"
+msgstr "Sàraðo rodymas"
+
+#: domains/delete.php:29 domains/delete.php:47 users/delete.php:34
+#: users/delete.php:52 virtuals/delete.php:34 virtuals/delete.php:52
+msgid "Do not delete"
+msgstr "Netrinti"
+
+#: lib/Forms/EditDomainForm.php:32 templates/domains/index.html:16
+msgid "Domain"
+msgstr "Domenas"
+
+#: domains/delete.php:41
+msgid "Domain deleted."
+msgstr "Domenas iðtrintas."
+
+#: domains/delete.php:48
+msgid "Domain not deleted."
+msgstr "Domenas neiðtrintas."
+
+#: domains/edit.php:35
+msgid "Domain saved."
+msgstr "Domenas iðsaugotas."
+
+#: domains/index.php:45 lib/Forms/EditDomainForm.php:20
+msgid "Edit Domain"
+msgstr "Redaguoti domenà"
+
+#: users/index.php:83 virtuals/index.php:56
+msgid "Edit User"
+msgstr "Redaguoti vartotojà"
+
+#: lib/Forms/EditUserForm.php:22
+#, php-format
+msgid "Edit User for \"%s\""
+msgstr "Redaguoti \"%s\" vartotojà"
+
+#: virtuals/edit.php:47
+msgid "Edit Virtual Email Address"
+msgstr "Redaguoti virtualius el. paðto adresus"
+
+#: virtuals/edit.php:53
+#, php-format
+msgid ""
+"Enter a virtual email address @%s and then indicate below where mail sent to "
+"that address is to be delivered. The address must begin with an "
+"alphanumerical character, it must contain only alphanumerical and '._-' "
+"characters, and must end with an alphanumerical character."
+msgstr ""
+"Áraðykite virtualø el. paðto adresà domenui @%s. Adresas turi prasidëti "
+"skaièiais arba raidëm, viduje gali turëti skaièius, raides arba '._-' "
+"simbolius, ir turi baigtis skaièiais arba raidëmis."
+
+#: lib/Driver/qmailldap.php:616
+#, php-format
+msgid "Error deleting account from LDAP: %s"
+msgstr "Klaida trinant vartotojo vardà ið LDAP: %s"
+
+#: domains/delete.php:39
+#, php-format
+msgid "Error deleting domain. %s."
+msgstr "Klaida trinant domenà. %s."
+
+#: users/delete.php:44
+#, php-format
+msgid "Error deleting user. %s."
+msgstr "Klaida trinant vartotojà. %s."
+
+#: virtuals/delete.php:44
+#, php-format
+msgid "Error deleting virtual email. %s."
+msgstr "Klaida trinant virtualø el. paðto adresà. %s."
+
+#: lib/Driver/qmailldap.php:210 lib/Driver/qmailldap.php:215
+#, php-format
+msgid "Error in LDAP search: %s"
+msgstr "Klaida atliekant LDAP paieðkà: %s"
+
+#: users/edit.php:35
+#, php-format
+msgid "Error reading address information from backend: %s"
+msgstr "Klaida ið posistemës skaitant adresø informacijà: %s"
+
+#: lib/Driver/qmailldap.php:606
+#, php-format
+msgid "Error retrieving LDAP results: %s"
+msgstr "Klaida gaunant LDAP rezultatus: %s"
+
+#: lib/Driver/qmailldap.php:347 lib/Driver/qmailldap.php:435
+#: lib/Driver/qmailldap.php:507
+#, php-format
+msgid "Error returning LDAP results: %s"
+msgstr "Klaida graþinant LDAP rezultatus: %s"
+
+#: lib/Driver.php:195
+msgid "Error running authentication update script."
+msgstr "Klaida leidþiant autentifikacijos atnaujinimo skriptà."
+
+#: domains/edit.php:33
+#, php-format
+msgid "Error saving domain: %s."
+msgstr "Klaida iðsaugant domenà: %s."
+
+#: users/edit.php:64
+#, php-format
+msgid "Error saving user. %s"
+msgstr "Klaida iðsaugant vartotojà. %s"
+
+#: virtuals/edit.php:77
+#, php-format
+msgid "Error saving virtual email. %s."
+msgstr "Klaida iðsaugant virtualø el. paðto adresà. %s."
+
+#: lib/Driver/qmailldap.php:341 lib/Driver/qmailldap.php:429
+#: lib/Driver/qmailldap.php:501 lib/Driver/qmailldap.php:600
+#, php-format
+msgid "Error searching LDAP: %s"
+msgstr "Klaida atliekant LDAP paieðkà: %s"
+
+#: lib/Forms/EditUserForm.php:41 templates/users/index.html:16
+msgid "Full Name"
+msgstr "Pilnas vardas"
+
+#: lib/Vilma.php:63
+msgid "Group/Forward"
+msgstr "Grupë/Persiuntimas"
+
+#: lib/Vilma.php:64
+msgid "Groups and Forwards"
+msgstr "Grupës ir persiuntimai"
+
+#: config/prefs.php.dist:20
+msgid "How many domain to display per page."
+msgstr "Kiek domenø rodyti viename puslapyje."
+
+#: virtuals/edit.php:56
+msgid "Local user"
+msgstr "Vietinis vartotojas"
+
+#: lib/MailboxDriver/imap.php:45
+#, php-format
+msgid "Mailbox '%s@%s' does not exist."
+msgstr "Paðto dëþutë '%s@%s' neegzistuoja."
+
+#: lib/MailboxDriver/maildrop.php:45
+#, php-format
+msgid "Maildrop directory \"%s\" does not exist."
+msgstr "Maildrop katalogas \"%s\" neegzistuoja."
+
+#: templates/domains/index.html:19
+msgid "Max Users"
+msgstr "Maks. vartotojø skaièius"
+
+#: lib/Forms/EditDomainForm.php:35
+msgid "Max users"
+msgstr "Maks. vartotojø skaièius"
+
+#: users/index.php:69
+msgid "Maximum Users"
+msgstr "Maks. vartotojø skaièius"
+
+#: lib/Driver/qmailldap.php:511
+msgid ""
+"More than one DN returned for this alias. Please contact an administrator "
+"to resolve this error."
+msgstr ""
+"Rastas daugiau nei vienas DN atitinkantis ðá vartotojà. Susisiekite su "
+"administratoriumi."
+
+#: lib/Driver/qmailldap.php:610
+msgid "More than one DN returned. Aborting delete operation."
+msgstr "Rastas daugiau nei vienas DN. Trynimo operacija nutraukiama."
+
+#: lib/Forms/EditUserForm.php:35
+msgid ""
+"Name must begin with an alphanumeric character, must contain only "
+"alphanumeric and '._-' characters, and must end with an alphanumeric "
+"character."
+msgstr ""
+"Vardas turi prasidëti skaièiais arba raidëm, viduje gali turëti skaièius, "
+"raides arba simbolius '._-', ir turi baigtis skaièiais arba raidëmis."
+
+#: lib/Forms/EditDomainForm.php:20
+msgid "New Domain"
+msgstr "Naujas domenas"
+
+#: lib/Forms/EditUserForm.php:24
+#, php-format
+msgid "New User @%s"
+msgstr "Naujas @%s vartotojas"
+
+#: virtuals/index.php:48
+msgid "New Virtual Email"
+msgstr "Naujas virtualus el. paðtas"
+
+#: virtuals/edit.php:47
+msgid "New Virtual Email Address"
+msgstr "Naujas virtualus el. paðto adresas"
+
+#: lib/Vilma.php:169
+msgid "New _Address"
+msgstr "Naujas adresas"
+
+#: lib/MailboxDriver/maildrop.php:19
+msgid "No 'mail_dir_base' parameter specified to maildrop driver."
+msgstr "Maildrop tvarkyklëje neáraðytas 'mail_dir_base' parametras."
+
+#: lib/MailboxDriver/maildrop.php:60
+msgid "No 'system_user' parameter specified to maildrop driver."
+msgstr "Maildrop tvarkyklëje neáraðytas 'system_user' parametras."
+
+#: lib/Driver.php:108
+#, php-format
+msgid "No such address %s of type %s found."
+msgstr "Adresas %s, kurio tipas %s, nerastas."
+
+#: lib/Driver.php:329
+#, php-format
+msgid "No such backend \"%s\" found"
+msgstr "Posistemë \"%s\" nerasta"
+
+#: users/edit.php:74
+msgid ""
+"No virtual email address set up for this user. You should set up at least "
+"one virtual email address if this user is to receive any emails."
+msgstr ""
+"Ðis vartotojas neturi virtualiø el. paðto adresø. Jeigu ðis vartotojas gauna "
+"el. laiðkus, turëtumëte nurodyti bent vienà virtualø el. paðto adresà."
+
+#: lib/Driver.php:249
+msgid "Not implemented."
+msgstr "Nerealizuota."
+
+#: lib/Forms/EditUserForm.php:37
+msgid "Only enter a password if you wish to change this user's password"
+msgstr "Slaptaþodá áraðykite tik tada, jeigu já keièiate"
+
+#: lib/Forms/EditUserForm.php:37 lib/Forms/EditUserForm.php:39
+msgid "Password"
+msgstr "Slaptaþodis"
+
+#: lib/Driver/sql.php:465
+msgid "Password must be supplied when creating a new user."
+msgstr "Kurdami naujà vartotojà, privalote áraðyti slaptaþodá."
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Quota"
+msgstr "Vieta serveryje"
+
+#: virtuals/edit.php:57
+msgid "Remote address"
+msgstr "Iðoriniai adresai"
+
+#: virtuals/edit.php:61
+msgid "Remote e-mail address"
+msgstr "Iðorinis el. paðto adresas"
+
+#: config/prefs.php.dist:11
+msgid "Set default display parameters."
+msgstr "Standartinio vaizdavimo parametrø nustatymas."
+
+#: templates/users/index.html:22
+msgid "Status"
+msgstr "Bûsena"
+
+#: lib/api.php:43
+msgid "Super Administrator"
+msgstr "Super administratorius"
+
+#: lib/MailboxDriver.php:78
+msgid "This driver cannot create mailboxes."
+msgstr "Ði tvarkyklë negali kurti paðto dëþuèiø."
+
+#: lib/MailboxDriver.php:94
+msgid "This driver cannot delete mailboxes."
+msgstr "Ði tvarkyklë negali trinti paðto dëþuèiø."
+
+#: lib/Forms/EditDomainForm.php:34
+msgid "Transport"
+msgstr "Transportas"
+
+#: templates/users/index.html:19
+msgid "Type"
+msgstr "Tipas"
+
+#: lib/Driver/qmailldap.php:715
+msgid "Unable to bind to the LDAP server. Check authentication credentials."
+msgstr ""
+"Nepavyko autentifikuotis á LDAP serverá. Patikrinkite vartotojo vardà bei "
+"slaptaþodá."
+
+#: lib/Driver/qmailldap.php:710
+msgid "Unable to set LDAP protocol version"
+msgstr "Klaida keièiant LDAP protokolo versijà"
+
+#: lib/Driver.php:199
+msgid "Unknown error running authentication update script."
+msgstr "Bevykdant autentifikacijos atnaujinimo skriptà ávyko neþinoma klaida."
+
+#: lib/Vilma.php:57
+msgid "User"
+msgstr "Vartotojas"
+
+#: lib/Forms/EditUserForm.php:35
+msgid "User Name"
+msgstr "Vartotojo vardas"
+
+#: users/delete.php:46
+msgid "User deleted."
+msgstr "Vartotojas iðtrintas."
+
+#: users/edit.php:66
+msgid "User details saved."
+msgstr "Vartotojo apraðymas iðsaugotas."
+
+#: lib/Driver.php:132
+msgid "User disabled."
+msgstr "Vartotojas iðjungtas"
+
+#: users/delete.php:53
+msgid "User not deleted."
+msgstr "Vartotojas neiðtrintas."
+
+#: lib/Driver.php:155
+msgid "User ready."
+msgstr "Vartotojas paruoðtas."
+
+#: lib/Vilma.php:58 virtuals/index.php:51
+msgid "Users"
+msgstr "Vartotojai"
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Value in MB"
+msgstr "Reikðmë MB"
+
+#: lib/Driver.php:210
+msgid "Vilma_Driver::deleteUser(): Method Not Implemented."
+msgstr "Vilma_Driver::deleteUser(): metodas nerealizuotas."
+
+#: virtuals/edit.php:53
+msgid "Virtual Email"
+msgstr "Virtualus el. paðtas"
+
+#: templates/virtuals/index.html:17
+msgid "Virtual Email Address"
+msgstr "Virtualus el. paðto adresas"
+
+#: virtuals/delete.php:46
+msgid "Virtual email deleted."
+msgstr "Virtualus el. paðto adresas iðtrintas."
+
+#: virtuals/delete.php:53
+msgid "Virtual email not deleted."
+msgstr "Virtualus el. paðto adresas neiðtrintas."
+
+#: virtuals/edit.php:79
+msgid "Virtual email saved."
+msgstr "Virtualus el. paðto adresas iðsaugotas."
+
+#: lib/Driver/qmailldap.php:35
+msgid "You must configure a Horde DataTree backend to use Vilma."
+msgstr ""
+"Norëdami naugotis paðto valdymo sistema, turite sukonfigûruoti duomenø "
+"medþio posistemæ."
+
+#: lib/Vilma.php:166
+msgid "_Domains"
+msgstr "Domenai"
+
+#: lib/Vilma.php:171
+msgid "_New Domain"
+msgstr "Naujas domenas"
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright YEAR Horde Project
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
+"POT-Creation-Date: 2008-04-01 14:58+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: users/edit.php:53
+#, php-format
+msgid "\"%s\" already has the maximum number of users allowed."
+msgstr ""
+
+#: lib/Driver/qmailldap.php:647
+msgid "Account Status"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:655
+msgid "Account is active"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:658
+msgid "Account is disabled"
+msgstr ""
+
+#: templates/users/index.html:13
+msgid "Address"
+msgstr ""
+
+#: lib/Vilma.php:60
+msgid "Alias"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:332
+#, php-format
+msgid "Alias for %s"
+msgstr ""
+
+#: lib/Vilma.php:61
+msgid "Aliases"
+msgstr ""
+
+#: lib/Vilma.php:54 lib/Vilma.php:55
+msgid "All"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:657
+msgid "Bounce Incoming Only"
+msgstr ""
+
+#: domains/delete.php:27 users/delete.php:34 users/delete.php:38
+#: virtuals/delete.php:34 virtuals/delete.php:38
+#: lib/Forms/DeleteDomainForm.php:27
+msgid "Delete"
+msgstr ""
+
+#: domains/index.php:44 lib/Forms/DeleteDomainForm.php:17
+msgid "Delete Domain"
+msgstr ""
+
+#: users/index.php:83 users/delete.php:31 virtuals/index.php:55
+msgid "Delete User"
+msgstr ""
+
+#: virtuals/delete.php:31
+msgid "Delete Virtual Email Address"
+msgstr ""
+
+#: lib/Forms/DeleteDomainForm.php:29
+#, php-format
+msgid "Delete domain \"%s\" and all associated email addresses?"
+msgstr ""
+
+#: virtuals/delete.php:36
+#, php-format
+msgid "Delete the virtual email address \"%s\" => \"%s\"?"
+msgstr ""
+
+#: users/delete.php:36
+#, php-format
+msgid "Delete user \"%s\" and all associated virtual email addresses?"
+msgstr ""
+
+#: virtuals/edit.php:64 templates/virtuals/index.html:20
+msgid "Destination"
+msgstr ""
+
+#: virtuals/edit.php:54
+msgid "Destination type"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:656
+msgid "Disable Delivery Only"
+msgstr ""
+
+#: config/prefs.php.dist:10
+msgid "Display details"
+msgstr ""
+
+#: config/prefs.php.dist:9
+msgid "Display listings"
+msgstr ""
+
+#: domains/delete.php:41 users/delete.php:34 users/delete.php:52
+#: virtuals/delete.php:34 virtuals/delete.php:52
+#: lib/Forms/DeleteDomainForm.php:27
+msgid "Do not delete"
+msgstr ""
+
+#: lib/Forms/EditDomainForm.php:32 templates/domains/index.html:16
+msgid "Domain"
+msgstr ""
+
+#: lib/Driver.php:229
+msgid ""
+"Domain added but an error was encountered while calling the configured "
+"hook. Contact your administrator for futher assistance."
+msgstr ""
+
+#: domains/delete.php:35
+msgid "Domain deleted."
+msgstr ""
+
+#: domains/delete.php:42
+msgid "Domain not deleted."
+msgstr ""
+
+#: domains/edit.php:35
+msgid "Domain saved."
+msgstr ""
+
+#: domains/index.php:45 lib/Forms/EditDomainForm.php:20
+msgid "Edit Domain"
+msgstr ""
+
+#: users/index.php:84 virtuals/index.php:56
+msgid "Edit User"
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:22
+#, php-format
+msgid "Edit User for \"%s\""
+msgstr ""
+
+#: virtuals/edit.php:47
+msgid "Edit Virtual Email Address"
+msgstr ""
+
+#: virtuals/edit.php:53
+#, php-format
+msgid ""
+"Enter a virtual email address @%s and then indicate below where mail sent to "
+"that address is to be delivered. The address must begin with an "
+"alphanumerical character, it must contain only alphanumerical and '._-' "
+"characters, and must end with an alphanumerical character."
+msgstr ""
+
+#: lib/Driver/qmailldap.php:593
+#, php-format
+msgid "Error deleting account from LDAP: %s"
+msgstr ""
+
+#: domains/delete.php:33
+#, php-format
+msgid "Error deleting domain. %s."
+msgstr ""
+
+#: users/delete.php:44
+#, php-format
+msgid "Error deleting user. %s."
+msgstr ""
+
+#: virtuals/delete.php:44
+#, php-format
+msgid "Error deleting virtual email. %s."
+msgstr ""
+
+#: lib/Driver/qmailldap.php:170 lib/Driver/qmailldap.php:175
+#, php-format
+msgid "Error in LDAP search: %s"
+msgstr ""
+
+#: users/edit.php:35
+#, php-format
+msgid "Error reading address information from backend: %s"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:583
+#, php-format
+msgid "Error retrieving LDAP results: %s"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:308 lib/Driver/qmailldap.php:396
+#: lib/Driver/qmailldap.php:468
+#, php-format
+msgid "Error returning LDAP results: %s"
+msgstr ""
+
+#: lib/Driver.php:195
+msgid "Error running authentication update script."
+msgstr ""
+
+#: domains/edit.php:33
+#, php-format
+msgid "Error saving domain: %s."
+msgstr ""
+
+#: users/edit.php:64
+#, php-format
+msgid "Error saving user. %s"
+msgstr ""
+
+#: virtuals/edit.php:77
+#, php-format
+msgid "Error saving virtual email. %s."
+msgstr ""
+
+#: lib/Driver/qmailldap.php:302 lib/Driver/qmailldap.php:390
+#: lib/Driver/qmailldap.php:462 lib/Driver/qmailldap.php:577
+#, php-format
+msgid "Error searching LDAP: %s"
+msgstr ""
+
+#: lib/Driver.php:280
+msgid "Error while calling hook to delete domain."
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:41 templates/users/index.html:16
+msgid "Full Name"
+msgstr ""
+
+#: lib/Vilma.php:63
+msgid "Group/Forward"
+msgstr ""
+
+#: lib/Vilma.php:64
+msgid "Groups and Forwards"
+msgstr ""
+
+#: config/prefs.php.dist:20
+msgid "How many domain to display per page."
+msgstr ""
+
+#: virtuals/edit.php:56
+msgid "Local user"
+msgstr ""
+
+#: lib/MailboxDriver/imap.php:45
+#, php-format
+msgid "Mailbox '%s@%s' does not exist."
+msgstr ""
+
+#: lib/MailboxDriver/maildrop.php:45
+#, php-format
+msgid "Maildrop directory \"%s\" does not exist."
+msgstr ""
+
+#: templates/domains/index.html:19
+msgid "Max Users"
+msgstr ""
+
+#: lib/Forms/EditDomainForm.php:35
+msgid "Max users"
+msgstr ""
+
+#: users/index.php:70
+msgid "Maximum Users"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:472
+msgid ""
+"More than one DN returned for this alias. Please contact an administrator "
+"to resolve this error."
+msgstr ""
+
+#: lib/Driver/qmailldap.php:587
+msgid "More than one DN returned. Aborting delete operation."
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:35
+msgid ""
+"Name must begin with an alphanumeric character, must contain only "
+"alphanumeric and '._-' characters, and must end with an alphanumeric "
+"character."
+msgstr ""
+
+#: lib/Forms/EditDomainForm.php:20
+msgid "New Domain"
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:24
+#, php-format
+msgid "New User @%s"
+msgstr ""
+
+#: virtuals/index.php:48
+msgid "New Virtual Email"
+msgstr ""
+
+#: virtuals/edit.php:47
+msgid "New Virtual Email Address"
+msgstr ""
+
+#: lib/Vilma.php:169
+msgid "New _Address"
+msgstr ""
+
+#: lib/MailboxDriver/maildrop.php:19
+msgid "No 'mail_dir_base' parameter specified to maildrop driver."
+msgstr ""
+
+#: lib/MailboxDriver/maildrop.php:60
+msgid "No 'system_user' parameter specified to maildrop driver."
+msgstr ""
+
+#: lib/Driver.php:108
+#, php-format
+msgid "No such address %s of type %s found."
+msgstr ""
+
+#: lib/Driver.php:374
+#, php-format
+msgid "No such backend \"%s\" found"
+msgstr ""
+
+#: users/edit.php:74
+msgid ""
+"No virtual email address set up for this user. You should set up at least "
+"one virtual email address if this user is to receive any emails."
+msgstr ""
+
+#: lib/Driver.php:245 lib/Driver.php:294
+msgid "Not implemented."
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:37
+msgid "Only enter a password if you wish to change this user's password"
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:37 lib/Forms/EditUserForm.php:39
+msgid "Password"
+msgstr ""
+
+#: lib/Driver/sql.php:465
+msgid "Password must be supplied when creating a new user."
+msgstr ""
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Quota"
+msgstr ""
+
+#: virtuals/edit.php:57
+msgid "Remote address"
+msgstr ""
+
+#: virtuals/edit.php:61
+msgid "Remote e-mail address"
+msgstr ""
+
+#: config/prefs.php.dist:11
+msgid "Set default display parameters."
+msgstr ""
+
+#: templates/users/index.html:22
+msgid "Status"
+msgstr ""
+
+#: lib/api.php:43
+msgid "Super Administrator"
+msgstr ""
+
+#: lib/MailboxDriver.php:78
+msgid "This driver cannot create mailboxes."
+msgstr ""
+
+#: lib/MailboxDriver.php:94
+msgid "This driver cannot delete mailboxes."
+msgstr ""
+
+#: lib/Forms/EditDomainForm.php:34
+msgid "Transport"
+msgstr ""
+
+#: templates/users/index.html:19
+msgid "Type"
+msgstr ""
+
+#: lib/Driver/qmailldap.php:696
+msgid "Unable to bind to the LDAP server. Check authentication credentials."
+msgstr ""
+
+#: lib/Driver/qmailldap.php:691
+msgid "Unable to set LDAP protocol version"
+msgstr ""
+
+#: lib/Driver.php:199
+msgid "Unknown error running authentication update script."
+msgstr ""
+
+#: lib/Vilma.php:57
+msgid "User"
+msgstr ""
+
+#: lib/Forms/EditUserForm.php:35
+msgid "User Name"
+msgstr ""
+
+#: users/delete.php:46
+msgid "User deleted."
+msgstr ""
+
+#: users/edit.php:66
+msgid "User details saved."
+msgstr ""
+
+#: lib/Driver.php:132
+msgid "User disabled."
+msgstr ""
+
+#: users/delete.php:53
+msgid "User not deleted."
+msgstr ""
+
+#: lib/Driver.php:155
+msgid "User ready."
+msgstr ""
+
+#: virtuals/index.php:51 lib/Vilma.php:58
+msgid "Users"
+msgstr ""
+
+#: lib/Forms/EditDomainForm.php:36
+msgid "Value in MB"
+msgstr ""
+
+#: lib/Driver.php:210
+msgid "Vilma_Driver::deleteUser(): Method Not Implemented."
+msgstr ""
+
+#: virtuals/edit.php:53
+msgid "Virtual Email"
+msgstr ""
+
+#: templates/virtuals/index.html:17
+msgid "Virtual Email Address"
+msgstr ""
+
+#: virtuals/delete.php:46
+msgid "Virtual email deleted."
+msgstr ""
+
+#: virtuals/delete.php:53
+msgid "Virtual email not deleted."
+msgstr ""
+
+#: virtuals/edit.php:79
+msgid "Virtual email saved."
+msgstr ""
+
+#: lib/Vilma.php:166
+msgid "_Domains"
+msgstr ""
+
+#: lib/Vilma.php:171
+msgid "_New Domain"
+msgstr ""
--- /dev/null
+Deny from all
--- /dev/null
+#!/usr/bin/php
+<?php
+/**
+ * This script will check the user table and create any mail directories on the
+ * system for any new users. A cron job can be set up to run this periodically.
+ *
+ * $Horde: vilma/scripts/create_mailboxes.php,v 1.6 2009/06/10 19:58:04 slusarz Exp $
+ */
+
+// No auth.
+@define('AUTH_HANDLER', true);
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+
+// Make sure no one runs this from the web.
+if (!Horde_Cli::runningFromCLI()) {
+ exit("Must be run from the command line\n");
+}
+
+// Load the CLI environment - make sure there's no time limit, init
+// some variables, etc.
+Horde_Cli::init();
+
+/* Make sure there's no compression. */
+@ob_end_clean();
+
+$users_by_domain = $vilma_driver->getAllUsers();
+
+foreach ($users_by_domain as $domain => $users) {
+ foreach ($users as $user) {
+ /* Check for user's home dir. */
+ if (!file_exists($user['user_home_dir'])) {
+ /* Try to make the user_home_dir, if false skip. */
+ if (!mkdir($user['user_home_dir'])) {
+ continue;
+ }
+ }
+ /* Check for the domain's dir. */
+ $domain_dir = $user['user_home_dir'] . '/' . $domain;
+ if (!file_exists($domain_dir)) {
+ /* Try to make the user_home_dir, if false skip. */
+ if (!mkdir($domain_dir)) {
+ continue;
+ }
+ }
+ /* Check for user's mailbox directory and if missing create it. */
+ $mailbox_dir = $user['user_home_dir'] . '/' . $user['user_mail_dir'];
+ if (!file_exists($mailbox_dir)) {
+ system('maildirmake ' . $mailbox_dir);
+ }
+ }
+}
--- /dev/null
+--$Horde: vilma/scripts/sql/vilma.sql,v 1.8 2007/04/17 12:44:06 jan Exp $
+-- SQL scripts.
+
+CREATE TABLE vilma_domains (
+ domain_id INT DEFAULT 0 NOT NULL,
+ domain_name VARCHAR(128) DEFAULT '' NOT NULL,
+ domain_transport VARCHAR(128) DEFAULT '' NOT NULL,
+ domain_max_users INT DEFAULT 0 NOT NULL,
+ domain_quota INT DEFAULT 0 NOT NULL,
+ domain_key VARCHAR(64),
+--
+ PRIMARY KEY (domain_id),
+ UNIQUE (domain_name)
+);
+
+CREATE TABLE vilma_users (
+ user_id INT DEFAULT 0 NOT NULL,
+ user_name VARCHAR(255) DEFAULT '' NOT NULL,
+ user_clear VARCHAR(255) DEFAULT '' NOT NULL,
+ user_crypt VARCHAR(255) DEFAULT '' NOT NULL,
+ user_full_name VARCHAR(255) DEFAULT '' NOT NULL,
+ user_uid INT NOT NULL,
+ user_gid INT NOT NULL,
+ user_home_dir VARCHAR(255) DEFAULT '' NOT NULL,
+ user_mail_dir VARCHAR(255) DEFAULT '' NOT NULL,
+ user_mail_quota INT DEFAULT 0 NOT NULL,
+ user_ftp_dir VARCHAR(255) DEFAULT NULL,
+ user_ftp_quota INT DEFAULT NULL,
+ user_enabled SMALLINT DEFAULT 1 NOT NULL,
+--
+ PRIMARY KEY (user_id),
+ UNIQUE (user_name)
+);
+
+CREATE TABLE vilma_virtuals (
+ virtual_id INT DEFAULT 0 NOT NULL,
+ virtual_email VARCHAR(128) DEFAULT '' NOT NULL,
+ virtual_destination VARCHAR(128) DEFAULT '' NOT NULL,
+--
+ PRIMARY KEY (virtual_id)
+);
--- /dev/null
+<?php
+if (isset($language)) {
+ header('Content-type: text/html; charset=' . Horde_Nls::getCharset());
+ header('Vary: Accept-Language');
+}
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+<!-- Vilma: Copyright 2003-2009 The Horde Project. Vilma is under a Horde license. -->
+<!-- Horde Project: http://www.horde.org/ | Vilma: http://www.horde.org/vilma/ -->
+<!-- Horde BSD License: http://www.horde.org/licenses/bsdl.php -->
+<?php echo !empty($language) ? '<html lang="' . strtr($language, '_', '-') . '">' : '<html>' ?>
+<head>
+<?php
+
+$page_title = $GLOBALS['registry']->get('name');
+if (!empty($title)) $page_title .= ' :: ' . $title;
+if (!empty($refresh_time) && ($refresh_time > 0) && !empty($refresh_url)) {
+ echo "<meta http-equiv=\"refresh\" content=\"$refresh_time;url=$refresh_url\">\n";
+}
+
+Horde::includeScriptFiles();
+
+?>
+<title><?php echo htmlspecialchars($page_title) ?></title>
+<link href="<?php echo $GLOBALS['registry']->getImageDir()?>/favicon.ico" rel="SHORTCUT ICON" />
+<?php Horde::includeStylesheetFiles() ?>
+</head>
+
+<body<?php if ($bc = Horde_Util::nonInputVar('bodyClass')) echo ' class="' . $bc . '"' ?><?php if ($bi = Horde_Util::nonInputVar('bodyId')) echo ' id="' . $bi . '"'; ?>>
--- /dev/null
+<div id="menu">
+ <tag:menu />
+</div>
+
+<tag:notify />
+
+<p class="item">
+ <a href="<tag:actions.new_url />"><tag:actions.new_text /></a>
+</p>
+
+<if:domains>
+<table width="100%" cellspacing="1" class="linedRow">
+ <tr class="item">
+ <th> </th>
+ <th>
+ <gettext>Domain</gettext>
+ </th>
+ <th>
+ <gettext>Max Users</gettext>
+ </th>
+ </tr>
+ <loop:domains>
+ <tr>
+ <td>
+ <a href="<tag:domains.edit_url />"><tag:images.edit /></a>
+ <a href="<tag:domains.del_url />"><tag:images.delete /></a>
+ </td>
+ <td>
+ <a href="<tag:domains.view_url />"><tag:domains.domain_name /></a>
+ </td>
+ <td class="rightAlign">
+ <tag:domains.domain_max_users />
+ </td>
+ </tr>
+ </loop:domains>
+</table>
+</if:domains>
--- /dev/null
+<div id="menu">
+ <tag:menu />
+</div>
+<tag:notify />
+<tag:main />
--- /dev/null
+<div id="menu">
+ <tag:menu />
+</div>
+
+<tag:notify />
+
+<tag:tabs />
+<if:addresses>
+<table width="100%" cellspacing="1" class="linedRow">
+ <tr class="item">
+ <th> </th>
+ <th>
+ <gettext>Address</gettext>
+ </th>
+ <th>
+ <gettext>Full Name</gettext>
+ </th>
+ <th>
+ <gettext>Type</gettext>
+ </th>
+ <th>
+ <gettext>Status</gettext>
+ </th>
+ </tr>
+ <loop:addresses>
+ <tr>
+ <td>
+ <if:addresses.edit_url>
+ <a href="<tag:addresses.edit_url />"><tag:images.edit /></a>
+ </if:addresses.edit_url>
+ <a href="<tag:addresses.del_url />"><tag:images.delete /></a>
+ </td>
+ <td>
+ <if:addresses.view_url>
+ <a href="<tag:addresses.view_url />">
+ </if:addresses.view_url>
+ <if:addresses.user_name>
+ <tag:addresses.user_name />
+ </if:addresses.user_name>
+ <if:addresses.address>
+ <<tag:addresses.address />>
+ </if:addresses.address>
+ <if:addresses.view_url>
+ </a>
+ </if:addresses.view_url>
+ </td>
+ <td align="center">
+ <tag:addresses.user_full_name />
+ </td>
+ <td class="rightAlign">
+ <tag:addresses.type />
+ </td>
+ <td>
+ <loop:addresses.status>
+ <tag:addresses.status /><br />
+ </loop:addresses.status>
+ </td>
+ </tr>
+ </loop:addresses>
+</table>
+</if:addresses>
+<tag:pager />
--- /dev/null
+<div id="menu">
+ <tag:menu />
+</div>
+
+<tag:notify />
+
+<p class="item">
+ <a href="<tag:actions.new_url />"><tag:actions.new_text /></a> |
+ <a href="<tag:actions.users_url />"><tag:actions.users_text /></a>
+</p>
+
+<if:virtuals>
+<table width="100%" cellspacing="1" class="linedRow">
+ <tr class="item">
+ <th> </th>
+ <th>
+ <gettext>Virtual Email Address</gettext>
+ </th>
+ <th>
+ <gettext>Destination</gettext>
+ </th>
+ </tr>
+ <loop:virtuals>
+ <tr>
+ <td>
+ <a href="<tag:virtuals.edit_url />"><tag:images.edit /></a>
+ <a href="<tag:virtuals.del_url />"><tag:images.delete /></a>
+ </td>
+ <td>
+ <tag:virtuals.virtual_email />
+ </td>
+ <td align="center">
+ <tag:virtuals.virtual_destination />
+ </td>
+ </tr>
+ </loop:virtuals>
+</table>
+</if:virtuals>
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/test.php,v 1.16 2009/01/06 18:02:26 jan Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @package Vilma
+ */
+
+require_once './lib/version.php';
+@define('CONFIG_DIR', dirname(__FILE__) . '/config/');
+
+$setup_ok = true;
+
+$config_files = array('conf.php', 'prefs.php');
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+<title>Vilma: System Capabilities Test</title>
+</head>
+
+<body>
+
+<h1>Vilma Version</h1>
+<ul>
+ <li>Vilma: <?php echo VILMA_VERSION ?></li>
+</ul>
+
+<h1>Vilma Configuration Files</h1>
+<ul>
+<?php
+foreach ($config_files as $file) {
+ if (file_exists(CONFIG_DIR . $file)) {
+ ?><li><?php echo $file ?> - <font color="green"><strong>Yes</strong></font><?php
+ } else {
+ $setup_ok = false;
+ ?><li><?php echo $file ?> - <font color="red"><strong>No</strong></font><?php
+ }
+}
+?>
+</ul>
+</body>
+</html>
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/users/delete.php,v 1.27 2009/06/10 17:33:45 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Form.php';
+
+/* Only admin should be using this. */
+if (!Vilma::hasPermission($domain)) {
+ Horde::authenticationFailureRedirect();
+}
+
+$vars = Horde_Variables::getDefaultVariables();
+$address = $vars->get('address');
+$section = Horde_Util::getFormData('section','all');
+
+//$addrInfo = $vilma_driver->getAddressInfo($address, 'all');
+/*
+$user_id = $vars->get('address');
+$formname = $vars->get('formname');
+$user = $vilma_driver->getUser($user_id);
+print_r($vars) . '<br />';
+echo $user_id . '<br />';
+echo $fromname . '<br />';
+print_r($user) . '<br />';
+$domain = Vilma::stripDomain($user['name']);
+$domain = $vilma_driver->getDomainByName($domain);
+*/
+$address = $vilma_driver->getAddressInfo($address);
+$type = $address['type'];
+if(($section == 'all') && ($type == 'alias')) {
+ $address = $vilma_driver->getAddressInfo($vars->get('address'),$type);
+}
+$user_id = $vars->get('address');
+$user = $vilma_driver->getUser($user_id);
+$aliases = $vilma_driver->_getAliases($user_id);
+$aliasesCount = 0;
+if(is_array($aliases)) {
+ $aliasesCount = sizeof($aliases);
+}
+$domain = Vilma::stripDomain($user_id);
+$forwards = $vilma_driver->_getGroupsAndForwards('forwards',$domain);
+$forwardsCount = 0;
+foreach($forwards as $entry) {
+ foreach($entry['targets'] as $target) {
+ if($user_id === $target) {
+ $forwardsCount++;
+ }
+ }
+}
+$groups = $vilma_driver->_getGroupsAndForwards('groups',$domain);
+$groupsCount = 0;
+foreach($groups as $entry) {
+ foreach($entry['targets'] as $target) {
+ if($user_id === $target) {
+ $groupsCount++;
+ }
+ }
+}
+if (is_a($address, 'PEAR_Error')) {
+ $notification->push(sprintf(_("Error reading address information from backend: %s"), $address->getMessage()), 'horde.error');
+ $url = '/users/index.php';
+ require VILMA_BASE . $url;
+ exit;
+}
+$user_name = $address['user_name'];
+if(!isset($user_name) || empty($user_name)) {
+ $user_name = $address['address'];
+}
+$vars->set('user_name', Vilma::stripUser($user_name));
+$domain = Vilma::stripDomain($address);
+$domain = $vilma_driver->getDomainByName($domain);
+$vars->set('domain', $domain);
+$vars->set('mode', 'edit');
+
+$form = new Horde_Form($vars, _("Delete User"));
+/* Set up the form. */
+$form->setButtons(array(_("Delete"), _("Do not delete")));
+//$form->addHidden($user_id, 'user_id', 'text', false);
+$form->addHidden($address['address'], 'address', 'text', false);
+$form->addHidden($section, 'section', 'text', false);
+
+$desc = "Delete user \"%s\"";
+$sub = " and all dependencies?";
+$tot = $aliasesCount + $groupsCount + $forwardsCount;
+if($tot > 0) {
+ $desc .= $sub;
+} else {
+ $desc .= "?";
+}
+if($aliasesCount > 0) {
+ $desc .= " Account has " . $aliasesCount . " aliases.";
+}
+if($forwardsCount > 0) {
+ $desc .= " Account is the target of " . $forwardsCount . " forward(s).";
+}
+if($groupsCount > 0) {
+ $desc .= " Account belongs to " . $groupsCount . " group(s).";
+}
+$form->addVariable(sprintf(_($desc), $user_name), 'description', 'description', false);
+if ($vars->get('submitbutton') == _("Delete")) {
+ if($type == 'alias') {
+ if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ $delete = $vilma_driver->_savealias($address['address'],'delete');
+ if (is_a($delete, 'PEAR_Error')) {
+ Horde::logMessage($delete, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error deleting user. %s."), $delete->getMessage()), 'horde.error');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('users/index.php'), 'domain_id', $domain['id'], false);
+ header('Location: ' . $url);
+ exit;
+ } else {
+ $notification->push(_("User deleted."), 'horde.success');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('users/index.php'), 'domain_id', $domain['id'], false);
+ header('Location: ' . $url);
+ exit;
+ }
+ }
+ } else {
+ if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ //$delete = $vilma_driver->deleteUser($info['user_id']);
+ $delete = $vilma_driver->deleteUser($address['address']);
+ if (is_a($delete, 'PEAR_Error')) {
+ Horde::logMessage($delete, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error deleting user. %s."), $delete->getMessage()), 'horde.error');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('users/index.php'), 'domain_id', $domain['id'], false);
+ header('Location: ' . $url);
+ exit;
+ } else {
+ $notification->push(_("User deleted."), 'horde.success');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('users/index.php'), 'domain_id', $domain['id'], false);
+ header('Location: ' . $url);
+ exit;
+ }
+ }
+ }
+} elseif ($vars->get('submitbutton') == _("Do not delete")) {
+ $notification->push(_("User not deleted."), 'horde.message');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('users/index.php'), 'domain_id', $domain['domain_id'], false);
+ header('Location: ' . $url);
+ exit;
+}
+
+/* Render the form. */
+require_once 'Horde/Form/Renderer.php';
+$renderer = &new Horde_Form_Renderer();
+$main = Horde_Util::bufferOutput(array($form, 'renderActive'), $renderer, $vars, 'delete.php', 'post');
+
+$template->set('main', $main);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/main/main.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * The Vilma script to add/edit users.
+ *
+ * $Horde: vilma/users/edit.php,v 1.45 2009/07/14 18:43:46 selsky Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @author David Cummings <davidcummings@acm.org>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Form.php';
+
+require_once VILMA_BASE . '/lib/Forms/EditUserForm.php';
+
+/* Only admin should be using this. */
+if (!Vilma::hasPermission($domain)) {
+ Horde::authenticationFailureRedirect();
+}
+$vars = Horde_Variables::getDefaultVariables();
+$address = $vars->get('address');
+$section = Horde_Util::getFormData('section','all');
+
+//$addrInfo = $vilma_driver->getAddressInfo($address, 'all');
+$domain = Vilma::stripDomain($address);
+
+/* Check if a form is being edited. */
+if (!$vars->exists('mode')) {
+ if ($address) {
+ $address = $vilma_driver->getAddressInfo($address,$section);
+ if (is_a($address, 'PEAR_Error')) {
+ $notification->push(sprintf(_("Error reading address information from backend: %s"), $address->getMessage()), 'horde.error');
+ $url = '/users/index.php';
+ require VILMA_BASE . $url;
+ exit;
+ }
+ $vars = new Horde_Variables($address);
+ $user_name = //$vars->get('address');
+ $vars->get('user_name');
+ $vars->set('user_name', Vilma::stripUser($user_name));
+ $domain = Vilma::stripDomain($user_name);
+ $vars->set('domain', $domain);
+ $vars->set('type', $address['type']);
+ $vars->set('target', 'test'); //$address['target']);
+ $vars->set('mode', 'edit');
+ } else {
+ $vars->set('mode', 'new');
+ $domain_info = $_SESSION['vilma']['domain'];
+ $domain = $domain_info['domain_name'];
+ $domain_id = $domain_info['domain_id'];
+ $vars->set('domain', $domain);
+ $vars->set('id', $domain_id);
+ $vars->add('user_name', Horde_Util::getFormData('user_name',''));
+ }
+}
+
+$domain = Vilma::stripDomain($address['address']);
+$tmp = $vars->get('domain');
+if(!isset($tmp)) {
+ $vars->set('domain', $domain);
+}
+$form = &new EditUserForm($vars);
+if (!$vars->exists('id') && !$vilma_driver->isBelowMaxUsers($domain)) {
+ $notification->push(sprintf(_("\"%s\" already has the maximum number of users allowed."), $domain), 'horde.error');
+ require VILMA_BASE . '/users/index.php';
+ exit;
+}
+if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ $info['user_name'] = Horde_String::lower($info['user_name']) . '@' . $domain;
+ $user_id = $vilma_driver->saveUser($info);
+ if (is_a($user_id, 'PEAR_Error')) {
+ Horde::logMessage($user_id, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error saving user. %s"), $user_id->getMessage()), 'horde.error');
+ } else {
+ $notification->push(_("User details saved."), 'horde.success');
+ /*
+ $virtuals = $vilma_driver->getVirtuals($info['name']);
+ if (count($virtuals)) {
+ //User has virtual email addresses set up.
+ $url = Horde::applicationUrl('users/index.php', true);
+ header('Location: ' . (Vilma::hasPermission($domain) ? $url : Horde_Util::addParameter($url, 'domain', $domain, false)));
+ } else {
+ //User does not have any virtual email addresses set up.
+ $notification->push(_("No virtual email address set up for this user. You should set up at least one virtual email address if this user is to receive any emails."), 'horde.warning');
+ $url = Horde::applicationUrl('virtuals/edit.php', true);
+ $url = Horde_Util::addParameter($url, array('domain' => $domain, 'stripped_email' => Vilma::stripUser($info['name']), 'virtual_destination' => $info['name']), null, false);
+ header('Location: ' . (Vilma::hasPermission($domain) ? $url : Horde_Util::addParameter($url, 'domain', $domain, false)));
+ }
+ */
+ //exit;
+ }
+}
+
+/* Render the form. */
+require_once 'Horde/Form/Renderer.php';
+$renderer = &new Horde_Form_Renderer();
+
+$main = Horde_Util::bufferOutput(array($form, 'renderActive'), $renderer, $vars, 'edit.php', 'post');
+
+$template->set('main', $main);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/main/main.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/users/index.php,v 1.35 2009/06/10 17:33:45 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ * @author Ben Klang <ben@alkaloid.net>
+ * @author David Cummings <davidcummings@acm.org>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Prefs/CategoryManager.php';
+
+/* Only admin should be using this. */
+if (!Vilma::hasPermission($curdomain)) {
+ Horde::authenticationFailureRedirect();
+}
+
+// Input validation: make sure we have a valid section
+$vars = Horde_Variables::getDefaultVariables();
+$section = $vars->get('section');
+$tmp = Vilma::getUserMgrTypes();
+if (!array_key_exists($section, Vilma::getUserMgrTypes())) {
+ $section = 'all';
+ $vars->set('section', $section);
+}
+$tabs = Vilma::getUserMgrTabs($vars);
+
+$addresses = $vilma_driver->getAddresses($curdomain['domain_name'], $section);
+if (is_a($addresses, 'PEAR_Error')) {
+ $notification->push($addresses);
+ header('Location: ' . Horde::applicationUrl('index.php'));
+}
+
+// Page results
+$page = Horde_Util::getGet('page', 0);
+$perpage = $prefs->getValue('addresses_perpage');
+$url = 'users/index.php';
+$url = Horde_Util::addParameter($url, 'section', $section);
+$pager = new Horde_UI_Pager('page',
+ Horde_Variables::getDefaultVariables(),
+ array('num' => count($addresses),
+ 'url' => $url,
+ 'page_count' => 10,
+ 'perpage' => $perpage));
+$addresses = array_slice($addresses, $page*$perpage, $perpage);
+
+$types = Vilma::getUserMgrTypes();
+foreach ($addresses as $i => $address) {
+ $type = $address['type'];
+ $id = $address['id'];
+ $url = Horde::applicationUrl('users/edit.php');
+ $url = Horde_Util::addParameter($url, 'address', $id);
+ if($type === 'alias') {
+ $addresses[$i]['edit_url'] = '';
+ } else {
+ $addresses[$i]['edit_url'] = Horde_Util::addParameter($url, 'section', $section);
+ }
+ $url = Horde::applicationUrl('users/delete.php');
+ $currentAddress = $address['address'];
+ if(!isset($currentAddress) || empty($currentAddress)) {
+ $currentAddress = $address['user_name'] . $address['domain'];
+ }
+ $url = Horde_Util::addParameter($url, 'address', $currentAddress);
+ //$addresses[$i]['del_url'] = Horde_Util::addParameter($url, 'address', $id);
+ $addresses[$i]['del_url'] = Horde_Util::addParameter($url, 'section', $section);
+ //$url = Horde::applicationUrl('users/edit.php');
+ //$addresses[$i]['view_url'] = Horde_Util::addParameter($url, 'address', $address['user_name']);
+ $url = Horde::applicationUrl('users/edit.php');
+ $url = Horde_Util::addParameter($url, 'address', $id);
+ if($type === 'alias') {
+ $addresses[$i]['view_url'] = '';
+ } else {
+ $addresses[$i]['view_url'] = Horde_Util::addParameter($url, 'section', $section);
+ }
+ $addresses[$i]['type'] = $types[$address['type']]['singular'];
+ $addresses[$i]['status'] = $vilma_driver->getUserStatus($address);
+}
+
+/* Set up the template action links. */
+if ($vilma_driver->isBelowMaxUsers($curdomain['domain_name'])) {
+ $url = Horde::applicationUrl('users/edit.php');
+ $maxusers = '';
+} else {
+ $maxusers = _("Maximum Users");
+}
+
+$url = Horde::applicationUrl('virtuals/edit.php');
+
+/* Set up the template fields. */
+$template->set('addresses', $addresses, true);
+$template->set('maxusers', $maxusers, true);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('tabs', $tabs->render());
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+$template->set('pager', $pager->render());
+
+/* Set up the field list. */
+$images = array('delete' => Horde::img('delete.png', _("Delete User"), '', $registry->getImageDir('horde')),
+ 'edit' => Horde::img('edit.png', _("Edit User"), '', $registry->getImageDir('horde')));
+$template->set('images', $images);
+
+/* Render the page. */
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/users/index.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/virtuals/delete.php,v 1.28 2009/07/08 18:30:04 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Form.php';
+
+/* Only admin should be using this. */
+if (!Horde_Auth::isAdmin()) {
+ Horde::authenticationFailureRedirect();
+}
+
+$vars = Horde_Variables::getDefaultVariables();
+$virtual_id = $vars->get('virtual_id');
+$formname = $vars->get('formname');
+
+$virtual = $vilma_driver->getVirtual($virtual_id);
+$domain = Vilma::stripDomain($virtual['virtual_email']);
+$domain = $vilma_driver->getDomainByName($domain);
+
+$form = new Horde_Form($vars, _("Delete Virtual Email Address"));
+
+/* Set up the form. */
+$form->setButtons(array(_("Delete"), _("Do not delete")));
+$form->addHidden('', 'virtual_id', 'text', false);
+$form->addVariable(sprintf(_("Delete the virtual email address \"%s\" => \"%s\"?"), $virtual['virtual_email'], $virtual['virtual_destination']), 'description', 'description', false);
+
+if ($vars->get('submitbutton') == _("Delete")) {
+ if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ $delete = $vilma_driver->deleteVirtual($info['virtual_id']);
+ if (is_a($delete, 'PEAR_Error')) {
+ Horde::logMessage($delete, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error deleting virtual email. %s."), $delete->getMessage()), 'horde.error');
+ } else {
+ $notification->push(_("Virtual email deleted."), 'horde.success');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('virtuals/index.php'), 'domain_id', $domain['domain_id'], false);
+ header('Location: ' . $url);
+ exit;
+ }
+ }
+} elseif ($vars->get('submitbutton') == _("Do not delete")) {
+ $notification->push(_("Virtual email not deleted."), 'horde.message');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('virtuals/index.php'), 'domain_id', $domain['domain_id'], false);
+ header('Location: ' . $url);
+ exit;
+}
+
+/* Render the form. */
+require_once 'Horde/Form/Renderer.php';
+$renderer = &new Horde_Form_Renderer();
+$main = Horde_Util::bufferOutput(array($form, 'renderActive'), $renderer, $vars, 'delete.php', 'post');
+
+$template->set('main', $main);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/main/main.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/virtuals/edit.php,v 1.32 2009/07/14 18:43:46 selsky Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+require_once 'Horde/Form.php';
+require_once 'Horde/Form/Action.php';
+
+/* Only admin should be using this. */
+if (!Horde_Auth::isAdmin() && !Vilma::isDomainAdmin()) {
+ Horde::authenticationFailureRedirect();
+}
+
+$domain = Vilma::getDomain();
+$vars = Horde_Variables::getDefaultVariables();
+$virtual_id = $vars->get('virtual_id');
+$user = $vars->get('user');
+$formname = $vars->get('formname');
+
+/* Check if a form is being edited. */
+$editing = false;
+if ($virtual_id && !$formname) {
+ $vars = new Horde_Variables($vilma_driver->getVirtual($virtual_id));
+ $editing = true;
+}
+
+if (empty($domain)) {
+ $domain = Vilma::stripDomain($vars->get('virtual_destination'));
+}
+$users = $vilma_driver->getUsers($domain);
+$user_list = array();
+foreach ($users as $user) {
+ $virtual_destination = substr($user['user_name'], 0, strpos($user['user_name'], '@'));
+ $user_list[$user['user_name']] = $virtual_destination;
+}
+
+$form = new Horde_Form($vars, ($editing) ? _("Edit Virtual Email Address") : _("New Virtual Email Address"));
+
+/* Set up the form. */
+$form->setButtons(true, true);
+$form->addHidden('', 'virtual_id', 'int', false);
+$form->addHidden('', 'domain', 'text', false);
+$form->addVariable(_("Virtual Email"), 'stripped_email', 'text', true, false, sprintf(_("Enter a virtual email address @%s and then indicate below where mail sent to that address is to be delivered. The address must begin with an alphanumerical character, it must contain only alphanumerical and '._-' characters, and must end with an alphanumerical character."), $domain), array('~^[a-zA-Z0-9]{1,1}[a-zA-Z0-9._-]*[a-zA-Z0-9]$~'));
+$var = &$form->addVariable(_("Destination type"), 'destination_type', 'enum',
+ true, false, null,
+ array(array('local' => _("Local user"),
+ 'remote' => _("Remote address"))));
+$action = Horde_Form_Action::factory('reload');
+$var->setAction($action);
+if ($vars->get('destination_type') == 'remote') {
+ $form->addVariable(_("Remote e-mail address"), 'virtual_destination',
+ 'email', true, false);
+} else {
+ $form->addVariable(_("Destination"), 'virtual_destination', 'enum',
+ true, false, null, array($user_list, true));
+}
+
+if ($form->validate($vars)) {
+ $form->getInfo($vars, $info);
+ $info['stripped_email'] = Horde_String::lower($info['stripped_email']);
+ if ($info['destination_type'] == 'remote') {
+ $info['virtual_destination'] = Horde_String::lower($info['virtual_destination']);
+ }
+ $virtual_id = $vilma_driver->saveVirtual($info, $domain);
+ if (is_a($virtual_id, 'PEAR_Error')) {
+ Horde::logMessage($virtual_id, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $notification->push(sprintf(_("Error saving virtual email. %s."), $virtual_id->getMessage()), 'horde.error');
+ } else {
+ $notification->push(_("Virtual email saved."), 'horde.success');
+ $url = Horde::applicationUrl('virtuals/index.php', true);
+ header('Location: ' . Horde_Util::addParameter($url, 'user', $info['virtual_destination'], false));
+ exit;
+ }
+}
+
+/* Render the form. */
+require_once 'Horde/Form/Renderer.php';
+$renderer = new Horde_Form_Renderer();
+$main = Horde_Util::bufferOutput(array($form, 'renderActive'), $renderer, $vars, 'edit.php', 'post');
+
+$template->set('main', $main);
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/main/main.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';
--- /dev/null
+<?php
+/**
+ * $Horde: vilma/virtuals/index.php,v 1.26 2009/07/08 18:30:04 slusarz Exp $
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSD). If you did not
+ * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE.
+ *
+ * @author Marko Djukic <marko@oblo.com>
+ */
+
+@define('VILMA_BASE', dirname(__FILE__) . '/..');
+require_once VILMA_BASE . '/lib/base.php';
+
+/* Only admin should be using this. */
+if (!Horde_Auth::isAdmin() && !Vilma::isDomainAdmin()) {
+ Horde::authenticationFailureRedirect();
+}
+
+$user = Horde_Util::getFormData('user');
+if (!empty($user)) {
+ $virtuals = $vilma_driver->getVirtuals($user);
+ $domain = Vilma::stripDomain($user);
+} else {
+ $domain = Vilma::getDomain();
+ $virtuals = $vilma_driver->getVirtuals($domain);
+}
+
+if (is_a($virtuals, 'PEAR_Error')) {
+ $notification->push($virtuals);
+ header('Location: ' . Horde::applicationUrl('index.php'));
+}
+
+foreach ($virtuals as $id => $virtual) {
+ $url = Horde::applicationUrl('virtuals/edit.php');
+ $virtuals[$id]['edit_url'] = Horde_Util::addParameter($url, 'virtual_id', $virtual['virtual_id']);
+ $url = Horde::applicationUrl('virtuals/delete.php');
+ $virtuals[$id]['del_url'] = Horde_Util::addParameter($url, 'virtual_id', $virtual['virtual_id']);
+}
+
+$template->set('virtuals', $virtuals, true);
+
+/* Set up the template action links. */
+$actions = array();
+$url = Horde::applicationUrl('virtuals/edit.php');
+$actions['new_url'] = (Vilma::isDomainAdmin() ? $url : Horde_Util::addParameter($url, 'domain', $domain));
+$actions['new_text'] = _("New Virtual Email");
+$url = Horde::applicationUrl('users/index.php');
+$actions['users_url'] = (Vilma::isDomainAdmin() ? $url : Horde_Util::addParameter($url, 'domain', $domain));
+$actions['users_text'] = _("Users");
+$template->set('actions', $actions);
+
+/* Set up the field list. */
+$images = array('delete' => Horde::img('delete.png', _("Delete User"), '', $registry->getImageDir('horde')),
+ 'edit' => Horde::img('edit.png', _("Edit User"), '', $registry->getImageDir('horde')));
+$template->set('images', $images);
+
+$template->set('menu', Vilma::getMenu('string'));
+$template->set('notify', Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')));
+
+/* Render the page. */
+require VILMA_TEMPLATES . '/common-header.inc';
+echo $template->fetch(VILMA_TEMPLATES . '/virtuals/index.html');
+require $registry->get('templates', 'horde') . '/common-footer.inc';