move all tables to new api and update api to 16.1

This commit is contained in:
Ralf Becker 2016-04-02 19:55:08 +00:00
parent adb748d6e7
commit 2baf654e14
35 changed files with 2755 additions and 1289 deletions

View File

@ -1,19 +0,0 @@
<?php
/**************************************************************************\
* eGroupWare *
* http://www.egroupware.org *
* Written by Mark Peters <skeeter@phpgroupware.org> *
* -------------------------------------------- *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
\**************************************************************************/
/* $Id$ */
if((int)$GLOBALS['hook_values']['account_id'] > 0)
{
$GLOBALS['egw']->accounts->delete((int)$GLOBALS['hook_values']['account_id']);
$GLOBALS['egw']->acl->delete_account((int)$GLOBALS['hook_values']['account_id']);
}

View File

@ -1,66 +0,0 @@
<?php
/**************************************************************************\
* eGroupWare - Admin *
* http://www.egroupware.org *
* This application written by Miles Lott <milos@groupwhere.org> *
* This file is ported to the topmenu hook by Pim Snel pim@lingewoud.nl *
* -------------------------------------------- *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; either version 2 of the License, or (at your *
* option) any later version. *
\**************************************************************************/
/* $Id: hook_after_navbar.inc.php 20071 2005-12-01 20:21:16Z ralfbecker $ */
/* Check currentapp and API upgrade status */
if( (isset($GLOBALS['egw_info']['server']['checkappversions']) && $GLOBALS['egw_info']['server']['checkappversions']))
{
if((isset($GLOBALS['egw_info']['user']['apps']['admin']) &&
$GLOBALS['egw_info']['user']['apps']['admin']) ||
$GLOBALS['egw_info']['server']['checkappversions'] == 'All')
{
$_returnhtml = array();
$app_name = $GLOBALS['egw_info']['flags']['currentapp'];
$GLOBALS['egw']->db->query("SELECT app_name,app_version FROM egw_applications WHERE app_name='$app_name' OR app_name='phpgwapi'",__LINE__,__FILE__);
while($GLOBALS['egw']->db->next_record())
{
$_db_version = $GLOBALS['egw']->db->f('app_version');
$app_name = $GLOBALS['egw']->db->f('app_name');
$_versionfile = $GLOBALS['egw']->common->get_app_dir($app_name) . '/setup/setup.inc.php';
if(file_exists($_versionfile))
{
include($_versionfile);
$_file_version = $setup_info[$app_name]['version'];
unset($setup_info);
if(amorethanb($_file_version, $_db_version))
{
if($app_name == 'phpgwapi' )
{
$_returnhtml[$app_name] = lang('The API requires an upgrade');
}
else
{
$_returnhtml[$app_name] = lang('This application requires an upgrade') . ": \n <br />" . lang('Please run setup to become current') . '.' . "\n";
}
}
unset($_file_version);
}
unset($_db_version);
unset($_versionfile);
}
if(count($_returnhtml)>0)
{
$icon_newmsg = $GLOBALS['egw']->common->image('admin','navbar18');
//$link_inbox = $GLOBALS['egw']->link('/index.php','menuaction=messenger.uimessenger.inbox');
$lang_msg = '<p style="text-align: center;">'.implode('<br />',$_returnhtml)."</p>\n";
$GLOBALS['egw']->framework->topmenu_info_icon('admin_new_msg',$icon_newmsg,'',true,$lang_msg);
}
unset($_returnhtml);
unset($_html);
}
}

View File

@ -12,7 +12,7 @@
/* Basic information about this app */
$setup_info['api']['name'] = 'api';
$setup_info['api']['title'] = 'EGroupware API';
$setup_info['api']['version'] = '14.3.907';
$setup_info['api']['version'] = '16.1';
$setup_info['api']['versions']['current_header'] = '1.29';
$setup_info['api']['enable'] = 3;
$setup_info['api']['app_order'] = 1;
@ -22,7 +22,7 @@ $setup_info['api']['maintainer'] = $setup_info['api']['author'] = array(
'email' => 'egroupware-developers@lists.sourceforge.net',
);
/* The tables this app creates
// The tables this app creates
$setup_info['api']['tables'][] = 'egw_config';
$setup_info['api']['tables'][] = 'egw_applications';
$setup_info['api']['tables'][] = 'egw_acl';
@ -31,7 +31,6 @@ $setup_info['api']['tables'][] = 'egw_preferences';
$setup_info['api']['tables'][] = 'egw_access_log';
$setup_info['api']['tables'][] = 'egw_languages';
$setup_info['api']['tables'][] = 'egw_lang';
$setup_info['api']['tables'][] = 'egw_nextid';
$setup_info['api']['tables'][] = 'egw_categories';
$setup_info['api']['tables'][] = 'egw_history_log';
$setup_info['api']['tables'][] = 'egw_async';
@ -45,7 +44,13 @@ $setup_info['api']['tables'][] = 'egw_locks';
$setup_info['api']['tables'][] = 'egw_sqlfs_props';
$setup_info['api']['tables'][] = 'egw_customfields';
$setup_info['api']['tables'][] = 'egw_sharing';
*/
$setup_info['api']['tables'][] = 'egw_mailaccounts';
$setup_info['api']['tables'][] = 'egw_ea_accounts';
$setup_info['api']['tables'][] = 'egw_ea_credentials';
$setup_info['api']['tables'][] = 'egw_ea_identities';
$setup_info['api']['tables'][] = 'egw_ea_valid';
$setup_info['api']['tables'][] = 'egw_ea_notifications';
// hooks used by vfs_home_hooks to manage user- and group-directories for the new stream based VFS
$setup_info['api']['hooks']['addaccount'] = array('EGroupware\\Api\\Vfs\\Hooks::addAccount', 'EGroupware\\Api\\Mail\\Hooks::addaccount');
$setup_info['api']['hooks']['deleteaccount'] = array('EGroupware\\Api\\Vfs\\Hooks::deleteAccount', 'EGroupware\\Api\\Mail\\Hooks::deleteaccount');
@ -59,52 +64,52 @@ $setup_info['api']['hooks']['changepassword'] = 'EGroupware\\Api\\Mail\\Hooks::c
$setup_info['api']['check_install'] = array(
'' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
),
'pear.horde.org/Horde_Imap_Client' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '2.24.2',
),
'pear.horde.org/Horde_Nls' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '2.0.3',
),
'pear.horde.org/Horde_Mail' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '2.1.2',
),
'pear.horde.org/Horde_Smtp' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '1.3.0',
),
'pear.horde.org/Horde_ManageSieve' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '1.0.1',
),
// next 4 are required for TNEF support
'pear.horde.org/Horde_Compress' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '2.0.8',
),
'pear.horde.org/Horde_Icalendar' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '2.0.0',
),
'pear.horde.org/Horde_Mapi' => array(
'func' => 'pear_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
'version' => '1.0.0',
),
'bcmath' => array(
'func' => 'extension_check',
'from' => 'EMailAdmin',
'from' => 'Api/Mail',
),
);

View File

@ -0,0 +1,511 @@
<?php
/**
* EGroupware - API Setup
*
* Current DB schema
*
* @link http://www.egroupware.org
* @package api
* @subpackage setup
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
$phpgw_baseline = array(
'egw_config' => array(
'fd' => array(
'config_app' => array('type' => 'ascii','precision' => '16','nullable' => False),
'config_name' => array('type' => 'ascii','precision' => '32','nullable' => False),
'config_value' => array('type' => 'text')
),
'pk' => array('config_app','config_name'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_applications' => array(
'fd' => array(
'app_id' => array('type' => 'auto','precision' => '4','nullable' => False),
'app_name' => array('type' => 'ascii','precision' => '16','nullable' => False),
'app_enabled' => array('type' => 'int','precision' => '4','nullable' => False),
'app_order' => array('type' => 'int','precision' => '4','nullable' => False),
'app_tables' => array('type' => 'ascii','precision' => '8192','nullable' => False),
'app_version' => array('type' => 'ascii','precision' => '20','nullable' => False,'default' => '0.0'),
'app_icon' => array('type' => 'ascii','precision' => '32'),
'app_icon_app' => array('type' => 'ascii','precision' => '16'),
'app_index' => array('type' => 'ascii','precision' => '64')
),
'pk' => array('app_id'),
'fk' => array(),
'ix' => array(array('app_enabled','app_order')),
'uc' => array('app_name')
),
'egw_acl' => array(
'fd' => array(
'acl_appname' => array('type' => 'ascii','precision' => '16','nullable' => False),
'acl_location' => array('type' => 'ascii','meta' => 'account','precision' => '16','nullable' => False),
'acl_account' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False),
'acl_rights' => array('type' => 'int','precision' => '4'),
'acl_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('acl_id'),
'fk' => array(),
'ix' => array('acl_account',array('acl_location','acl_account'),array('acl_appname','acl_account')),
'uc' => array(array('acl_appname','acl_location','acl_account'))
),
'egw_accounts' => array(
'fd' => array(
'account_id' => array('type' => 'auto','meta' => 'account-abs','nullable' => False),
'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False),
'account_pwd' => array('type' => 'varchar','precision' => '128','nullable' => False),
'account_lastlogin' => array('type' => 'int','precision' => '4'),
'account_lastloginfrom' => array('type' => 'ascii','precision' => '48','comment' => 'ip'),
'account_lastpwd_change' => array('type' => 'int','precision' => '4'),
'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'),
'account_expires' => array('type' => 'int','precision' => '4'),
'account_type' => array('type' => 'char','precision' => '1'),
'account_primary_group' => array('type' => 'int','meta' => 'group','precision' => '4','nullable' => False,'default' => '0'),
'account_description' => array('type' => 'varchar','precision' => '255','comment' => 'group description')
),
'pk' => array('account_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('account_lid')
),
'egw_preferences' => array(
'fd' => array(
'preference_owner' => array('type' => 'int','meta' => 'account-prefs','precision' => '4','nullable' => False),
'preference_app' => array('type' => 'ascii','precision' => '16','nullable' => False),
'preference_value' => array('type' => 'text','nullable' => False),
'preference_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('preference_id'),
'fk' => array(),
'ix' => array(),
'uc' => array(array('preference_owner','preference_app'))
),
'egw_access_log' => array(
'fd' => array(
'sessionid' => array('type' => 'auto','nullable' => False,'comment' => 'primary key'),
'loginid' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'username used to login'),
'ip' => array('type' => 'ascii','precision' => '48','nullable' => False,'comment' => 'ip of user'),
'li' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'TS if login'),
'lo' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'TD of logout'),
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0','comment' => 'numerical account id'),
'session_dla' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'TS of last user action'),
'session_action' => array('type' => 'ascii','precision' => '64','comment' => 'menuaction or path of last user action'),
'session_php' => array('type' => 'ascii','precision' => '64','nullable' => False,'comment' => 'php session-id or error-message'),
'notification_heartbeat' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'TS of last notification request'),
'user_agent' => array('type' => 'ascii','precision' => '255','comment' => 'User-agent of browser/device')
),
'pk' => array('sessionid'),
'fk' => array(),
'ix' => array('li','lo','session_dla','session_php','notification_heartbeat',array('account_id','ip','li'),array('account_id','loginid','li')),
'uc' => array()
),
'egw_languages' => array(
'fd' => array(
'lang_id' => array('type' => 'ascii','precision' => '5','nullable' => False),
'lang_name' => array('type' => 'varchar','precision' => '50','nullable' => False)
),
'pk' => array('lang_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_lang' => array(
'fd' => array(
'lang' => array('type' => 'varchar','precision' => '5','nullable' => False,'default' => ''),
'app_name' => array('type' => 'ascii','precision' => '16','nullable' => False,'default' => 'common'),
'message_id' => array('type' => 'ascii','precision' => '128','nullable' => False,'default' => ''),
'content' => array('type' => 'varchar','precision' => '8192'),
'lang_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('lang_id'),
'fk' => array(),
'ix' => array(),
'uc' => array(array('lang','app_name','message_id'))
),
'egw_categories' => array(
'fd' => array(
'cat_id' => array('type' => 'auto','meta' => 'category','precision' => '4','nullable' => False),
'cat_main' => array('type' => 'int','meta' => 'category','precision' => '4','nullable' => False,'default' => '0'),
'cat_parent' => array('type' => 'int','meta' => 'category','precision' => '4','nullable' => False,'default' => '0'),
'cat_level' => array('type' => 'int','precision' => '2','nullable' => False,'default' => '0'),
'cat_owner' => array('type' => 'ascii','meta' => 'account-commasep','precision' => '255','nullable' => False,'default' => '0'),
'cat_access' => array('type' => 'ascii','precision' => '7'),
'cat_appname' => array('type' => 'ascii','precision' => '16','nullable' => False),
'cat_name' => array('type' => 'varchar','precision' => '150','nullable' => False),
'cat_description' => array('type' => 'varchar','precision' => '255','nullable' => False),
'cat_data' => array('type' => 'varchar','precision' => '8192'),
'last_mod' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False)
),
'pk' => array('cat_id'),
'fk' => array(),
'ix' => array(array('cat_appname','cat_owner','cat_parent','cat_level')),
'uc' => array()
),
'egw_history_log' => array(
'fd' => array(
'history_id' => array('type' => 'auto','precision' => '4','nullable' => False),
'history_record_id' => array('type' => 'int','precision' => '4','nullable' => False),
'history_appname' => array('type' => 'ascii','precision' => '16','nullable' => False),
'history_owner' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False),
'history_status' => array('type' => 'varchar','precision' => '32','nullable' => False),
'history_new_value' => array('type' => 'text','nullable' => False),
'history_timestamp' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp'),
'history_old_value' => array('type' => 'text','nullable' => False),
'sessionid' => array('type' => 'int','precision' => '4','comment' => 'primary key to egw_access_log')
),
'pk' => array('history_id'),
'fk' => array(),
'ix' => array(array('history_appname','history_record_id','history_id')),
'uc' => array()
),
'egw_async' => array(
'fd' => array(
'async_id' => array('type' => 'ascii','precision' => '64','nullable' => False),
'async_next' => array('type' => 'int','meta' => 'timestamp','precision' => '4','nullable' => False,'comment' => 'timestamp of next run'),
'async_times' => array('type' => 'ascii','precision' => '255','nullable' => False,'comment' => 'serialized array with values for keys hour,min,day,month,year'),
'async_method' => array('type' => 'ascii','precision' => '80','nullable' => False,'comment' => 'app.class.method class::method to execute'),
'async_data' => array('type' => 'varchar','precision' => '8192','nullable' => False,'comment' => 'serialized array with data to pass to method'),
'async_account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0','comment' => 'creator of job'),
'async_auto_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('async_auto_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('async_id')
),
'egw_links' => array(
'fd' => array(
'link_id' => array('type' => 'auto','nullable' => False),
'link_app1' => array('type' => 'ascii','precision' => '16','nullable' => False),
'link_id1' => array('type' => 'ascii','meta' => array("link_app1='home-accounts'" => 'account'),'precision' => '64','nullable' => False),
'link_app2' => array('type' => 'ascii','precision' => '16','nullable' => False),
'link_id2' => array('type' => 'ascii','meta' => array("link_app2='home-accounts'" => 'account'),'precision' => '64','nullable' => False),
'link_remark' => array('type' => 'varchar','precision' => '100'),
'link_lastmod' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False),
'link_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False),
'deleted' => array('type' => 'timestamp')
),
'pk' => array('link_id'),
'fk' => array(),
'ix' => array('deleted',array('link_app1','link_id1','link_lastmod'),array('link_app2','link_id2','link_lastmod')),
'uc' => array()
),
'egw_addressbook' => array(
'fd' => array(
'contact_id' => array('type' => 'auto','nullable' => False),
'contact_tid' => array('type' => 'char','precision' => '1','default' => 'n'),
'contact_owner' => array('type' => 'int','meta' => 'account','precision' => '8','nullable' => False,'comment' => 'account or group id of the adressbook'),
'contact_private' => array('type' => 'int','precision' => '1','default' => '0','comment' => 'privat or personal'),
'cat_id' => array('type' => 'ascii','meta' => 'category','precision' => '255','comment' => 'Category(s)'),
'n_family' => array('type' => 'varchar','precision' => '64','comment' => 'Family name'),
'n_given' => array('type' => 'varchar','precision' => '64','comment' => 'Given Name'),
'n_middle' => array('type' => 'varchar','precision' => '64'),
'n_prefix' => array('type' => 'varchar','precision' => '64','comment' => 'Prefix'),
'n_suffix' => array('type' => 'varchar','precision' => '64','comment' => 'Suffix'),
'n_fn' => array('type' => 'varchar','precision' => '128','comment' => 'Full name'),
'n_fileas' => array('type' => 'varchar','precision' => '255','comment' => 'sort as'),
'contact_bday' => array('type' => 'varchar','precision' => '12','comment' => 'Birtday'),
'org_name' => array('type' => 'varchar','precision' => '128','comment' => 'Organisation'),
'org_unit' => array('type' => 'varchar','precision' => '64','comment' => 'Department'),
'contact_title' => array('type' => 'varchar','precision' => '64','comment' => 'jobtittle'),
'contact_role' => array('type' => 'varchar','precision' => '64','comment' => 'role'),
'contact_assistent' => array('type' => 'varchar','precision' => '64','comment' => 'Name of the Assistent (for phone number)'),
'contact_room' => array('type' => 'varchar','precision' => '64','comment' => 'room'),
'adr_one_street' => array('type' => 'varchar','precision' => '64','comment' => 'street (business)'),
'adr_one_street2' => array('type' => 'varchar','precision' => '64','comment' => 'street (business) - 2. line'),
'adr_one_locality' => array('type' => 'varchar','precision' => '64','comment' => 'city (business)'),
'adr_one_region' => array('type' => 'varchar','precision' => '64','comment' => 'region (business)'),
'adr_one_postalcode' => array('type' => 'varchar','precision' => '64','comment' => 'postalcode (business)'),
'adr_one_countryname' => array('type' => 'varchar','precision' => '64','comment' => 'countryname (business)'),
'contact_label' => array('type' => 'text','comment' => 'currently not used'),
'adr_two_street' => array('type' => 'varchar','precision' => '64','comment' => 'street (private)'),
'adr_two_street2' => array('type' => 'varchar','precision' => '64','comment' => 'street (private) - 2. line'),
'adr_two_locality' => array('type' => 'varchar','precision' => '64','comment' => 'city (private)'),
'adr_two_region' => array('type' => 'varchar','precision' => '64','comment' => 'region (private)'),
'adr_two_postalcode' => array('type' => 'varchar','precision' => '64','comment' => 'postalcode (private)'),
'adr_two_countryname' => array('type' => 'varchar','precision' => '64','comment' => 'countryname (private)'),
'tel_work' => array('type' => 'varchar','precision' => '40','comment' => 'phone-number (business)'),
'tel_cell' => array('type' => 'varchar','precision' => '40','comment' => 'mobil phone (business)'),
'tel_fax' => array('type' => 'varchar','precision' => '40','comment' => 'fax-number (business)'),
'tel_assistent' => array('type' => 'varchar','precision' => '40','comment' => 'phone-number assistent'),
'tel_car' => array('type' => 'varchar','precision' => '40'),
'tel_pager' => array('type' => 'varchar','precision' => '40','comment' => 'pager'),
'tel_home' => array('type' => 'varchar','precision' => '40','comment' => 'phone-number (private)'),
'tel_fax_home' => array('type' => 'varchar','precision' => '40','comment' => 'fax-number (private)'),
'tel_cell_private' => array('type' => 'varchar','precision' => '40','comment' => 'mobil phone (private)'),
'tel_other' => array('type' => 'varchar','precision' => '40','comment' => 'other phone'),
'tel_prefer' => array('type' => 'varchar','precision' => '32','comment' => 'prefered phone-number'),
'contact_email' => array('type' => 'varchar','precision' => '128','comment' => 'email address (business)'),
'contact_email_home' => array('type' => 'varchar','precision' => '128','comment' => 'email address (private)'),
'contact_url' => array('type' => 'varchar','precision' => '128','comment' => 'website (business)'),
'contact_url_home' => array('type' => 'varchar','precision' => '128','comment' => 'website (private)'),
'contact_freebusy_uri' => array('type' => 'ascii','precision' => '128','comment' => 'freebusy-url for calendar of the contact'),
'contact_calendar_uri' => array('type' => 'ascii','precision' => '128','comment' => 'url for users calendar - currently not used'),
'contact_note' => array('type' => 'varchar','precision' => '8192','comment' => 'notes field'),
'contact_tz' => array('type' => 'varchar','precision' => '8','comment' => 'timezone difference'),
'contact_geo' => array('type' => 'ascii','precision' => '32','comment' => 'currently not used'),
'contact_pubkey' => array('type' => 'ascii','precision' => '16384','comment' => 'public key'),
'contact_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'timestamp of the creation'),
'contact_creator' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'account id of the creator'),
'contact_modified' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'timestamp of the last modified'),
'contact_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'account id of the last modified'),
'contact_jpegphoto' => array('type' => 'blob','comment' => 'photo of the contact (attachment)'),
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'account id'),
'contact_etag' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'etag of the changes'),
'contact_uid' => array('type' => 'ascii','precision' => '128','comment' => 'unique id of the contact'),
'adr_one_countrycode' => array('type' => 'ascii','precision' => '2','comment' => 'countrycode (business)'),
'adr_two_countrycode' => array('type' => 'ascii','precision' => '2','comment' => 'countrycode (private)'),
'carddav_name' => array('type' => 'ascii','precision' => '128','comment' => 'name part of CardDAV URL, if specified by client')
),
'pk' => array('contact_id'),
'fk' => array(),
'ix' => array('contact_owner','cat_id','n_fileas','contact_modified','contact_uid','carddav_name',array('n_family','n_given'),array('n_given','n_family'),array('org_name','n_family','n_given')),
'uc' => array('account_id')
),
'egw_addressbook_extra' => array(
'fd' => array(
'contact_id' => array('type' => 'int','precision' => '4','nullable' => False),
'contact_owner' => array('type' => 'int','meta' => 'account','precision' => '8'),
'contact_name' => array('type' => 'varchar','meta' => 'cfname','precision' => '64','nullable' => False,'comment' => 'custom-field name'),
'contact_value' => array('type' => 'varchar','meta' => 'cfvalue','precision' => '16384','comment' => 'custom-field value'),
'contact_extra_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('contact_extra_id'),
'fk' => array(),
'ix' => array('contact_name',array('contact_id','contact_name')),
'uc' => array()
),
'egw_addressbook_lists' => array(
'fd' => array(
'list_id' => array('type' => 'auto','nullable' => False),
'list_name' => array('type' => 'varchar','precision' => '80','nullable' => False),
'list_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False),
'list_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8'),
'list_creator' => array('type' => 'int','meta' => 'user','precision' => '4'),
'list_uid' => array('type' => 'ascii','precision' => '128'),
'list_carddav_name' => array('type' => 'ascii','precision' => '128'),
'list_etag' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'),
'list_modified' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp'),
'list_modifier' => array('type' => 'int','meta' => 'user','precision' => '4')
),
'pk' => array('list_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('list_uid','list_carddav_name',array('list_owner','list_name'))
),
'egw_addressbook2list' => array(
'fd' => array(
'contact_id' => array('type' => 'int','precision' => '4','nullable' => False),
'list_id' => array('type' => 'int','precision' => '4','nullable' => False),
'list_added' => array('type' => 'int','meta' => 'timestamp','precision' => '8'),
'list_added_by' => array('type' => 'int','meta' => 'user','precision' => '4')
),
'pk' => array('contact_id','list_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_sqlfs' => array(
'fd' => array(
'fs_id' => array('type' => 'auto','nullable' => False),
'fs_dir' => array('type' => 'int','precision' => '4','nullable' => False),
'fs_name' => array('type' => 'varchar','precision' => '200','nullable' => False),
'fs_mode' => array('type' => 'int','precision' => '2','nullable' => False),
'fs_uid' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0'),
'fs_gid' => array('type' => 'int','meta' => 'group-abs','precision' => '4','nullable' => False,'default' => '0'),
'fs_created' => array('type' => 'timestamp','precision' => '8','nullable' => False),
'fs_modified' => array('type' => 'timestamp','precision' => '8','nullable' => False),
'fs_mime' => array('type' => 'ascii','precision' => '96','nullable' => False),
'fs_size' => array('type' => 'int','precision' => '8','nullable' => False),
'fs_creator' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False),
'fs_modifier' => array('type' => 'int','meta' => 'user','precision' => '4'),
'fs_active' => array('type' => 'bool','nullable' => False,'default' => 't'),
'fs_content' => array('type' => 'blob'),
'fs_link' => array('type' => 'varchar','precision' => '255')
),
'pk' => array('fs_id'),
'fk' => array(),
'ix' => array(array('fs_dir','fs_active','fs_name(16)')),
'uc' => array()
),
'egw_locks' => array(
'fd' => array(
'lock_token' => array('type' => 'ascii','precision' => '64','nullable' => False),
'lock_path' => array('type' => 'varchar','precision' => '255','nullable' => False),
'lock_expires' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False),
'lock_owner' => array('type' => 'varchar','precision' => '255'),
'lock_recursive' => array('type' => 'bool','nullable' => False,'default' => '0'),
'lock_write' => array('type' => 'bool','nullable' => False,'default' => '0'),
'lock_exclusive' => array('type' => 'bool','nullable' => False,'default' => '0'),
'lock_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','default' => '0'),
'lock_modified' => array('type' => 'int','meta' => 'timestamp','precision' => '8','default' => '0'),
'lock_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('lock_id'),
'fk' => array(),
'ix' => array('lock_path','lock_expires'),
'uc' => array('lock_token')
),
'egw_sqlfs_props' => array(
'fd' => array(
'fs_id' => array('type' => 'int','precision' => '4','nullable' => False),
'prop_namespace' => array('type' => 'ascii','precision' => '64','nullable' => False),
'prop_name' => array('type' => 'ascii','precision' => '64','nullable' => False),
'prop_value' => array('type' => 'varchar','precision' => '16384'),
'prop_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('prop_id'),
'fk' => array(),
'ix' => array(array('fs_id','prop_namespace','prop_name')),
'uc' => array()
),
'egw_customfields' => array(
'fd' => array(
'cf_id' => array('type' => 'auto','nullable' => False),
'cf_app' => array('type' => 'ascii','precision' => '16','nullable' => False,'comment' => 'app-name cf belongs too'),
'cf_name' => array('type' => 'varchar','precision' => '128','nullable' => False,'comment' => 'internal name'),
'cf_label' => array('type' => 'varchar','precision' => '128','comment' => 'label to display'),
'cf_type' => array('type' => 'varchar','precision' => '64','nullable' => False,'default' => 'text','comment' => 'type of field'),
'cf_type2' => array('type' => 'varchar','precision' => '2048','comment' => 'comma-separated subtypes of app, cf is valid for'),
'cf_help' => array('type' => 'varchar','precision' => '256','comment' => 'helptext'),
'cf_values' => array('type' => 'varchar','precision' => '8096','comment' => 'json object with value label pairs'),
'cf_len' => array('type' => 'int','precision' => '2','comment' => 'length or columns of field'),
'cf_rows' => array('type' => 'int','precision' => '2','comment' => 'rows of field'),
'cf_order' => array('type' => 'int','precision' => '2','comment' => 'order to display fields'),
'cf_needed' => array('type' => 'bool','default' => '0','comment' => 'field is required'),
'cf_private' => array('type' => 'ascii','meta' => 'account-commasep','precision' => '2048','comment' => 'comma-separated account_id'),
'cf_modifier' => array('type' => 'int','meta' => 'account','precision' => '4','comment' => 'last modifier'),
'cf_modified' => array('type' => 'timestamp','default' => 'current_timestamp','comment' => 'last modification time'),
'cf_tab' => array('type' => 'varchar','precision' => '64','comment' => 'tab customfield should be shown')
),
'pk' => array('cf_id'),
'fk' => array(),
'ix' => array(array('cf_app','cf_order')),
'uc' => array(array('cf_app','cf_name'))
),
'egw_sharing' => array(
'fd' => array(
'share_id' => array('type' => 'auto','nullable' => False,'comment' => 'auto-id'),
'share_token' => array('type' => 'ascii','precision' => '64','nullable' => False,'comment' => 'secure token'),
'share_path' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'path to share'),
'share_owner' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'owner of share'),
'share_expires' => array('type' => 'date','comment' => 'expire date of share'),
'share_writable' => array('type' => 'int','precision' => '1','nullable' => False,'default' => '0','comment' => '0=readable, 1=writable'),
'share_with' => array('type' => 'varchar','precision' => '4096','comment' => 'email addresses, comma seperated'),
'share_passwd' => array('type' => 'varchar','precision' => '128','comment' => 'optional password-hash'),
'share_created' => array('type' => 'timestamp','nullable' => False,'comment' => 'creation date'),
'share_last_accessed' => array('type' => 'timestamp','comment' => 'last access of share')
),
'pk' => array('share_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('share_token')
),
'egw_mailaccounts' => array(
'fd' => array(
'mail_id' => array('type' => 'auto','nullable' => False,'comment' => 'the id'),
'account_id' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False,'comment' => 'account id of the owner, can be user AND group'),
'mail_type' => array('type' => 'int','precision' => '1','nullable' => False,'comment' => '0=active, 1=alias, 2=forward, 3=forwardOnly, 4=quota'),
'mail_value' => array('type' => 'ascii','precision' => '128','nullable' => False,'comment' => 'the value (that should be) corresponding to the mail_type')
),
'pk' => array('mail_id'),
'fk' => array(),
'ix' => array('mail_value',array('account_id','mail_type')),
'uc' => array()
),
'egw_ea_accounts' => array(
'fd' => array(
'acc_id' => array('type' => 'auto','nullable' => False),
'acc_name' => array('type' => 'varchar','precision' => '80','comment' => 'description'),
'ident_id' => array('type' => 'int','precision' => '4','nullable' => False,'comment' => 'standard identity'),
'acc_imap_host' => array('type' => 'ascii','precision' => '128','nullable' => False,'comment' => 'imap hostname'),
'acc_imap_ssl' => array('type' => 'int','precision' => '1','nullable' => False,'default' => '0','comment' => '0=none, 1=starttls, 2=tls, 3=ssl, &8=validate certificate'),
'acc_imap_port' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '143','comment' => 'imap port'),
'acc_sieve_enabled' => array('type' => 'bool','default' => '0','comment' => 'sieve enabled'),
'acc_sieve_host' => array('type' => 'ascii','precision' => '128','comment' => 'sieve host, default imap_host'),
'acc_sieve_port' => array('type' => 'int','precision' => '4','default' => '4190'),
'acc_folder_sent' => array('type' => 'varchar','precision' => '128','comment' => 'sent folder'),
'acc_folder_trash' => array('type' => 'varchar','precision' => '128','comment' => 'trash folder'),
'acc_folder_draft' => array('type' => 'varchar','precision' => '128','comment' => 'draft folder'),
'acc_folder_template' => array('type' => 'varchar','precision' => '128','comment' => 'template folder'),
'acc_smtp_host' => array('type' => 'varchar','precision' => '128','comment' => 'smtp hostname'),
'acc_smtp_ssl' => array('type' => 'int','precision' => '1','nullable' => False,'default' => '0','comment' => '0=none, 1=starttls, 2=tls, 3=ssl, &8=validate certificate'),
'acc_smtp_port' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '25','comment' => 'smtp port'),
'acc_smtp_type' => array('type' => 'ascii','precision' => '32','default' => 'emailadmin_smtp','comment' => 'smtp class to use'),
'acc_imap_type' => array('type' => 'ascii','precision' => '32','default' => 'emailadmin_imap','comment' => 'imap class to use'),
'acc_imap_logintype' => array('type' => 'ascii','precision' => '20','comment' => 'standard, vmailmgr, admin, uidNumber'),
'acc_domain' => array('type' => 'varchar','precision' => '100','comment' => 'domain name'),
'acc_further_identities' => array('type' => 'bool','nullable' => False,'default' => '1','comment' => '0=no, 1=yes'),
'acc_user_editable' => array('type' => 'bool','nullable' => False,'default' => '1','comment' => '0=no, 1=yes'),
'acc_sieve_ssl' => array('type' => 'int','precision' => '1','default' => '1','comment' => '0=none, 1=starttls, 2=tls, 3=ssl, &8=validate certificate'),
'acc_modified' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp'),
'acc_modifier' => array('type' => 'int','meta' => 'user','precision' => '4'),
'acc_smtp_auth_session' => array('type' => 'bool','comment' => '0=no, 1=yes, use username/pw from current user'),
'acc_folder_junk' => array('type' => 'varchar','precision' => '128','comment' => 'junk folder'),
'acc_imap_default_quota' => array('type' => 'int','precision' => '4','comment' => 'default quota, if no user specific one set'),
'acc_imap_timeout' => array('type' => 'int','precision' => '2','comment' => 'timeout for imap connection'),
'acc_user_forward' => array('type' => 'bool','default' => '0','comment' => 'allow user to define forwards')
),
'pk' => array('acc_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_ea_credentials' => array(
'fd' => array(
'cred_id' => array('type' => 'auto','nullable' => False),
'acc_id' => array('type' => 'int','precision' => '4','nullable' => False,'comment' => 'into egw_ea_accounts'),
'cred_type' => array('type' => 'int','precision' => '1','nullable' => False,'comment' => '&1=imap, &2=smtp, &4=admin'),
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'account_id or 0=all'),
'cred_username' => array('type' => 'varchar','precision' => '80','nullable' => False,'comment' => 'username'),
'cred_password' => array('type' => 'varchar','precision' => '80','comment' => 'password encrypted'),
'cred_pw_enc' => array('type' => 'int','precision' => '1','default' => '0','comment' => '0=not, 1=user pw, 2=system')
),
'pk' => array('cred_id'),
'fk' => array(),
'ix' => array(),
'uc' => array(array('acc_id','account_id','cred_type'))
),
'egw_ea_identities' => array(
'fd' => array(
'ident_id' => array('type' => 'auto','nullable' => False),
'acc_id' => array('type' => 'int','precision' => '4','nullable' => False,'comment' => 'for which account'),
'ident_realname' => array('type' => 'varchar','precision' => '128','nullable' => False,'comment' => 'real name'),
'ident_email' => array('type' => 'varchar','precision' => '128','comment' => 'email address'),
'ident_org' => array('type' => 'varchar','precision' => '128','comment' => 'organisation'),
'ident_signature' => array('type' => 'text','comment' => 'signature text'),
'account_id' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False,'default' => '0','comment' => '0=all users of give mail account'),
'ident_name' => array('type' => 'varchar','precision' => '128','comment' => 'name of identity to display')
),
'pk' => array('ident_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_ea_valid' => array(
'fd' => array(
'acc_id' => array('type' => 'int','precision' => '4','nullable' => False),
'account_id' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False)
),
'pk' => array(),
'fk' => array(),
'ix' => array(array('account_id','acc_id')),
'uc' => array(array('acc_id','account_id'))
),
'egw_ea_notifications' => array(
'fd' => array(
'notif_id' => array('type' => 'auto','nullable' => False),
'acc_id' => array('type' => 'int','precision' => '4','nullable' => False,'comment' => 'mail account'),
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'user account'),
'notif_folder' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'folder name')
),
'pk' => array('notif_id'),
'fk' => array(),
'ix' => array(array('account_id','acc_id')),
'uc' => array()
),
);

View File

@ -86,7 +86,6 @@ class Config
{
if (is_array($this->config_data))
{
self::$db->lock(array(config::TABLE));
foreach($this->config_data as $name => $value)
{
self::save_value($name, $value, $this->appname, false);
@ -99,7 +98,6 @@ class Config
//self::$db->delete(config::TABLE,array('config_app'=>$this->appname,'config_name'=>$name),__LINE__,__FILE__);
}
}
self::$db->unlock();
if ($this->appname == 'phpgwapi' && method_exists($GLOBALS['egw'],'invalidate_session_cache')) // egw object in setup is limited
{

View File

@ -15,9 +15,6 @@ namespace EGroupware\Api\Contacts;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi
use common; // common::generate_uid
/**
* Contacts - SQL storage
*/
@ -72,10 +69,10 @@ class Sql extends Api\Storage
*/
function __construct(Api\Db $db=null)
{
parent::__construct('phpgwapi', 'egw_addressbook', self::EXTRA_TABLE,
parent::__construct('api', 'egw_addressbook', self::EXTRA_TABLE,
'contact_', '_name', '_value', '_id', $db);
// Get custom fields from addressbook instead of phpgwapi
// Get custom fields from addressbook instead of api
$this->customfields = Api\Storage\Customfields::get('addressbook');
if ($GLOBALS['egw_info']['server']['account_repository'])
@ -599,7 +596,7 @@ class Sql extends Api\Storage
$update = array();
if (!isset($data['list_uid']))
{
$update['list_uid'] = $data['list_uid'] = common::generate_uid('addresbook-lists', $list_id);
$update['list_uid'] = $data['list_uid'] = Api\CalDAV::generate_uid('addresbook-lists', $list_id);
}
if (!isset($data['list_carddav_name']))
{
@ -766,7 +763,7 @@ class Sql extends Api\Storage
// enforce a minium uid strength
if (is_array($contact) && (!isset($contact['uid'])
|| strlen($contact['uid']) < $minimum_uid_length)) {
parent::update(array('uid' => common::generate_uid('addressbook',$contact['id'])));
parent::update(array('uid' => Api\CalDAV::generate_uid('addressbook',$contact['id'])));
}
return $contact;
}
@ -818,7 +815,7 @@ class Sql extends Api\Storage
// enforce a minium uid strength
if (!isset($this->data['uid']) || strlen($this->data['uid']) < $minimum_uid_length)
{
$update['uid'] = common::generate_uid('addressbook',$this->data['id']);
$update['uid'] = Api\CalDAV::generate_uid('addressbook',$this->data['id']);
//echo "<p>set uid={$this->data['uid']}, etag={$this->data['etag']}</p>";
}
// set carddav_name, if not given by caller

View File

@ -263,8 +263,8 @@ class Storage
}
if ($this->contact_repository == 'sql' || $this->contact_repository == 'sql-ldap')
{
$tda2list = $this->db->get_table_definitions('phpgwapi','egw_addressbook2list');
$tdlists = $this->db->get_table_definitions('phpgwapi','egw_addressbook_lists');
$tda2list = $this->db->get_table_definitions('api','egw_addressbook2list');
$tdlists = $this->db->get_table_definitions('api','egw_addressbook_lists');
$this->distributionlist_tabledef = array('fd' => array(
$this->distri_id => $tda2list['fd'][$this->distri_id],
$this->distri_owner => $tdlists['fd'][$this->distri_owner],
@ -872,7 +872,7 @@ class Storage
*/
function get_fields($type='all',$contact_id=null,$owner=null)
{
$def = $this->db->get_table_definitions('phpgwapi','egw_addressbook');
$def = $this->db->get_table_definitions('api','egw_addressbook');
$all_fields = array();
foreach(array_keys($def['fd']) as $field)

View File

@ -992,11 +992,10 @@ class Db
echo "<p>db::index_names() not yet implemented for db-type '$this->Type'</p>\n";
return $indices;
}
$this->query("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relkind ='i' ORDER BY relname");
while ($this->next_record())
foreach($this->query("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relkind ='i' ORDER BY relname") as $row)
{
$indices[] = array(
'index_name' => $this->f(0),
'index_name' => $row[0],
'tablespace_name' => $this->Database,
'database' => $this->Database,
);
@ -1541,7 +1540,7 @@ class Db
* Application name used by the API
*
*/
const API_APPNAME = 'phpgwapi';
const API_APPNAME = 'api';
/**
* Default app, if no app specified in select, insert, delete, ...
*
@ -1559,6 +1558,9 @@ class Db
*/
function set_app($app)
{
// ease the transition to api
if ($app == 'phpgwapi') $app = 'api';
if ($this === $GLOBALS['egw']->db && $app != self::API_APPNAME)
{
// prevent that anyone switches the global db object to an other app
@ -1581,6 +1583,9 @@ class Db
*/
function get_table_definitions($app=False,$table=False)
{
// ease the transition to api
if ($app === 'phpgwapi') $app = 'api';
static $all_app_data = array();
if ($app === true && $table)
{
@ -1710,8 +1715,7 @@ class Db
}
// fall through !!!
default:
$this->select($table,'count(*)',$where,$line,$file);
if ($this->next_record() && $this->f(0))
if ($this->select($table,'count(*)',$where,$line,$file)->fetchColumn())
{
return !!$this->update($table,$data,$where,$line,$file,$app,$use_prepared_statement,$table_def);
}

View File

@ -118,41 +118,23 @@ class Backup
{
if ($GLOBALS['egw_setup']->config_table && $GLOBALS['egw_setup']->table_exist(array($GLOBALS['egw_setup']->config_table)))
{
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_dir'",__LINE__,__FILE__);
$this->db->next_record();
if (!($this->backup_dir = $this->db->f(0)))
{
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='files_dir'",__LINE__,__FILE__);
$this->db->next_record();
$this->backup_dir = $this->db->f(0).'/db_backup';
}
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='files_dir'",__LINE__,__FILE__);
$this->db->next_record();
if (!($this->files_dir = $this->db->f(0)))
if (!($this->files_dir = $this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='files_dir'",__LINE__,__FILE__)->fetchColumn()))
{
error_log(__METHOD__."->"."No files Directory set/found");
}
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='system_charset'",__LINE__,__FILE__);
$this->db->next_record();
$this->charset = $this->db->f(0);
if (!$this->charset)
if (!($this->backup_dir = $this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_dir'",__LINE__,__FILE__)->fetchColumn()))
{
$this->db->query("SELECT content FROM {$GLOBALS['egw_setup']->lang_table} WHERE message_id='charset' AND app_name='common' AND lang!='en'",__LINE__,__FILE__);
$this->db->next_record();
$this->charset = $this->db->f(0);
$this->backup_dir = $this->files_dir.'/db_backup';
}
$this->db->select($GLOBALS['egw_setup']->applications_table,'app_version',array('app_name'=>'phpgwapi'),__LINE__,__FILE__);
$this->api_version = $this->db->next_record() ? $this->db->f(0) : false;
/* Backup settings */
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_mincount'",__LINE__,__FILE__);
$this->db->next_record();
$this->backup_mincount = $this->db->f(0);
$this->charset = $this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='system_charset'",__LINE__,__FILE__)->fetchColumn();
$this->api_version = $this->db->select($GLOBALS['egw_setup']->applications_table,'app_version',array('app_name'=>array('api','phpgwapi')),
__LINE__,__FILE__,0,'ORDER BY app_name ASC')->fetchColumn();
// Backup settings
$this->backup_mincount = $this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_mincount'",__LINE__,__FILE__)->fetchColumn();
// backup files too
$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_files'",__LINE__,__FILE__);
$this->db->next_record();
$this->backup_files = (bool)$this->db->f(0);
$this->backup_files = (bool)$this->db->query("SELECT config_value FROM {$GLOBALS['egw_setup']->config_table} WHERE config_app='phpgwapi' AND config_name='backup_files'",__LINE__,__FILE__)->fetchColumn();
}
if (!$this->charset) $this->charset = 'iso-8859-1';
if (!$this->charset) $this->charset = 'utf-8';
}
else // called from eGW
{
@ -163,9 +145,9 @@ class Backup
$this->files_dir = $GLOBALS['egw_info']['server']['files_dir'];
$this->backup_mincount = $GLOBALS['egw_info']['server']['backup_mincount'];
$this->backup_files = $GLOBALS['egw_info']['server']['backup_files'];
$this->charset = $GLOBALS['egw']->translation->charset();
$this->charset = Api\Translation::charset();
$this->api_version = $GLOBALS['egw_info']['apps']['phpgwapi']['version'];
$this->api_version = $GLOBALS['egw_info']['apps'][isset($GLOBALS['egw_info']['apps']['api'])?'api':'phpgwapi']['version'];
}
// Set a default value if not set.
if (!isset($this->backup_mincount))

View File

@ -204,7 +204,7 @@ class Hooks
*
* @param boolan $force_rescan =false true: do not use instance cache
*/
protected static function read($force_rescan=false)
public static function read($force_rescan=false)
{
//$starttime = microtime(true);
if ($force_rescan) Cache::unsetInstance(__CLASS__, 'locations');

View File

@ -181,6 +181,9 @@ class Base
*/
function __construct($app='',$table='',Api\Db $db=null,$column_prefix='',$no_clone=false,$timestamp_type=null)
{
// ease the transition to api
if ($app == 'phpgwapi') $app = 'api';
if ($no_clone)
{
$this->db = is_object($db) ? $db : $GLOBALS['egw']->db;

View File

@ -154,11 +154,8 @@ class module_calendar_month extends Module
$site_urls[] = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['SERVER_ADDR'] . $sitemgr_path;
$site_urls[] = $site_url = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . $sitemgr_path;
$GLOBALS['egw']->db->select('egw_sitemgr_sites','anonymous_user,anonymous_passwd,site_id',
array('site_url' => $site_urls),__LINE__,__FILE__,false,'','sitemgr');
$GLOBALS['egw']->db->next_record();
$anon_user = $this->accounts->name2id($GLOBALS['egw']->db->f('anonymous_user'),'account_lid','u');
$anon_user = $this->accounts->name2id($GLOBALS['egw']->db->select('egw_sitemgr_sites','anonymous_user,anonymous_passwd,site_id',
array('site_url' => $site_urls),__LINE__,__FILE__,false,'','sitemgr')->fetchColumn(),'account_lid','u');
}
$anon_groups = $this->accounts->memberships($anon_user,true);

View File

@ -103,7 +103,7 @@ foreach(array(
'etemplate_widget_taglist' => 'Api\\Etemplate\\Widget\\Taglist',
'etemplate_widget_file' => 'Api\\Etemplate\\Widget\\File',
'etemplate_widget_vfs' => 'Api\\Etemplate\\Widget\\Vfs',
'etemplate_requst' => 'Api\\Etemplate\\Request',
'etemplate_request' => 'Api\\Etemplate\\Request',
'nextmatch_widget::category_action' => 'Api\\Etemplate\\Widget\\Nextmatch::category_action',
// so_sql and friends
'so_sql' => 'Api\\Storage\\Base',

71
doc/mail/dbmail.schema Normal file
View File

@ -0,0 +1,71 @@
#
# dbmail-ldap v3 directory schema
#
# Based on the Qmail schema
# Modified for dbmail by Paul Stevens <paul@nfg.nl>
# Modified for dbmail by Lars Kneschke <lkneschke@metaways.de> too
#
# This schema depends on:
# - core.schema
# - cosine.schema
# - nis.schema
#
# This schema conflicts with
# - qmailuser.schema
# Attribute Type Definitions
attributetype ( 1.3.6.1.4.1.12340.6.2.1.1 NAME 'mailQuota'
DESC 'The amount of space the user can use until all further messages get bounced.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.2 NAME 'mailForwardingAddress'
DESC 'Address(es) to forward all incoming messages to.'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.3 NAME 'mailHost'
DESC 'Name or address of the MTA host to use for recipient'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.4 NAME 'dbmailUID'
DESC 'UID of the user on the mailsystem'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.5 NAME 'dbmailGID'
DESC 'GID of the user on the mailsystem'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.6 NAME 'mailAlternateAddress'
DESC 'Secondary (alias) mailaddresses for the same user'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.7 NAME 'deliveryMode'
DESC 'multi field entries of: normal, forwardonly'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.12340.6.2.1.8 NAME 'accountStatus'
DESC 'The status of a user account: active, disabled'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.12340.6.2.2.1 NAME 'dbmailUser'
DESC 'DBMail-LDAP User' SUP top AUXILIARY
MUST ( uid $ mail )
MAY ( userPassword $ uidNumber $ gidNumber $ mailQuota $ mailForwardingAddress $ mailHost $ mailAlternateAddress $ dbmailUID $ dbmailGID $ deliveryMode $ accountStatus ) )
objectclass ( 1.3.6.1.4.1.12340.6.2.2.2 NAME 'dbmailForwardingAddress'
DESC 'DBMail-LDAP Forwarding Address' SUP top AUXILIARY
MUST ( mail $ mailForwardingAddress ) )

View File

@ -0,0 +1,330 @@
#!/usr/bin/php -Cq
<?php
/**
* EGroupware -checkpasswd for Dovecot and Active Directory
*
* Quota is stored with "quota:" prefix in multivalued proxyAddresses attribute.
* Group-memberships are passed to Dovecot to use them in ACL.
*
* Reads descriptor 3 through end of file and then closes descriptor 3.
* There must be at most 512 bytes of data before end of file.
*
* The information supplied on descriptor 3 is a login name terminated by \0, a password terminated by \0,
* a timestamp terminated by \0, and possibly more data.
* There are no other restrictions on the form of the login name, password, and timestamp.
*
* If the password is unacceptable, checkpassword exits 1. If checkpassword is misused, it may instead exit 2.
* If user is not found, checkpassword exits 3.
* If there is a temporary problem checking the password, checkpassword exits 111.
*
* If the password is acceptable, checkpassword runs prog. prog consists of one or more arguments.
*
* Following enviroment variables are used by Dovecot:
* - SERVICE: contains eg. imap, pop3 or smtp
* - TCPLOCALIP and TCPREMOTEIP: Client socket's IP addresses if available
* Following is document, but does NOT work:
* - MASTER_USER: If master login is attempted. This means that the password contains the master user's password and the normal username contains the user who master wants to log in as.
* Found working:
* - AUTH_LOGIN_USER: If master login is attempted. This means that username/password are from master, AUTH_LOGIN_USER is user master wants to log in as.
*
* Following enviroment variables are used on return:
* - USER: modified user name
* - HOME: mail_home
* - EXTRA: userdb extra fields eg. "system_groups_user=... userdb_quota_rule=*:storage=10000"
*
* @author rb(at)stylite.de
* @copyright (c) 2012-13 by rb(at)stylite.de
* @package emailadmin
* @link http://wiki2.dovecot.org/AuthDatabase/CheckPassword
* @link http://cr.yp.to/checkpwd/interface.html
* @version $Id$
*/
// protect from being called via HTTP
if (php_sapi_name() !== 'cli') die('This is a command line only script!');
// uncomment to write to log-file, otherwise errors go to stderr
//$log = '/var/log/dovecot_checkpassword.log';
//$log_verbose = true; // error's are always logged, set to true to log auth failures and success too
// ldap server settings
$ldap_uri = 'ldaps://10.7.102.13/';
$ldap_base = 'CN=Users,DC=gruene,DC=intern';
$bind_dn = "CN=Administrator,$ldap_base";
//$bind_dn = "Administrator@gruene.intern";
//$bind_pw = 'secret';
$version = 3;
$use_tls = false;
$search_base = $ldap_base;//'o=%d,dc=egroupware';
$passdb_filter = $userdb_filter = '(&(objectCategory=person)(sAMAccountName=%s))';
// %d for domain and %s for username given by Dovecot is set automatic
$user_attrs = array(
'%u' => 'samaccountname', // do NOT remove!
// '%n' => 'uidnumber',
// '%h' => 'mailmessagestore',
'%q' => '{quota:}proxyaddresses',
'%x' => 'dn',
);
$user_name = '%u'; // '%u@%d';
$user_home = '/var/dovecot/imap/gruene/%u'; //'/var/dovecot/imap/%d/%u'; // mailbox location
$extra = array(
'userdb_quota_rule' => '*:bytes=%q',
/* only for director
'proxy' => 'Y',
'nologin' => 'Y',
'nopassword' => 'Y',
*/
);
// get host by not set l attribute
/* only for director
$host_filter = 'o=%d';
$host_base = 'dc=egroupware';
$host_attr = 'l';
$host_default = '10.40.8.200';
*/
// to return Dovecot extra system_groups_user
$group_base = $ldap_base;
$group_filter = '(&(objectCategory=group)(member=%x))';
$group_attr = 'cn';
$group_append = ''; //'@%d';
$master_dn = $bind_dn; //"cn=admin,dc=egroupware";
//$domain_master_dn = "cn=admin,o=%d,dc=egroupware";
ini_set('display_errors',false);
error_reporting(E_ALL & ~E_NOTICE);
if ($log) ini_set('error_log',$log);
if ($_SERVER['argc'] < 2)
{
fwrite(STDERR,"\nUsage: {$_SERVER['argv'][0]} prog-to-exec\n\n");
fwrite(STDERR,"To test run:\n");
fwrite(STDERR,"echo -en 'username\\0000''password\\0000' | {$_SERVER['argv'][0]} env 3<&0 ; echo $?\n");
fwrite(STDERR,"echo -en 'username\\0000' | AUTHORIZED=1 {$_SERVER['argv'][0]} env 3<&0 ; echo $?\n");
fwrite(STDERR,"echo -en '(dovecode-admin@domain|dovecot|cyrus)\\0000''master-password\\0000' | AUTH_LOGIN_USER=username {$_SERVER['argv'][0]} env 3<&0 ; echo $?\n\n");
exit(2);
}
list($username,$password) = explode("\0",file_get_contents('php://fd/3'));
if (isset($_SERVER['AUTH_LOGIN_USER']))
{
$master = $username;
$username = $_SERVER['AUTH_LOGIN_USER'];
}
//error_log("dovecot_checkpassword '{$_SERVER['argv'][1]}': username='$username', password='$password', master='$master'");
$ds = ldap_connect($ldap_uri);
if ($version) ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $version);
if ($use_tls) ldap_start_tls($ds);
if (!@ldap_bind($ds, $bind_dn, $bind_pw))
{
error_log("Can't connect to LDAP server $ldap_uri!");
exit(111); // 111 = temporary problem
}
list(,$domain) = explode('@',$username);
if (preg_match('/^(.*)\.imapc$/',$domain,$matches))
{
$domain = $matches[1];
$username = explode('.', $username);
array_pop($username);
$username = implode('.',$username);
$user_home = '/var/tmp/imapc-%d/%s';
$extra = array(
'userdb_mail' => 'imapc:/var/tmp/imapc-'.$domain.'/'.$username,
//'userdb_imapc_password' => $password,
//'userdb_imapc_host' => 'hugo.de',
);
}
$replace = array(
'%d' => $domain,
'%s' => $username,
);
$base = strtr($search_base, $replace);
if (($passdb_query = !isset($_SERVER['AUTHORIZED']) || $_SERVER['AUTHORIZED'] != 1))
{
$filter = $passdb_filter;
// authenticate with master user/password
// master user name is hardcoded "dovecot", "cyrus" or "dovecot-admin@domain" and mapped currently to cn=admin,[o=domain,]dc=egroupware
if (isset($master))
{
list($n,$d) = explode('@', $master);
if (!($n === 'dovecot-admin' && $d === $domain || in_array($master,array('dovecot','cyrus'))))
{
// no valid master-user for given domain
exit(1);
}
$dn = $d ? strtr($domain_master_dn,array('%d'=>$domain)) : $master_dn;
if (!@ldap_bind($ds, $dn, $password))
{
if ($log_verbose) error_log("Can't bind as '$dn' with password '$password'! Authentication as master '$master' for user '$username' failed!");
exit(111); // 111 = temporary problem
}
if ($log_verbose) error_log("Authentication as master '$master' for user '$username' succeeded!");
$passdb_query = false;
$filter = $userdb_filter;
}
}
else
{
$filter = $userdb_filter;
putenv('AUTHORIZED=2');
}
$filter = strtr($filter, quote($replace));
// remove prefixes eg. "{quota:}proxyaddresses"
$attrs = $user_attrs;
foreach($attrs as &$a) if ($a[0] == '{') list(,$a) = explode('}', $a);
if (!($sr = ldap_search($ds, $base, $filter, array_values($attrs))))
{
error_log("Error ldap_search(\$ds, '$base', '$filter')!");
exit(111); // 111 = temporary problem
}
$entries = ldap_get_entries($ds, $sr);
if (!$entries['count'])
{
if ($log_verbose) error_log("User '$username' NOT found!");
exit(3);
}
if ($entries['count'] > 1)
{
// should not happen for passdb, but could happen for aliases ...
error_log("Error ldap_search(\$ds, '$base', '$filter') returned more then one user!");
exit(111); // 111 = temporary problem
}
//print_r($entries);
if ($passdb_query)
{
// now authenticate user by trying to bind to found dn with given password
if (!@ldap_bind($ds, $entries[0]['dn'], $password))
{
if ($log_verbose) error_log("Can't bind as '{$entries[0]['dn']}' with password '$password'! Authentication for user '$username' failed!");
exit(1);
}
if ($log_verbose) error_log("Successfull authentication user '$username' dn='{$entries[0]['dn']}'.");
}
else // user-db query, no authentication
{
if ($log_verbose) error_log("User-db query for user '$username' dn='{$entries[0]['dn']}'.");
}
// add additional placeholders from $user_attrs
foreach($user_attrs as $placeholder => $attr)
{
if ($attr[0] == '{') // prefix given --> ignore all values without and remove it
{
list($prefix, $attr) = explode('}', substr($attr, 1));
foreach($entries[0][$attr] as $key => $value)
{
if ($key === 'count') continue;
if (strpos($value, $prefix) !== 0) continue;
$replace[$placeholder] = substr($value, strlen($prefix));
break;
}
}
else
{
$replace[$placeholder] = is_array($entries[0][$attr]) ? $entries[0][$attr][0] : $entries[0][$attr];
}
}
// search memberships
if (isset($group_base) && $group_filter && $group_attr)
{
$base = strtr($group_base, $replace);
$filter = strtr($group_filter, quote($replace));
$append = strtr($group_append, $replace);
if (($sr = ldap_search($ds, $base, $filter, array($group_attr))) &&
($groups = ldap_get_entries($ds, $sr)) && $groups['count'])
{
//print_r($groups);
$system_groups_user = array();
foreach($groups as $key => $group)
{
if ($key === 'count') continue;
$system_groups_user[] = $group[$group_attr][0].$append;
}
$extra['system_groups_user'] = implode(',', $system_groups_user); // todo: check separator
}
else
{
error_log("Error searching for memberships ldap_search(\$ds, '$base', '$filter')!");
}
}
// set host attribute for director to old imap
if (isset($host_base) && isset($host_filter))
{
if (!($sr = ldap_search($ds, $host_base, $filter=strtr($host_filter, quote($replace)), array($host_attr))))
{
error_log("Error ldap_search(\$ds, '$host_base', '$filter')!");
exit(111); // 111 = temporary problem
}
$entries = ldap_get_entries($ds, $sr);
if ($entries['count'] && !isset($entries[0][$host_attr]))
{
$extra['host'] = $host_default;
}
}
// close ldap connection
ldap_unbind($ds);
// build command to run
array_shift($_SERVER['argv']);
$cmd = array_shift($_SERVER['argv']);
foreach($_SERVER['argv'] as $arg)
{
$cmd .= ' '.escapeshellarg($arg);
}
// setting USER, HOME, EXTRA
putenv('USER='.strtr($user_name, $replace));
if ($user_home) putenv('HOME='.strtr($user_home, $replace));
if ($extra)
{
foreach($extra as $name => $value)
{
if (($pos = strpos($value,'%')) !== false)
{
// check if replacement is set, otherwise skip whole extra-value
if (!isset($replace[substr($value,$pos,2)]))
{
unset($extra[$name]);
continue;
}
$value = strtr($value,$replace);
}
putenv($name.'='.$value);
}
putenv('EXTRA='.implode(' ', array_keys($extra)));
}
// call given command and exit with it's exit-status
passthru($cmd, $ret);
exit($ret);
/**
* escapes a string for use in searchfilters meant for ldap_search.
*
* Escaped Characters are: '*', '(', ')', ' ', '\', NUL
* It's actually a PHP-Bug, that we have to escape space.
* For all other Characters, refer to RFC2254.
*
* @param string|array $string either a string to be escaped, or an array of values to be escaped
* @return string
*/
function quote($string)
{
return str_replace(array('\\','*','(',')','\0',' '),array('\\\\','\*','\(','\)','\\0','\20'),$string);
}

754
doc/mail/main.cf Normal file
View File

@ -0,0 +1,754 @@
# Global Postfix configuration file. This file lists only a subset
# of all 300+ parameters. See the sample-xxx.cf files for a full list.
#
# The general format is lines with parameter = value pairs. Lines
# that begin with whitespace continue the previous line. A value can
# contain references to other $names or ${name}s.
#
# NOTE - CHANGE NO MORE THAN 2-3 PARAMETERS AT A TIME, AND TEST IF
# POSTFIX STILL WORKS AFTER EVERY CHANGE.
# SOFT BOUNCE
#
# The soft_bounce parameter provides a limited safety net for
# testing. When soft_bounce is enabled, mail will remain queued that
# would otherwise bounce. This parameter disables locally-generated
# bounces, and prevents the SMTP server from rejecting mail permanently
# (by changing 5xx replies into 4xx replies). However, soft_bounce
# is no cure for address rewriting mistakes or mail routing mistakes.
#
#soft_bounce = no
# LOCAL PATHNAME INFORMATION
#
# The queue_directory specifies the location of the Postfix queue.
# This is also the root directory of Postfix daemons that run chrooted.
# See the files in examples/chroot-setup for setting up Postfix chroot
# environments on different UNIX systems.
#
queue_directory = /var/spool/postfix
# The command_directory parameter specifies the location of all
# postXXX commands.
#
command_directory = /usr/sbin
# The daemon_directory parameter specifies the location of all Postfix
# daemon programs (i.e. programs listed in the master.cf file). This
# directory must be owned by root.
#
daemon_directory = /usr/lib/postfix
# QUEUE AND PROCESS OWNERSHIP
#
# The mail_owner parameter specifies the owner of the Postfix queue
# and of most Postfix daemon processes. Specify the name of a user
# account THAT DOES NOT SHARE ITS USER OR GROUP ID WITH OTHER ACCOUNTS
# AND THAT OWNS NO OTHER FILES OR PROCESSES ON THE SYSTEM. In
# particular, don't specify nobody or daemon. PLEASE USE A DEDICATED
# USER.
#
mail_owner = postfix
# The default_privs parameter specifies the default rights used by
# the local delivery agent for delivery to external file or command.
# These rights are used in the absence of a recipient user context.
# DO NOT SPECIFY A PRIVILEGED USER OR THE POSTFIX OWNER.
#
#default_privs = nobody
# INTERNET HOST AND DOMAIN NAMES
#
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = host.domain.tld
#myhostname = virtual.domain.tld
# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = domain.tld
# SENDING MAIL
#
# The myorigin parameter specifies the domain that locally-posted
# mail appears to come from. The default is to append $myhostname,
# which is fine for small sites. If you run a domain with multiple
# machines, you should (1) change this to $mydomain and (2) set up
# a domain-wide alias database that aliases each user to
# user@that.users.mailhost.
#
# For the sake of consistency between sender and recipient addresses,
# myorigin also specifies the default domain name that is appended
# to recipient addresses that have no @domain part.
#
#myorigin = $myhostname
#myorigin = $mydomain
# RECEIVING MAIL
# The inet_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on. By default,
# the software claims all active interfaces on the machine. The
# parameter also controls delivery of mail to user@[ip.address].
#
# See also the proxy_interfaces parameter, for network addresses that
# are forwarded to us via a proxy or network address translator.
#
# Note: you need to stop/start Postfix when this parameter changes.
#
#inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
# The proxy_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on by way of a
# proxy or network address translation unit. This setting extends
# the address list specified with the inet_interfaces parameter.
#
# You must specify your proxy/NAT addresses when your system is a
# backup MX host for other domains, otherwise mail delivery loops
# will happen when the primary MX host is down.
#
#proxy_interfaces =
#proxy_interfaces = 1.2.3.4
# The mydestination parameter specifies the list of domains that this
# machine considers itself the final destination for.
#
# These domains are routed to the delivery agent specified with the
# local_transport parameter setting. By default, that is the UNIX
# compatible delivery agent that lookups all recipients in /etc/passwd
# and /etc/aliases or their equivalent.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain.
#
# Do not specify the names of virtual domains - those domains are
# specified elsewhere (see sample-virtual.cf).
#
# Do not specify the names of domains that this machine is backup MX
# host for. Specify those names via the relay_domains settings for
# the SMTP server, or use permit_mx_backup if you are lazy (see
# sample-smtpd.cf).
#
# The local machine is always the final destination for mail addressed
# to user@[the.net.work.address] of an interface that the mail system
# receives mail on (see the inet_interfaces parameter).
#
# Specify a list of host or domain names, /file/name or type:table
# patterns, separated by commas and/or whitespace. A /file/name
# pattern is replaced by its contents; a type:table is matched when
# a name matches a lookup key (the right-hand side is ignored).
# Continue long lines by starting the next line with whitespace.
#
# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
# SPECIFY RELAY DESTINATIONS IN RELAY_DOMAINS.
#
# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
#mydestination = $myhostname, localhost.$mydomain
#mydestination = $myhostname, localhost.$mydomain $mydomain
#mydestination = $myhostname, localhost.$mydomain, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain
mydestination = $myhostname, localhost.$mydomain $mydomain,
kneschke.de, phpgw.de, egroupware.org, linux-at-work.de, lists.kneschke.de
# REJECTING MAIL FOR UNKNOWN LOCAL USERS
#
# The local_recipient_maps parameter specifies optional lookup tables
# with all names or addresses of users that are local with respect
# to $mydestination and $inet_interfaces.
#
# If this parameter is defined, then the SMTP server will reject
# mail for unknown local users. This parameter is defined by default.
#
# To turn off local recipient checking in the SMTP server, specify
# local_recipient_maps = (i.e. empty).
#
# The default setting assumes that you use the default Postfix local
# delivery agent for local delivery. You need to update the
# local_recipient_maps setting if:
#
# - You define $mydestination domain recipients in files other than
# /etc/passwd, /etc/aliases, or the $virtual_alias_maps files.
# For example, you define $mydestination domain recipients in
# the $virtual_mailbox_maps files.
#
# - You redefine the local delivery agent in master.cf.
#
# - You redefine the "local_transport" setting in main.cf.
#
# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
# feature of the Postfix local delivery agent (see sample-local.cf).
#
# Details are described in the LOCAL_RECIPIENT_README file.
#
# Beware: if the Postfix SMTP server runs chrooted, you probably have
# to access the passwd file via the proxymap service, in order to
# overcome chroot restrictions. The alternative, having a copy of
# the system passwd file in the chroot jail is just not practical.
#
# The right-hand side of the lookup tables is conveniently ignored.
# In the left-hand side, specify a bare username, an @domain.tld
# wild-card, or specify a user@domain.tld address.
#
#local_recipient_maps = unix:passwd.byname $alias_maps
#local_recipient_maps = proxy:unix:passwd.byname $alias_maps
#local_recipient_maps =
# The unknown_local_recipient_reject_code specifies the SMTP server
# response code when a recipient domain matches $mydestination or
# $inet_interfaces, while $local_recipient_maps is non-empty and the
# recipient address or address local-part is not found.
#
# The default setting is 550 (reject mail) but it is safer to start
# with 450 (try again later) until you are certain that your
# local_recipient_maps settings are OK.
#
unknown_local_recipient_reject_code = 550
#unknown_local_recipient_reject_code = 450
# TRUST AND RELAY CONTROL
# The mynetworks parameter specifies the list of "trusted" SMTP
# clients that have more privileges than "strangers".
#
# In particular, "trusted" SMTP clients are allowed to relay mail
# through Postfix. See the smtpd_recipient_restrictions parameter
# in file sample-smtpd.cf.
#
# You can specify the list of "trusted" network addresses by hand
# or you can let Postfix do it for you (which is the default).
#
# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
# clients in the same IP subnetworks as the local machine.
# On Linux, this does works correctly only with interfaces specified
# with the "ifconfig" command.
#
# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
# clients in the same IP class A/B/C networks as the local machine.
# Don't do this with a dialup site - it would cause Postfix to "trust"
# your entire provider's network. Instead, specify an explicit
# mynetworks list by hand, as described below.
#
# Specify "mynetworks_style = host" when Postfix should "trust"
# only the local machine.
#
#mynetworks_style = class
#mynetworks_style = subnet
#mynetworks_style = host
# Alternatively, you can specify the mynetworks list by hand, in
# which case Postfix ignores the mynetworks_style setting.
#
# Specify an explicit list of network/netmask patterns, where the
# mask specifies the number of bits in the network part of a host
# address.
#
# You can also specify the absolute pathname of a pattern file instead
# of listing the patterns here. Specify type:table for table-based lookups
# (the value on the table right-hand side is not used).
#
#mynetworks = 168.100.189.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks
#mynetworks = hash:/etc/postfix/network_table
# The relay_domains parameter restricts what destinations this system will
# relay mail to. See the smtpd_recipient_restrictions restriction in the
# file sample-smtpd.cf for detailed information.
#
# By default, Postfix relays mail
# - from "trusted" clients (IP address matches $mynetworks) to any destination,
# - from "untrusted" clients to destinations that match $relay_domains or
# subdomains thereof, except addresses with sender-specified routing.
# The default relay_domains value is $mydestination.
#
# In addition to the above, the Postfix SMTP server by default accepts mail
# that Postfix is final destination for:
# - destinations that match $inet_interfaces,
# - destinations that match $mydestination
# - destinations that match $virtual_alias_domains,
# - destinations that match $virtual_mailbox_domains.
# These destinations do not need to be listed in $relay_domains.
#
# Specify a list of hosts or domains, /file/name patterns or type:name
# lookup tables, separated by commas and/or whitespace. Continue
# long lines by starting the next line with whitespace. A file name
# is replaced by its contents; a type:name table is matched when a
# (parent) domain appears as lookup key.
#
# NOTE: Postfix will not automatically forward mail for domains that
# list this system as their primary or backup MX host. See the
# permit_mx_backup restriction in the file sample-smtpd.cf.
#
#relay_domains = $mydestination
# INTERNET OR INTRANET
# The relayhost parameter specifies the default host to send mail to
# when no entry is matched in the optional transport(5) table. When
# no relayhost is given, mail is routed directly to the destination.
#
# On an intranet, specify the organizational domain name. If your
# internal DNS uses no MX records, specify the name of the intranet
# gateway host instead.
#
# In the case of SMTP, specify a domain, host, host:port, [host]:port,
# [address] or [address]:port; the form [host] turns off MX lookups.
#
# If you're connected via UUCP, see also the default_transport parameter.
#
#relayhost = $mydomain
#relayhost = gateway.my.domain
#relayhost = uucphost
#relayhost = [an.ip.add.ress]
# REJECTING UNKNOWN RELAY USERS
#
# The relay_recipient_maps parameter specifies optional lookup tables
# with all addresses in the domains that match $relay_domains.
#
# If this parameter is defined, then the SMTP server will reject
# mail for unknown relay users. This feature is off by default.
#
# The right-hand side of the lookup tables is conveniently ignored.
# In the left-hand side, specify an @domain.tld wild-card, or specify
# a user@domain.tld address.
#
#relay_recipient_maps = hash:/etc/postfix/relay_recipients
# INPUT RATE CONTROL
#
# The in_flow_delay configuration parameter implements mail input
# flow control. This feature is turned on by default, although it
# still needs further development (it's disabled on SCO UNIX due
# to an SCO bug).
#
# A Postfix process will pause for $in_flow_delay seconds before
# accepting a new message, when the message arrival rate exceeds the
# message delivery rate. With the default 100 SMTP server process
# limit, this limits the mail inflow to 100 messages a second more
# than the number of messages delivered per second.
#
# Specify 0 to disable the feature. Valid delays are 0..10.
#
#in_flow_delay = 1s
# ADDRESS REWRITING
#
# Insert text from sample-rewrite.cf if you need to do address
# masquerading.
#
# Insert text from sample-canonical.cf if you need to do address
# rewriting, or if you need username->Firstname.Lastname mapping.
# ADDRESS REDIRECTION (VIRTUAL DOMAIN)
#
# Insert text from sample-virtual.cf if you need virtual domain support.
# "USER HAS MOVED" BOUNCE MESSAGES
#
# Insert text from sample-relocated.cf if you need "user has moved"
# style bounce messages. Alternatively, you can bounce recipients
# with an SMTP server access table. See sample-smtpd.cf.
# TRANSPORT MAP
#
# Insert text from sample-transport.cf if you need explicit routing.
# ALIAS DATABASE
#
# The alias_maps parameter specifies the list of alias databases used
# by the local delivery agent. The default list is system dependent.
#
# On systems with NIS, the default is to search the local alias
# database, then the NIS alias database. See aliases(5) for syntax
# details.
#
# If you change the alias database, run "postalias /etc/aliases" (or
# wherever your system stores the mail alias file), or simply run
# "newaliases" to build the necessary DBM or DB file.
#
# It will take a minute or so before changes become visible. Use
# "postfix reload" to eliminate the delay.
#
#alias_maps = dbm:/etc/aliases
#alias_maps = hash:/etc/aliases
#alias_maps = hash:/etc/aliases, nis:mail.aliases
#alias_maps = netinfo:/aliases
# The alias_database parameter specifies the alias database(s) that
# are built with "newaliases" or "sendmail -bi". This is a separate
# configuration parameter, because alias_maps (see above) may specify
# tables that are not necessarily all under control by Postfix.
#
#alias_database = dbm:/etc/aliases
#alias_database = dbm:/etc/mail/aliases
#alias_database = hash:/etc/aliases
#alias_database = hash:/etc/aliases, hash:/opt/majordomo/aliases
# ADDRESS EXTENSIONS (e.g., user+foo)
#
# The recipient_delimiter parameter specifies the separator between
# user names and address extensions (user+foo). See canonical(5),
# local(8), relocated(5) and virtual(5) for the effects this has on
# aliases, canonical, virtual, relocated and .forward file lookups.
# Basically, the software tries user+foo and .forward+foo before
# trying user and .forward.
#
#recipient_delimiter = +
# DELIVERY TO MAILBOX
#
# The home_mailbox parameter specifies the optional pathname of a
# mailbox file relative to a user's home directory. The default
# mailbox file is /var/spool/mail/user or /var/mail/user. Specify
# "Maildir/" for qmail-style delivery (the / is required).
#
#home_mailbox = Mailbox
#home_mailbox = Maildir/
# The mail_spool_directory parameter specifies the directory where
# UNIX-style mailboxes are kept. The default setting depends on the
# system type.
#
#mail_spool_directory = /var/mail
#mail_spool_directory = /var/spool/mail
# The mailbox_command parameter specifies the optional external
# command to use instead of mailbox delivery. The command is run as
# the recipient with proper HOME, SHELL and LOGNAME environment settings.
# Exception: delivery for root is done as $default_user.
#
# Other environment variables of interest: USER (recipient username),
# EXTENSION (address extension), DOMAIN (domain part of address),
# and LOCAL (the address localpart).
#
# Unlike other Postfix configuration parameters, the mailbox_command
# parameter is not subjected to $parameter substitutions. This is to
# make it easier to specify shell syntax (see example below).
#
# Avoid shell meta characters because they will force Postfix to run
# an expensive shell process. Procmail alone is expensive enough.
#
# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
#
#mailbox_command = /some/where/procmail
#mailbox_command = /some/where/procmail -a "$EXTENSION"
# The mailbox_transport specifies the optional transport in master.cf
# to use after processing aliases and .forward files. This parameter
# has precedence over the mailbox_command, fallback_transport and
# luser_relay parameters.
#
# Specify a string of the form transport:nexthop, where transport is
# the name of a mail delivery transport defined in master.cf. The
# :nexthop part is optional. For more details see the sample transport
# configuration file.
#
# NOTE: if you use this feature for accounts not in the UNIX password
# file, then you must update the "local_recipient_maps" setting in
# the main.cf file, otherwise the SMTP server will reject mail for
# non-UNIX accounts with "User unknown in local recipient table".
#
#mailbox_transport = lmtp:unix:/file/name
mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
#mailbox_transport = cyrus
# The fallback_transport specifies the optional transport in master.cf
# to use for recipients that are not found in the UNIX passwd database.
# This parameter has precedence over the luser_relay parameter.
#
# Specify a string of the form transport:nexthop, where transport is
# the name of a mail delivery transport defined in master.cf. The
# :nexthop part is optional. For more details see the sample transport
# configuration file.
#
# NOTE: if you use this feature for accounts not in the UNIX password
# file, then you must update the "local_recipient_maps" setting in
# the main.cf file, otherwise the SMTP server will reject mail for
# non-UNIX accounts with "User unknown in local recipient table".
#
#fallback_transport = lmtp:unix:/file/name
#fallback_transport = cyrus
#fallback_transport =
# The luser_relay parameter specifies an optional destination address
# for unknown recipients. By default, mail for unknown@$mydestination
# and unknown@[$inet_interfaces] is returned as undeliverable.
#
# The following expansions are done on luser_relay: $user (recipient
# username), $shell (recipient shell), $home (recipient home directory),
# $recipient (full recipient address), $extension (recipient address
# extension), $domain (recipient domain), $local (entire recipient
# localpart), $recipient_delimiter. Specify ${name?value} or
# ${name:value} to expand value only when $name does (does not) exist.
#
# luser_relay works only for the default Postfix local delivery agent.
#
# NOTE: if you use this feature for accounts not in the UNIX password
# file, then you must specify "local_recipient_maps =" (i.e. empty) in
# the main.cf file, otherwise the SMTP server will reject mail for
# non-UNIX accounts with "User unknown in local recipient table".
#
#luser_relay = $user@other.host
#luser_relay = $local@other.host
#luser_relay = admin+$local
# JUNK MAIL CONTROLS
#
# The controls listed here are only a very small subset. See the file
# sample-smtpd.cf for an elaborate list of anti-UCE controls.
# The header_checks parameter specifies an optional table with patterns
# that each logical message header is matched against, including
# headers that span multiple physical lines.
#
# By default, these patterns also apply to MIME headers and to the
# headers of attached messages. With older Postfix versions, MIME and
# attached message headers were treated as body text.
#
# For details, see the sample-filter.cf file.
#
#header_checks = regexp:/etc/postfix/header_checks
# FAST ETRN SERVICE
#
# Postfix maintains per-destination logfiles with information about
# deferred mail, so that mail can be flushed quickly with the SMTP
# "ETRN domain.tld" command, or by executing "sendmail -qRdomain.tld".
#
# By default, Postfix maintains deferred mail logfile information
# only for destinations that Postfix is willing to relay to (as
# specified in the relay_domains parameter). For other destinations,
# Postfix attempts to deliver ALL queued mail after receiving the
# SMTP "ETRN domain.tld" command, or after execution of "sendmail
# -qRdomain.tld". This can be slow when a lot of mail is queued.
#
# The fast_flush_domains parameter controls what destinations are
# eligible for this "fast ETRN/sendmail -qR" service.
#
#fast_flush_domains = $relay_domains
#fast_flush_domains =
# The disable_vrfy_command parameter allows you to disable the SMTP
# VRFY command. This stops some techniques used by spammers to harvest
# email addresses.
#
disable_vrfy_command = yes
# SHOW SOFTWARE VERSION OR NOT
#
# The smtpd_banner parameter specifies the text that follows the 220
# code in the SMTP server's greeting banner. Some people like to see
# the mail version advertised. By default, Postfix shows no version.
#
# You MUST specify $myhostname at the start of the text. That is an
# RFC requirement. Postfix itself does not care.
#
#smtpd_banner = $myhostname ESMTP $mail_name
#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
# PARALLEL DELIVERY TO THE SAME DESTINATION
#
# How many parallel deliveries to the same user or domain? With local
# delivery, it does not make sense to do massively parallel delivery
# to the same user, because mailbox updates must happen sequentially,
# and expensive pipelines in .forward files can cause disasters when
# too many are run at the same time. With SMTP deliveries, 10
# simultaneous connections to the same domain could be sufficient to
# raise eyebrows.
#
# Each message delivery transport has its XXX_destination_concurrency_limit
# parameter. The default is $default_destination_concurrency_limit for
# most delivery transports. For the local delivery agent the default is 2.
#local_destination_concurrency_limit = 2
#default_destination_concurrency_limit = 20
# DEBUGGING CONTROL
#
# The debug_peer_level parameter specifies the increment in verbose
# logging level when an SMTP client or server host name or address
# matches a pattern in the debug_peer_list parameter.
#
debug_peer_level = 2
# The debug_peer_list parameter specifies an optional list of domain
# or network patterns, /file/name patterns or type:name tables. When
# an SMTP client or server host name or address matches a pattern,
# increase the verbose logging level by the amount specified in the
# debug_peer_level parameter.
#
#debug_peer_list = 127.0.0.1
#debug_peer_list = some.domain
# The debugger_command specifies the external command that is executed
# when a Postfix daemon program is run with the -D option.
#
# Use "command .. & sleep 5" so that the debugger can attach before
# the process marches on. If you use an X-based debugger, be sure to
# set up your XAUTHORITY environment variable before starting Postfix.
#
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id & sleep 5
# If you don't have X installed on the Postfix machine, try:
# debugger_command =
# PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont;
# echo where) | gdb $daemon_directory/$process_name $process_id 2>&1
# >$config_directory/$process_name.$process_id.log & sleep 5
# INSTALL-TIME CONFIGURATION INFORMATION
#
# The following parameters are used when installing a new Postfix version.
#
# sendmail_path: The full pathname of the Postfix sendmail command.
# This is the Sendmail-compatible mail posting interface.
#
sendmail_path = /usr/sbin/sendmail
# newaliases_path: The full pathname of the Postfix newaliases command.
# This is the Sendmail-compatible command to build alias databases.
#
newaliases_path = /usr/bin/newaliases
# mailq_path: The full pathname of the Postfix mailq command. This
# is the Sendmail-compatible mail queue listing command.
#
mailq_path = /usr/bin/mailq
# setgid_group: The group for mail submission and queue management
# commands. This must be a group name with a numerical group ID that
# is not shared with other accounts, not even with the Postfix account.
#
setgid_group = postdrop
# manpage_directory: The location of the Postfix on-line manual pages.
#
manpage_directory = /usr/share/man
# sample_directory: The location of the Postfix sample configuration files.
#
sample_directory = /usr/share/doc/postfix-2.0.19/sample
# readme_directory: The location of the Postfix README files.
#
readme_directory = /usr/share/doc/postfix-2.0.19/readme
default_destination_concurrency_limit = 2
#alias_database = hash:/etc/mail/aliases
local_destination_concurrency_limit = 2
alias_maps = hash:/etc/mail/aliases
content_filter = smtp-amavis:[127.0.0.1]:10024
queue_minfree = 100000000
message_size_limit = 50000000
mailbox_size_limit = 500000000
smtpd_helo_required=yes
smtpd_helo_restrictions=permit_mynetworks, reject_invalid_hostname, reject_invalid_hostname
smtpd_sender_restrictions=permit_mynetworks, reject_unknown_sender_domain, reject_non_fqdn_sender
virtual_maps = ldap:aliases, ldap:mailboxes
aliases_server_host = 127.0.0.1
aliases_search_base = dc=domain,dc=loc
aliases_query_filter = (&(|(mail=%s)(mailalternateaddress=%s))(objectclass=posixaccount)(deliveryMode=forwardonly)(accountstatus=active))
aliases_bind_dn = cn=thepostfixadmin,dc=domain,dc=loc
aliases_bind_pw = thepassword
aliases_result_attribute = mailforwardingaddress
aliases_version = 3
mailboxes_server_host = 127.0.0.1
mailboxes_search_base = dc=domain,dc=loc
mailboxes_query_filter = (&(|(mail=%s)(mailalternateaddress=%s))(objectclass=posixaccount)(accountstatus=active))
mailboxes_bind_dn = cn=thepostfixadmin,dc=domain,dc=loc
mailboxes_bind_pw = thepassword
mailboxes_result_attribute = uid, mailforwardingaddress
mailboxes_version = 3
#SMTPD mit SASL-Authentification verwenden
smtpd_sasl_auth_enable = yes
#Zusatz-Optionen: Keine anonyme-Anmeldung verwenden
smtpd_sasl_security_options = noanonymous
#Wieder ein Workaround für ältere Clients und Outlook
broken_sasl_auth_clients = yes
# ODER meine Netze und SASL erlauben
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_rbl_client relays.ordb.org,
reject_rbl_client sbl-xbl.spamhaus.org,
reject_rbl_client opm.blitzed.org,
reject_rbl_client dnsbl.njabl.org,
reject_rbl_client blackholes.wirehub.net,
reject_rbl_client list.dsbl.org,
reject_rbl_client dnsbl.sorbs.net,
reject_unauth_destination,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unauth_pipelining,
reject_unknown_sender_domain,
reject_unknown_recipient_domain
# reject_unknown_client
# reject_rbl_client proxies.relays.monkeys.com,
# incoming SSL
smtpd_use_tls = yes
#smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/ssl/private/smtp.linux-at-work.de/smtp.linux-at-work.de.key
smtpd_tls_cert_file = /etc/ssl/private/smtp.linux-at-work.de/smtp.linux-at-work.de.crt
smtpd_tls_CAfile = /etc/ssl/certs/ca-cert.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
#outgoing SSL
smtp_tls_key_file = /etc/ssl/private/smtp.linux-at-work.de/smtp.linux-at-work.de.key
smtp_tls_cert_file = /etc/ssl/private/smtp.linux-at-work.de/smtp.linux-at-work.de.crt
smtp_tls_CAfile = /etc/ssl/certs/ca-cert.pem
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_loglevel = 2
# The server and client negotiate a session, which takes some computer time
# and network bandwidth. The session is cached only in the smtpd process
# actually using this session and is lost when the process dies.
# To share the session information between the smtp processes, a disc based
# session cache can be used based on the SDBM databases (routines included
# in Postfix/TLS). Since concurrent writing must be supported, only SDBM
# can be used.
#
smtp_tls_session_cache_database = sdbm:/etc/postfix/smtp_scache
# By default TLS is disabled, so no difference to plain postfix is visible.
# If you enable TLS it will be used when offered by the server.
# WARNING: I didn't have access to other software (except those explicitely
# listed) to test the interaction. On corresponding mailing list
# there was a discussion going on about MS exchange servers offering
# STARTTLS even if it is not configured, so it might be wise to not
# use this option on your central mail hub, as you don't know in advance
# whether you are going to hit such host. Use the recipient/site specific
# options instead.
# HINT: I have it switched on on my mailservers and did experience one
# single failure since client side TLS is implemented. (There was one
# misconfired MS Exchange server; I contacted ths admin.) Hence, I am happy
# with it running all the time, but I am interested in testing anyway.
# You have been warned, however :-)
#
# In case of failure, a "4xx" code is issued and the mail stays in the queue.
#
# Explicitely switch it on here, if you want it.
#
#smtp_use_tls = yes

408
doc/mail/postfix_tcp_map_ads.php Executable file
View File

@ -0,0 +1,408 @@
#!/usr/bin/php -Cq
<?php
/**
* EGroupware - tcp-map for Postfix and Active Directory
*
* Using multivalued proxyAddresses attribute as implemented in Api\Mail\Smtp\Ads:
* - "smtp:<email>" allows to receive mail for given <email>
* (includes aliases AND primary email)
* - "forward:<email>" forwards received mail to given <email>
* (requires account to have at an "smtp:<email>" value!)
* - ("forwardOnly" is used for no local mailbox, only forwards, not implemented!)
* - ("quota:<quota>" is used to store quota)
*
* Groups can be used as distribution lists by assigning them an
* email address via there mail attribute (no proxyAddress)
*
* PROTOCOL DESCRIPTION
* The TCP map class implements a very simple protocol: the
* client sends a request, and the server sends one reply.
* Requests and replies are sent as one line of ASCII text,
* terminated by the ASCII newline character. Request and
* reply parameters (see below) are separated by whitespace.
*
* REQUEST FORMAT
* Each request specifies a command, a lookup key, and possi-
* bly a lookup result.
*
* get SPACE key NEWLINE
* Look up data under the specified key.
*
* put SPACE key SPACE value NEWLINE
* This request is currently not implemented.
*
* REPLY FORMAT
* Each reply specifies a status code and text. Replies must
* be no longer than 4096 characters including the newline
* terminator.
*
* 500 SPACE text NEWLINE
* In case of a lookup request, the requested data
* does not exist. In case of an update request, the
* request was rejected. The text describes the
* nature of the problem.
*
* 400 SPACE text NEWLINE
* This indicates an error condition. The text
* describes the nature of the problem. The client
* should retry the request later.
*
* 200 SPACE text NEWLINE
* The request was successful. In the case of a lookup
* request, the text contains an encoded version of
* the requested data.
*
* ENCODING
* In request and reply parameters, the character %, each
* non-printing character, and each whitespace character must
* be replaced by %XX, where XX is the corresponding ASCII
* hexadecimal character value. The hexadecimal codes can be
* specified in any case (upper, lower, mixed).
*
* The Postfix client always encodes a request. The server
* may omit the encoding as long as the reply is guaranteed
* to not contain the % or NEWLINE character.
*
* @author rb(at)stylite.de
* @copyright (c) 2012-13 by rb(at)stylite.de
* @package emailadmin
* @link http://www.postfix.org/tcp_table.5.html
* @version $Id$
*/
// protect from being called via HTTP
if (php_sapi_name() !== 'cli') die('This is a command line only script!');
// our defaults
$default_host = 'localhost';
$verbose = false;
// allow only clients matching that preg to access, should be only mserver IP
//$only_client = '/^10\.40\.8\.210:/';
// uncomment to write to log-file, otherwise errors go to stderr
//$log = 'syslog'; // or not set (stderr) or filename '/var/log/postfix_tcp_map.log';
//$log_verbose = true; // error's are always logged, set to true to log failures and success too
// ldap server settings
$ldap_uri = 'ldaps://10.7.102.13/';
$base = 'CN=Users,DC=gruene,DC=intern';
//$bind_dn = "CN=Administrator,$base";
//$bind_dn = "Administrator@gruene.intern";
//$bind_pw = 'secret';
$version = 3;
$use_tls = false;
// supported maps
$maps = array(
// virtual mailbox map
'mailboxes' => array(
'base' => $base,
'filter' => '(&(objectCategory=person)(proxyAddresses=smtp:%s))',
'attrs' => 'samaccountname', // result-attrs must be lowercase!
'port' => 2001,
),
// virtual alias maps
'aliases' => array(
'base' => $base,
'filter' => '(&(objectCategory=person)(proxyAddresses=smtp:%s))',
'attrs' => array('samaccountname','{forward:}proxyaddresses'),
'port' => 2002,
),
// groups as distribution list
'groups' => array(
'base' => $base,
'filter' => '(&(objectCategory=group)(mail=%s))',
'attrs' => 'dn',
// continue with resulting dn
'filter1' => '(&(objectCategory=person)(proxyAddresses=smtp:*)(memberOf=%s))',
'attrs1' => array('samaccountname','{forward:}proxyaddresses'),
'port' => 2003,
),
);
ini_set('display_errors',false);
error_reporting(E_ALL & ~E_NOTICE);
if ($log) ini_set('error_log',$log);
function usage($extra=null)
{
global $maps;
fwrite(STDERR, "\nUsage: $cmd [-v|--verbose] [-h|--help] [-l|--log (syslog|path)] [-q|--query <email-addresse> (mailboxes|alias|groups)] [host]\n\n");
fwrite(STDERR, print_r($maps,true)."\n");
if ($extra) fwrite(STDERR, "\n\n$extra\n\n");
exit(2);
}
$cmd = basename(array_shift($_SERVER['argv']));
while (($arg = array_shift($_SERVER['argv'])) && $arg[0] == '-')
{
switch($arg)
{
case '-v': case '--verbose':
$verbose = $log_verbose = true;
break;
case '-h': case '--help':
usage();
break;
case '-l': case '--log':
$log = array_shift($_SERVER['argv']);
break;
case '-q': case '--query':
if (count($_SERVER['argv']) == 2) // need 2 arguments
{
$request = 'get '.array_shift($_SERVER['argv'])."\n";
$map = array_shift($_SERVER['argv']);
echo respond($request, $map)."\n";
exit;
}
usage();
break;
default:
usage("Unknown option '$arg'!");
}
}
if ($_SERVER['argv']) usage();
if ($arg)
{
$host = $arg;
}
else
{
$host = $default_host;
}
if ($verbose) echo "using $host\n";
$servers = $clients = $buffers = array();
// Create the server socket
foreach($maps as $map => $data)
{
$addr = 'tcp://'.$host.':'.$data['port'];
if (!($server = stream_socket_server($addr, $errno, $errstr)))
{
fwrite(STDERR, date('Y-m-d H:i:s').": Error calling stream_socket_server('$addr')!\n");
fwrite(STDERR, $errstr." ($errno)\n");
exit($errno);
}
$servers[$data['port']] = $server;
$clients[$data['port']] = array();
}
while (true) // mail loop of tcp server --> never exits
{
$read = $servers;
if ($clients) $read = array_merge($read, call_user_func_array('array_merge', array_values($clients)));
if ($verbose) print 'about to call socket_select(array('.implode(',',$read).', ...) waiting... ';
if (stream_select($read, $write=null, $except=null, null)) // null = block forever
{
foreach($read as $sock)
{
if (($port = array_search($sock, $servers)) !== false)
{
$client = stream_socket_accept($sock,$timeout,$client_addr); // @ required to get not timeout warning!
if ($verbose) echo "accepted connection $client from $client_addr on port $port\n";
if ($only_client && !preg_match($only_client,$client_addr))
{
fwrite($client,"Go away!\r\n");
fclose($client);
error_log(date('Y-m-d H:i:s').": Connection $client from wrong client $client_addr (does NOT match '$only_client') --> terminated");
continue;
}
$clients[$port][] = $client;
}
elseif (feof($sock)) // client connection closed
{
if ($verbose) echo "client $sock closed connection\n";
foreach($clients as $port => &$socks)
{
if (($key = array_search($sock, $socks, true)) !== false)
{
unset($socks[$key]);
}
}
}
else // client send something
{
$buffer =& $buffers[$sock];
$buffer .= fread($sock, 8096);
if (strpos($buffer, "\n") !== false)
{
list($request, $buffer) = explode("\n", $buffer, 2);
foreach($maps as $map => $data)
{
if (($key = array_search($sock, $clients[$data['port']], true)) !== false)
{
if ($verbose) echo date('Y-m-d H:i:s').": client send: $request for map $map\n";
// Respond to client
fwrite($sock, respond($request, $map));
break;
}
}
}
}
}
if ($except)
{
echo "Exception: "; print_r($except);
}
}
else
{
// timeout expired
}
}
/**
* escapes a string for use in searchfilters meant for ldap_search.
*
* Escaped Characters are: '*', '(', ')', ' ', '\', NUL
* It's actually a PHP-Bug, that we have to escape space.
* For all other Characters, refer to RFC2254.
*
* @param string|array $string either a string to be escaped, or an array of values to be escaped
* @return string
*/
function quote($string)
{
return str_replace(array('\\','*','(',')','\0',' '),array('\\\\','\*','\(','\)','\\0','\20'),$string);
}
function respond($request, $map, $extra='', $reconnect=false)
{
static $ds;
global $ldap_uri, $version, $use_tls, $bind_dn, $bind_pw;
global $maps, $log_verbose;
if (($map == 'aliases' || $map == 'groups') && strpos($request,'@') === false && !$extra)
{
return "500 No domain aliases yet\n";
}
if (!isset($ds) || $reconnect)
{
$ds = ldap_connect($ldap_uri);
if ($version) ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $version);
if ($use_tls) ldap_start_tls($ds);
if (!@ldap_bind($ds, $bind_dn, $bind_pw))
{
error_log("$map: Can't connect to LDAP server $ldap_uri!");
$ds = null;
return "400 Can't connect to LDAP server $ldap_uri!\n"; // 400 (temp.) error
}
}
if (!preg_match('/^get ([^\n]+)\n?$/', $request, $matches))
{
error_log("$map: Wrong format '$request'!");
return "400 Wrong format '$request'!\n"; // 400 (temp.) error
}
$username = $matches[1];
list($name,$domain) = explode('@',$username);
/* check if we are responsible for the given domain
if ($domain && $map != 'domains' && (int)($response = respond("get $domain", 'domains')) != 200)
{
return $response;
}*/
$replace = array(
'%n' => quote($name),
'%d' => quote($domain),
'%s' => quote($username),
);
$base = strtr($maps[$map]['base'], $replace);
$filter = strtr($maps[$map]['filter'.$extra], $replace);
$prefix = isset($maps[$map]['prefix'.$extra]) ? str_replace(array('%n','%d','%s'),array($name,$domain,$username),$maps[$map]['prefix']) : '';
$search_attrs = $attrs = (array)$maps[$map]['attrs'.$extra];
// remove prefix like "{smtp:}proxyaddresses"
foreach($search_attrs as &$attr)
{
if ($attr[0] == '{') list(,$attr) = explode('}', $attr);
}
unset($attr);
if (!($sr = @ldap_search($ds, $base, $filter, $search_attrs)))
{
$errno = ldap_errno($ds);
$error = ldap_error($ds).' ('.$errno.')';
if ($errno == -1) // eg. -1 lost connection to ldap
{
// as DC closes connections quickly, first try to reconnect once, before returning a temp. failure
if (!$reconnect) return respond($request, $map, $extra, true);
error_log("$map: get '$username' --> 400 $error: !ldap_search(\$ds, '$base', '$filter')");
ldap_close($ds);
$ds = null; // force new connection on next lookup
return "400 $error\n"; // 400 (temp.) error
}
else // happens if base containing domain does not exist
{
if ($log_verbose) error_log("$map: get '$username' --> 500 Not found: $error: !ldap_search(\$ds, '$base', '$filter')");
return "500 Not found: $error\n"; // 500 not found
}
}
$entries = ldap_get_entries($ds, $sr);
if (!$entries['count'])
{
if ($log_verbose) error_log("$map: get '$username' --> 500 not found ldap_search(\$ds, '$base', '$filter') no entries");
return "500 Not found\n"; // 500: Query returned no result
}
$response = array();
foreach($entries as $key => $entry)
{
if ($key === 'count') continue;
foreach($attrs as $attr)
{
unset($filter_prefix);
if ($attr[0] == '{')
{
list($filter_prefix, $attr) = explode('}', substr($attr, 1));
}
foreach((array)$entry[$attr] as $k => $mail)
{
if ($k !== 'count' && ($mail = trim($mail)))
{
if ($filter_prefix)
{
if (stripos($mail, $filter_prefix) === 0)
{
$mail = substr($mail, strlen($filter_prefix));
}
else
{
continue;
}
}
$response[] = isset($maps[$map]['return']) ? $maps[$map]['return'] : $prefix.$mail;
}
}
}
}
if (!$response)
{
if ($log_verbose) error_log("$map: get '$username' --> 500 not found ldap_search(\$ds, '$base', '$filter') no response");
return "500 Not found\n"; // 500: Query returned no result
}
if (isset($maps[$map]['filter'.(1+$extra)]) && isset($maps[$map]['attrs'.(1+$extra)]))
{
return respond('get '.$response[0], $map, 1+$extra);
}
$response = '200 '.implode(',',$response)."\n";
if ($log_verbose) error_log("$map: get '$username' --> $response");
return $response;
}

271
doc/mail/qmail.new.schema Normal file
View File

@ -0,0 +1,271 @@
#
# qmail-ldap (20030901) ldapv3 directory schema
#
# The offical qmail-ldap OID assigned by IANA is 7914
#
# Created by: David E. Storey <dave@tamos.net>
# Modified and included into qmail-ldap by Andre Oppermann <opi@nrg4u.com>
# Schema fixes by Mike Jackson <mjj@pp.fi>
# Schema fixes by Christian Zoffoli (XMerlin) <czoffoli@xmerlin.org>
#
#
# This schema depends on:
# - core.schema
# - cosine.schema
# - nis.schema
#
# Attribute Type Definitions
attributetype ( 1.3.6.1.4.1.7914.1.2.1.1 NAME 'qmailUID'
DESC 'UID of the user on the mailsystem'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.2 NAME 'qmailGID'
DESC 'GID of the user on the mailsystem'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.3 NAME 'mailMessageStore'
DESC 'Path to the maildir/mbox on the mail system'
EQUALITY caseExactIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.4 NAME 'mailAlternateAddress'
DESC 'Secondary (alias) mailaddresses for the same user'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
#
# mailQuota format is no longer supported from qmail-ldap 20030901 on,
# user mailQuotaSize and mailQuotaCount instead.
#
#attributetype ( 1.3.6.1.4.1.7914.1.2.1.5 NAME 'mailQuota'
# DESC 'The amount of space the user can use until all further messages get bounced.'
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
#
attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'mailHost'
DESC 'On which qmail server the messagestore of this user is located.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.7914.1.2.1.7 NAME 'mailForwardingAddress'
DESC 'Address(es) to forward all incoming messages to.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.8 NAME 'deliveryProgramPath'
DESC 'Program to execute for all incoming mails.'
EQUALITY caseExactIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.9 NAME 'qmailDotMode'
DESC 'Interpretation of .qmail files: both, dotonly, ldaponly, ldapwithprog'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.10 NAME 'deliveryMode'
DESC 'multi field entries of: nolocal, noforward, noprogram, reply'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.11 NAME 'mailReplyText'
DESC 'A reply text for every incoming message'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.12 NAME 'accountStatus'
DESC 'The status of a user account: active, noaccess, disabled, deleted'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.14 NAME 'qmailAccountPurge'
DESC 'The earliest date when a mailMessageStore will be purged'
EQUALITY numericStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.15 NAME 'mailQuotaSize'
DESC 'The size of space the user can have until further messages get bounced.'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.16 NAME 'mailQuotaCount'
DESC 'The number of messages the user can have until further messages get bounced.'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.17 NAME 'mailSizeMax'
DESC 'The maximum size of a single messages the user accepts.'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
#
# qmailGroup attributes
#
attributetype ( 1.3.6.1.4.1.7914.1.3.1.1 NAME 'dnmember'
DESC 'Group member specified as distinguished name.'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.2 NAME 'rfc822member'
DESC 'Group member specified as normal rf822 email address.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.3 NAME 'filtermember'
DESC 'Group member specified as ldap search filter.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{512} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.4 NAME 'senderconfirm'
DESC 'Sender to Group has to answer confirmation email.'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.5 NAME 'membersonly'
DESC 'Sender to Group must be group member itself.'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.6 NAME 'confirmtext'
DESC 'Text that will be sent with sender confirmation email.'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.7 NAME 'dnmoderator'
DESC 'Group moderator specified as Distinguished name.'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.8 NAME 'rfc822moderator'
DESC 'Group moderator specified as normal rfc822 email address.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.9 NAME 'moderatortext'
DESC 'Text that will be sent with request for moderation email.'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.10 NAME 'dnsender'
DESC 'Allowed sender specified as distinguished name.'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.11 NAME 'rfc822sender'
DESC 'Allowed sender specified as normal rf822 email address.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.12 NAME 'filtersender'
DESC 'Allowed sender specified as ldap search filter.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{512} )
#
# qldapAdmin Attributes
#
attributetype ( 1.3.6.1.4.1.7914.1.4.1.1 NAME 'qladnmanager'
DESC ''
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.2 NAME 'qlaDomainList'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.3 NAME 'qlaUidPrefix'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.4 NAME 'qlaQmailUid'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.5 NAME 'qlaQmailGid'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.6 NAME 'qlaMailMStorePrefix'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.7 NAME 'qlaMailQuotaSize'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.8 NAME 'qlaMailQuotaCount'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.9 NAME 'qlaMailSizeMax'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.10 NAME 'qlaMailHostList'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'qmailUser'
DESC 'QMail-LDAP User'
SUP top
AUXILIARY
MUST ( mail )
MAY ( uid $ mailMessageStore $ homeDirectory $ userPassword $
mailAlternateAddress $ qmailUID $ qmailGID $
mailHost $ mailForwardingAddress $ deliveryProgramPath $
qmailDotMode $ deliveryMode $ mailReplyText $
accountStatus $ qmailAccountPurge $
mailQuotaSize $ mailQuotaCount $ mailSizeMax ) )
objectclass ( 1.3.6.1.4.1.7914.1.3.2.1 NAME 'qmailGroup'
DESC 'QMail-LDAP Group'
SUP top
AUXILIARY
MUST ( mail $ mailAlternateAddress $ mailMessageStore )
MAY ( dnmember $ rfc822member $ filtermember $ senderconfirm $
membersonly $ confirmtext $ dnmoderator $ rfc822moderator $
moderatortext $ dnsender $ rfc822sender $ filtersender) )
objectclass ( 1.3.6.1.4.1.7914.1.4.2.1 NAME 'qldapAdmin'
DESC 'QMail-LDAP Subtree Admin'
SUP top
AUXILIARY
MUST ( qlaDnManager $ qlaDomainList $ qlaMailMStorePrefix $
qlaMailHostList )
MAY ( qlaUidPrefix $ qlaQmailUid $ qlaQmailGid $ qlaMailQuotaSize $
qlaMailQuotaCount $ qlaMailSizeMax ) )

103
doc/mail/qmailuser.schema Normal file
View File

@ -0,0 +1,103 @@
#
# qmail-ldap v3 directory schema
#
# The offical qmail-ldap OID assigned by IANA is 7914
#
# Created by: David E. Storey <dave@tamos.net>
#
# Modified and included into qmail-ldap by Andre Oppermann <opi@nrg4u.com>
#
# Schema fixes by Mike Jackson <mjj@pp.fi>
#
#
# This schema depends on:
# - core.schema
# - cosine.schema
# - nis.schema
#
#
# Example from new format
#
# attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
# DESC 'An integer uniquely identifying a user in an administrative domain'
# EQUALITY integerMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
# Attribute Type Definitions
attributetype ( 1.3.6.1.4.1.7914.1.2.1.1 NAME 'qmailUID'
DESC 'UID of the user on the mailsystem'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.2 NAME 'qmailGID'
DESC 'GID of the user on the mailsystem'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.3 NAME 'mailMessageStore'
DESC 'Path to the maildir/mbox on the mail system'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.4 NAME 'mailAlternateAddress'
DESC 'Secondary (alias) mailaddresses for the same user'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.5 NAME 'mailQuota'
DESC 'The amount of space the user can use until all further messages get bounced.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'mailHost'
DESC 'On which qmail server the messagestore of this user is located.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.7914.1.2.1.7 NAME 'mailForwardingAddress'
DESC 'Address(es) to forward all incoming messages to.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.8 NAME 'deliveryProgramPath'
DESC 'Program to execute for all incoming mails.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.9 NAME 'qmailDotMode'
DESC 'Interpretation of .qmail files: both, dotonly, ldaponly, ldapwithprog, none'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.10 NAME 'deliveryMode'
DESC 'multi field entries of: normal, forwardonly, nombox, localdelivery, reply, echo'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.11 NAME 'mailReplyText'
DESC 'A reply text for every incoming message'
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.12 NAME 'accountStatus'
DESC 'The status of a user account: active, nopop, disabled, deleted'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.14 NAME 'qmailAccountPurge'
DESC 'The earliest date when a mailMessageStore will be purged'
EQUALITY numericStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'qmailUser'
DESC 'QMail-LDAP User' SUP top AUXILIARY
MUST ( mail $ uid )
MAY ( mailMessageStore $ homeDirectory $ userPassword $
mailAlternateAddress $ qmailUID $ qmailGID $ mailQuota $
mailHost $ mailForwardingAddress $ deliveryProgramPath $
qmailDotMode $ deliveryMode $ mailReplyText $
accountStatus $ qmailAccountPurge ) )

View File

@ -0,0 +1,19 @@
SMARTSIEVE - SIEVE SCRIPT MANAGER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Copyright 2002 Stephen Grier <stephengrier@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

16
doc/mail/tcpmaps.conf Normal file
View File

@ -0,0 +1,16 @@
# # Start it with:
# # initctl reload-configuration
# # initctl start tcpmaps
description "TCPMAP"
author "Ralf und Wim"
start on runlevel [235] or starting postfix
stop on runlevel [S016]
#pre-start exec /etc/vmware-tools/services.sh start
#post-stop exec /etc/vmware-tools/services.sh stop
respawn
instance tcpmaps
exec /usr/local/bin/postfix_tcp_map_ads.php --log syslog localhost

View File

@ -655,17 +655,17 @@ function set_univention_defaults()
$domain = array_shift($domains);
// set "use auth with session credentials",tls,"not user editable","further identities"
$config['smtpserver'] = "$mailserver,465,,,yes,tls,no,yes";
$config['smtp'] = ',emailadmin_smtp_univention';
$config['smtp'] = ',Smtp\\Univention';
$config['mailserver'] = "$mailserver,993,$domain,email,tls";
if (_ucr_get('mail/dovecot') == 'yes')
{
$config['imap'] = /*'cyrus,'._ucr_secret('cyrus')*/','.',emailadmin_imap_dovecot';
$config['imap'] = /*'cyrus,'._ucr_secret('cyrus')*/','.',Imap\\Dovecot';
// default with sieve port to 4190, as config is only available on host mailserver app is installed
if (!($sieve_port = _ucr_get('mail/dovecot/sieve/port'))) $sieve_port = 4190;
}
else
{
$config['imap'] = /*'cyrus,'._ucr_secret('cyrus')*/','.',emailadmin_imap_cyrus';
$config['imap'] = /*'cyrus,'._ucr_secret('cyrus')*/','.',Imap\\Cyrus';
// default with sieve port to 4190, as config is only available on host mailserver app is installed
if (!($sieve_port = _ucr_get('mail/cyrus/sieve/port'))) $sieve_port = 4190;
}

View File

@ -429,7 +429,6 @@ class infolog_so
$this->db->delete($this->info_table,array('info_id'=>$info_id),__LINE__,__FILE__);
$this->db->delete($this->extra_table,array('info_id'=>$info_id),__LINE__,__FILE__);
egw_link::unlink(0,'infolog',$info_id);
egw_index::delete('infolog',$info_id);
if ($this->data['info_id'] == $info_id)
{
@ -439,13 +438,12 @@ class infolog_so
if ($delete_children)
{
$db2 = clone($this->db); // we need an extra result-set
$db2->select($this->info_table,'info_id',array(
foreach($db2->select($this->info_table,'info_id',array(
'info_id_parent' => $info_id,
'info_owner' => $this->user,
),__LINE__,__FILE__);
while ($db2->next_record())
),__LINE__,__FILE__) as $row)
{
$this->delete($db2->f(0),$delete_children);
$this->delete($row['info_id'], $delete_children);
}
}
// set parent_id to $new_parent or 0 for all not deleted children
@ -625,10 +623,6 @@ class infolog_so
// echo "<p>soinfolog.write this->data= "; _debug_array($this->data);
//error_log("### soinfolog::write(".print_r($to_write,true).") where=".print_r($where,true)." returning id=".$this->data['info_id']);
// update the index
//egw_index::save('infolog',$this->data['info_id'],$this->data['info_owner'],$this->data,$this->data['info_cat'],
// array('info_uid','info_type','info_status','info_confirm','info_access'));
return $this->data['info_id'];
}
@ -806,23 +800,6 @@ class infolog_so
if ($query['query']) $query['search'] = $query['query']; // allow both names
if ($query['search']) // we search in _from, _subject, _des and _extra_value for $query
{
/* new code join the index
if (ctype_digit($query['search'])) // search by ticket-number (numbers get never indexed!)
{
$sql_query = 'AND info_id='.(int)$query['search'];
}
else
{
$join = egw_index::sql_join_ids_by_keyword($query['search'],'infolog','info_id');
}
*/
/* new code with info_id IN (subquery) --> way to slow
$sql_query .= 'AND info_id IN ('.
egw_index::sql_ids_by_keyword(explode(' ',$query['search']),egw_index::MATCH_CONTAINS,'infolog').
// add search string itself, if it is numeric, to allow to search for a info_id/ticket number
ctype_digit($query['search'] ? ' UNION (SELECT '.$this->db->quote($query['search']).')' : '').')';
*/
/* old code searching the table direct */
$columns = array('info_from','info_addr','info_location','info_subject','info_extra_value');
// at the moment MaxDB 7.5 cant cast nor search text columns, it's suppost to change in 7.6
if ($this->db->capabilities['like_on_text']) $columns[] = 'info_des';
@ -953,19 +930,17 @@ class infolog_so
{
$users = array();
$this->db->select($this->info_table,'DISTINCT info_owner',array(
foreach($this->db->select($this->info_table,'DISTINCT info_owner',array(
str_replace(' AND ','',$this->statusFilter('open')),
'(ABS(info_startdate-'.time().')<'.(4*24*60*60).' OR '. // start_day within 4 days
'ABS(info_enddate-'.time().')<'.(4*24*60*60).')', // end_day within 4 days
),__LINE__,__FILE__);
while ($this->db->next_record())
),__LINE__,__FILE__) as $row)
{
$users[] = $this->db->f(0);
$users[] = $row['info_responsible'];
}
$this->db->select($this->info_table,'DISTINCT info_responsible',$this->statusFilter('open',false),__LINE__,__FILE__);
while ($this->db->next_record())
foreach($this->db->select($this->info_table,'DISTINCT info_responsible',$this->statusFilter('open',false),__LINE__,__FILE__) as $row)
{
foreach(explode(',',$this->db->f(0)) as $responsible)
foreach(explode(',', $row['info_responsible']) as $responsible)
{
if ($GLOBALS['egw']->accounts->get_type($responsible) == 'g')
{

View File

@ -44,12 +44,8 @@ $setup_info['mail']['depends'][] = array(
'versions' => Array('14.1')
);
$setup_info['mail']['depends'][] = array(
'appname' => 'etemplate',
'versions' => Array('14.1')
);
$setup_info['mail']['depends'][] = array(
'appname' => 'emailadmin',
'versions' => Array('14.1')
'appname' => 'api',
'versions' => Array('16.1')
);
// installation checks for mail
$setup_info['mail']['check_install'] = array(

View File

@ -82,12 +82,13 @@ class egw extends egw_minimal
function setup($domain_names,$createsessionobject=True)
{
// create the DB-object
$this->db = new egw_db($GLOBALS['egw_info']['server']);
// as SiteMgr, Wiki, KnowledgeBase and probably more still use eg next_record(), we stick with Db\Deprecated for now
$this->db = new Api\Db\Deprecated($GLOBALS['egw_info']['server']);
if ($this->debug)
{
$this->db->Debug = 1;
}
$this->db->set_app('phpgwapi');
$this->db->set_app(Api\Db::API_APPNAME);
// check if eGW is already setup, if not redirect to setup/
try {

View File

@ -1,386 +0,0 @@
<?php
/**
* API - eGW wide index over all applications (super-index)
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage link
* @version $Id$
*/
/**
* eGW wide index over all applications (superindex)
*
* This index allows a fulltext search over all applications (or of cause also a single app).
* Whenever an applications stores an entry it calls:
*
* boolean egw_index::save($app,$id,$owner,array $fields,array $cat_id=null),
*
* which calls, as the application do when is deletes an entry (!),
*
* boolean egw_index::delete($app,$id)
*
* and then splits all fields into keywords and add these to the index by
*
* boolean private egw_index::add($app,$id,$keyword).
*
* Applications can then use the index to search for a given keyword (and optional application):
*
* array egw_index::search($keyword,$app=null) or
*
* foreach(new egw_index($keyword,$app=null) as $app_id => $title)
*
* To also allow to search by a category or keyword part of it, the index also tracks the categories
* of the entries. Applications can choose to only use it for category storage, or cat do it redundant in
* there own table too. To retrieve the categories of one or multiple entries:
*
* array egw_index::cats($app,$ids)
*
* Applications can use a sql (sub-)query to get the id's of there app matching a certain keyword and
* include that in there own queries:
*
* string egw_index::sql_ids_by_keyword($app,$keyword)
*
* Please note: the index knows nothing about ACL, so it's the task of the application to ensure ACL rights.
*/
class egw_index implements IteratorAggregate
{
const INDEX_TABLE = 'egw_index';
const KEYWORD_TABLE = 'egw_index_keywords';
const INDEX_CAT_TABLE = 'egw_cat2entry';
const CAT_TABLE = 'egw_categories';
const SEPARATORS = "/[ ,;.:\"'!\/?=()+*><|\n\r-]+/";
const MIN_KEYWORD_LEN = 4;
/**
* Private reference to the global db object
*
* @var egw_db
*/
private static $db;
/**
* Search parameters of the constructor
*
* @var array
*/
private $search_params;
/**
* Constructor for the search iterator
*
* @param string $keyword
* @param string $app=null
* @param string $order='app' ordered by column: 'owner', 'id', 'app' (default)
* @param string $sort='ASC' sorting 'ASC' (default) or 'DESC'
* @param int $start=null if not null return limited resultset starting with row $start
* @param int $num_rows=0 number of rows for a limited resultset, defaul maxmatches from the user prefs
*/
function __construct($keyword,$app=null,$order='title',$sort='ASC',$start=null,$num_rows=0)
{
$this->search_params = func_get_args();
}
/**
* Return the result of egw_index::search() as ArrayIterator
*
* @return ArrayIterator
*/
function getIterator()
{
return new ArrayIterator(call_user_func_array(array(__CLASS__,'search'),$this->search_params));
}
/**
* Search for keywords
*
* @param string $keyword
* @param string $app=null
* @param string $order='app' ordered by column: 'keyword', 'id', 'app' (default)
* @param string $sort='ASC' sorting 'ASC' (default) or 'DESC'
* @param int $start=null if not null return limited resultset starting with row $start
* @param int $num_rows=null number of rows for a limited resultset, defaul maxmatches from the user prefs
* @return array with "$app:$id" or $id => $title pairs
*/
static function &search($keyword,$app=null,$order='title',$sort='ASC',$start=null,$num_rows=null)
{
if (!in_array(strtoupper($sort),array('ASC','DESC'))) $sort = 'ASC';
if (substr($order,0,3) != 'si_') $order = 'si_'.$order;
if (!in_array($order,array('si_app','si_id','si_owner'))) $order = 'si_app';
$rs = self::$db->union(array(
array(
'table' => self::INDEX_TABLE,
'cols' => 'si_app,si_app_id,si_owner',
'where' => array('keyword' => $keyword)+
($app ? array('ce_app' => $app) : array()),
),
array(
'table' => self::INDEX_CAT_TABLE,
'cols' => 'ce_app,ce_app_id,ce_owner',
'where' => array('cat_id IN (SELECT cat_id FROM '.self::CAT_TABLE.' WHERE cat_title '.
self::$db->capabilities['case_insensitive_like'].' '.self::$db->quote('%'.$keyword.'%').')')+
($app ? array('ce_app' => $app) : array()),
),
),__LINE__,__FILE__,$order.' '.$sort,$start,$num_rows);
// agregate the ids by app
$app_ids = $titles = $rows = array();
foreach($rs as $row)
{
$app_ids[$row['si_app']] = $row['si_app_id'];
$rows[] = $row;
}
unset($rs);
// query the titles app-wise
foreach($app_ids as $id_app => $ids)
{
$titles[$id_app] = bolink::titles($id_app,$ids);
}
$matches = array();
foreach($rows as $row)
{
$key = $app ? $row['si_app_id'] : $row['si_app'].':'.$row['si_app_id'];
$title = $titles[$row['si_app']][$row['si_app_id']];
if (is_null($title)) // entry does not exist
{
self::delete($row['si_app'],$row['si_app_id']);
error_log(__METHOD__.": not existing entry (is_null(title($row[si_app],$row[si_app_id])) deleted from index!");
continue;
}
elseif($title === false)
{
$title = lang('Not readable %1 entry of user %2',lang($row['si_app']),$GLOBALS['egw']->common->grab_owner_name($row['si_owner']));
}
$matches[$key] = $title;
}
return $matches;
//return iterator_to_array(new egw_index($keyword,$app,$order,$sort,$start,$num_rows),true);
}
/**
* Stores the keywords for an entry in the index
*
* @param string $app
* @param string|int $id
* @param string $owner eGW account_id of the owner of the entry, used to create a "private entry of ..." title
* @param array $fields
* @param array|int|string $cat_ids=null optional cat_id(s) either comma-separated or as array
* @param array $ignore_fields=array() keys of fields NOT to index
* @return int|boolean false on error, othwerwise number off added keywords
*/
static function save($app,$id,$owner,array $fields,$cat_ids=null,array $ignore_fields=array())
{
if (!$app || !$id)
{
return false;
}
// collect the keywords of all fields
$keywords = array();
foreach($fields as $field)
{
if ($ignore_fields && in_array($field, $ignore_fields)) continue;
foreach(preg_split(self::SEPARATORS, $field) as $keyword)
{
if (!in_array($keyword,$keywords) && strlen($keyword) >= self::MIN_KEYWORD_LEN && !is_numeric($keyword))
{
$keywords[] = $keyword;
}
}
}
// delete evtl. existing current keywords
self::delete($app,$id);
// add the keywords
foreach($keywords as $key => &$keyword)
{
if (!self::add($app,$id,$keyword,$owner)) // add can reject keywords
{
unset($keywords[$key]);
}
}
// delete the existing cats
self::delete_cats($app,$id);
// add the cats
if ($cat_ids)
{
self::add_cats($app,$id,$cat_ids,$owner);
}
return count($keywords);
}
/**
* Delete the keywords for an entry or an entire application
*
* @param string $app
* @param string|int $id=null
*/
static function delete($app,$id=null)
{
if (!$app)
{
return false;
}
$where = array('si_app' => $app);
if ($id)
{
$where['si_app_id'] = $id;
}
return !!self::$db->delete(self::INDEX_TABLE,$where,__LINE__,__FILE__);
}
/**
* Returns the cats of an entry or multiple entries
*
* @param string $app
* @param string|int|array $ids
* @return array with cats or single id or id => array with cats pairs
*/
static function cats($app,$ids)
{
if (!$app || !$ids)
{
return array();
}
$cats = array();
foreach(self::$db->select(self::INDEX_CAT_TABLE,'cat_id,ce_app_id',array(
'ce_app' => $app,
'ce_app_id' => $ids,
),__LINE__,__FILE__) as $row)
{
$cats[$row['ce_app_id']][] = $row['cat_id'];
}
return is_array($ids) ? $cats : $cats[(int)$ids];
}
/**
* Get the SQL to fetch (eg. as subquery) the id's of a given app matching a keyword
*
* @param string $keyword
* @param string $app
* @return string
*/
static function sql_ids_by_keyword($keyword,$app)
{
return '(SELECT si_id FROM '.self::INDEX_TABLE.' WHERE si_app='.self::$db->quote($app).
' AND si_keyword = '.self::$db->quote($keyword).') UNION '.
'(SELECT ce_id FROM '.self::INDEX_CAT_TABLE.' WHERE si_app='.self::$db->quote($app).
' AND cat_id IN (SELECT cat_id FROM '.self::CAT_TABLE.' WHERE cat_title '.self::$db->capabilities['case_insensitive_like'].' '.
self::$db->quote('%'.$keyword.'%').'))';
}
/**
* Stores one keyword for an entry in the index
*
* @todo reject keywords which are common words ...
* @param string $app
* @param string|int $id
* @param string $keyword
* @param int $owner=null
* @return boolean true if keyword added, false if it was rejected in future
*/
static private function add($app,$id,$keyword,$owner=null)
{
// todo: reject keywords which are common words, not sure how to do that for all languages
// mayby we can come up with some own little statistic analysis:
// all keywords more common then N % of the entries get deleted and moved to a separate table ...
if (!($si = self::$db->select(self::KEYWORD_TABLE, '*', array('si_keyword' => $keyword))->fetch()))
{
self::$db->insert(self::KEYWORD_TABLE, array(
'si_keyword' => $keyword,
), false, __LINE__, __FILE__);
$si_id = self::$db->get_last_insert_id(self::KEYWORD_TABLE, 'si_id');
}
elseif ($si['si_ignore'])
{
return false;
}
else
{
$si_id = $si['si_id'];
}
self::$db->insert(self::INDEX_TABLE,array(
'si_app' => $app,
'si_app_id' => $id,
'si_id' => $si_id,
'si_owner' => $owner,
),false,__LINE__,__FILE__);
return true;
}
/**
* Stores the cat_id(s) for an entry
*
* @param string $app
* @param string|int $id
* @param array|int|string $cat_ids=null optional cat_id(s) either comma-separated or as array
* @param int $owner=null
* @return boolean true on success, false on error
*/
static private function add_cats($app,$id,$cat_ids,$owner=null)
{
if (!$app)
{
return false;
}
if (!$cat_ids)
{
return true; // nothing to do
}
foreach(is_array($cat_ids) ? $cat_ids : explode(',',$cat_ids) as $cat_id)
{
self::$db->insert(self::INDEX_CAT_TABLE,array(
'cat_id' => $cat_id,
'ce_app' => $app,
'ce_app_id' => $id,
'ce_owner' => $owner,
),false,__LINE__,__FILE__);
}
return true;
}
/**
* Delete the cat for an entry or an entire application
*
* @param string $app
* @param string|int $id=null
*/
static private function delete_cats($app,$id=null)
{
if (!$app)
{
return false;
}
$where = array('ce_app' => $app);
if ($id)
{
$where['ce_app_id'] = $id;
}
return !!self::$db->delete(self::INDEX_CAT_TABLE,$where,__LINE__,__FILE__);
}
/**
* Init our static vars
*/
static function _init_static()
{
if (!is_object($GLOBALS['egw_setup']))
{
self::$db = $GLOBALS['egw']->db;
}
else
{
self::$db = $GLOBALS['egw_setup']->db;
}
}
}
egw_index::_init_static();

View File

@ -11,8 +11,8 @@
/* Basic information about this app */
$setup_info['phpgwapi']['name'] = 'phpgwapi';
$setup_info['phpgwapi']['title'] = 'EGroupware old API';
$setup_info['phpgwapi']['version'] = '14.3.908';
$setup_info['phpgwapi']['title'] = 'old EGroupware API';
$setup_info['phpgwapi']['version'] = '14.3.909';
$setup_info['phpgwapi']['versions']['current_header'] = '1.29';
$setup_info['phpgwapi']['enable'] = 3;
$setup_info['phpgwapi']['app_order'] = 1;
@ -22,28 +22,8 @@ $setup_info['phpgwapi']['maintainer'] = $setup_info['phpgwapi']['author'] = arra
'email' => 'egroupware-developers@lists.sourceforge.net',
);
/* The tables this app creates */
$setup_info['phpgwapi']['tables'][] = 'egw_config';
$setup_info['phpgwapi']['tables'][] = 'egw_applications';
$setup_info['phpgwapi']['tables'][] = 'egw_acl';
$setup_info['phpgwapi']['tables'][] = 'egw_accounts';
$setup_info['phpgwapi']['tables'][] = 'egw_preferences';
$setup_info['phpgwapi']['tables'][] = 'egw_access_log';
$setup_info['phpgwapi']['tables'][] = 'egw_languages';
$setup_info['phpgwapi']['tables'][] = 'egw_lang';
$setup_info['phpgwapi']['tables'][] = 'egw_categories';
$setup_info['phpgwapi']['tables'][] = 'egw_history_log';
$setup_info['phpgwapi']['tables'][] = 'egw_async';
$setup_info['phpgwapi']['tables'][] = 'egw_links';
$setup_info['phpgwapi']['tables'][] = 'egw_addressbook';
$setup_info['phpgwapi']['tables'][] = 'egw_addressbook_extra';
$setup_info['phpgwapi']['tables'][] = 'egw_addressbook_lists';
$setup_info['phpgwapi']['tables'][] = 'egw_addressbook2list';
$setup_info['phpgwapi']['tables'][] = 'egw_sqlfs';
$setup_info['phpgwapi']['tables'][] = 'egw_index_keywords';
$setup_info['phpgwapi']['tables'][] = 'egw_index';
$setup_info['phpgwapi']['tables'][] = 'egw_cat2entry';
$setup_info['phpgwapi']['tables'][] = 'egw_locks';
$setup_info['phpgwapi']['tables'][] = 'egw_sqlfs_props';
$setup_info['phpgwapi']['tables'][] = 'egw_customfields';
$setup_info['phpgwapi']['tables'][] = 'egw_sharing';
// old Api depends on new one
$setup_info['phpgwapi']['depends']['api'] = array(
'appname' => 'api',
'versions' => Array('16.1')
);

View File

@ -11,433 +11,4 @@
* @version $Id$
*/
$phpgw_baseline = array(
'egw_config' => array(
'fd' => array(
'config_app' => array('type' => 'ascii','precision' => '16','nullable' => False),
'config_name' => array('type' => 'ascii','precision' => '32','nullable' => False),
'config_value' => array('type' => 'text')
),
'pk' => array('config_app','config_name'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_applications' => array(
'fd' => array(
'app_id' => array('type' => 'auto','precision' => '4','nullable' => False),
'app_name' => array('type' => 'ascii','precision' => '16','nullable' => False),
'app_enabled' => array('type' => 'int','precision' => '4','nullable' => False),
'app_order' => array('type' => 'int','precision' => '4','nullable' => False),
'app_tables' => array('type' => 'ascii','precision' => '8192','nullable' => False),
'app_version' => array('type' => 'ascii','precision' => '20','nullable' => False,'default' => '0.0'),
'app_icon' => array('type' => 'ascii','precision' => '32'),
'app_icon_app' => array('type' => 'ascii','precision' => '16'),
'app_index' => array('type' => 'ascii','precision' => '64')
),
'pk' => array('app_id'),
'fk' => array(),
'ix' => array(array('app_enabled','app_order')),
'uc' => array('app_name')
),
'egw_acl' => array(
'fd' => array(
'acl_appname' => array('type' => 'ascii','precision' => '16','nullable' => False),
'acl_location' => array('type' => 'ascii','meta' => 'account','precision' => '16','nullable' => False),
'acl_account' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False),
'acl_rights' => array('type' => 'int','precision' => '4'),
'acl_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('acl_id'),
'fk' => array(),
'ix' => array('acl_account',array('acl_location','acl_account'),array('acl_appname','acl_account')),
'uc' => array(array('acl_appname','acl_location','acl_account'))
),
'egw_accounts' => array(
'fd' => array(
'account_id' => array('type' => 'auto','meta' => 'account-abs','nullable' => False),
'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False),
'account_pwd' => array('type' => 'varchar','precision' => '128','nullable' => False),
'account_lastlogin' => array('type' => 'int','precision' => '4'),
'account_lastloginfrom' => array('type' => 'ascii','precision' => '48','comment' => 'ip'),
'account_lastpwd_change' => array('type' => 'int','precision' => '4'),
'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'),
'account_expires' => array('type' => 'int','precision' => '4'),
'account_type' => array('type' => 'char','precision' => '1'),
'account_primary_group' => array('type' => 'int','meta' => 'group','precision' => '4','nullable' => False,'default' => '0'),
'account_description' => array('type' => 'varchar','precision' => '255','comment' => 'group description')
),
'pk' => array('account_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('account_lid')
),
'egw_preferences' => array(
'fd' => array(
'preference_owner' => array('type' => 'int','meta' => 'account-prefs','precision' => '4','nullable' => False),
'preference_app' => array('type' => 'ascii','precision' => '16','nullable' => False),
'preference_value' => array('type' => 'text','nullable' => False),
'preference_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('preference_id'),
'fk' => array(),
'ix' => array(),
'uc' => array(array('preference_owner','preference_app'))
),
'egw_access_log' => array(
'fd' => array(
'sessionid' => array('type' => 'auto','nullable' => False,'comment' => 'primary key'),
'loginid' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'username used to login'),
'ip' => array('type' => 'ascii','precision' => '48','nullable' => False,'comment' => 'ip of user'),
'li' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'TS if login'),
'lo' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'TD of logout'),
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0','comment' => 'numerical account id'),
'session_dla' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'TS of last user action'),
'session_action' => array('type' => 'ascii','precision' => '64','comment' => 'menuaction or path of last user action'),
'session_php' => array('type' => 'ascii','precision' => '64','nullable' => False,'comment' => 'php session-id or error-message'),
'notification_heartbeat' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'TS of last notification request'),
'user_agent' => array('type' => 'ascii','precision' => '255','comment' => 'User-agent of browser/device')
),
'pk' => array('sessionid'),
'fk' => array(),
'ix' => array('li','lo','session_dla','session_php','notification_heartbeat',array('account_id','ip','li'),array('account_id','loginid','li')),
'uc' => array()
),
'egw_languages' => array(
'fd' => array(
'lang_id' => array('type' => 'ascii','precision' => '5','nullable' => False),
'lang_name' => array('type' => 'varchar','precision' => '50','nullable' => False)
),
'pk' => array('lang_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_lang' => array(
'fd' => array(
'lang' => array('type' => 'varchar','precision' => '5','nullable' => False,'default' => ''),
'app_name' => array('type' => 'ascii','precision' => '16','nullable' => False,'default' => 'common'),
'message_id' => array('type' => 'ascii','precision' => '128','nullable' => False,'default' => ''),
'content' => array('type' => 'varchar','precision' => '8192'),
'lang_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('lang_id'),
'fk' => array(),
'ix' => array(),
'uc' => array(array('lang','app_name','message_id'))
),
'egw_categories' => array(
'fd' => array(
'cat_id' => array('type' => 'auto','meta' => 'category','precision' => '4','nullable' => False),
'cat_main' => array('type' => 'int','meta' => 'category','precision' => '4','nullable' => False,'default' => '0'),
'cat_parent' => array('type' => 'int','meta' => 'category','precision' => '4','nullable' => False,'default' => '0'),
'cat_level' => array('type' => 'int','precision' => '2','nullable' => False,'default' => '0'),
'cat_owner' => array('type' => 'ascii','meta' => 'account-commasep','precision' => '255','nullable' => False,'default' => '0'),
'cat_access' => array('type' => 'ascii','precision' => '7'),
'cat_appname' => array('type' => 'ascii','precision' => '16','nullable' => False),
'cat_name' => array('type' => 'varchar','precision' => '150','nullable' => False),
'cat_description' => array('type' => 'varchar','precision' => '255','nullable' => False),
'cat_data' => array('type' => 'varchar','precision' => '8192'),
'last_mod' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False)
),
'pk' => array('cat_id'),
'fk' => array(),
'ix' => array(array('cat_appname','cat_owner','cat_parent','cat_level')),
'uc' => array()
),
'egw_history_log' => array(
'fd' => array(
'history_id' => array('type' => 'auto','precision' => '4','nullable' => False),
'history_record_id' => array('type' => 'int','precision' => '4','nullable' => False),
'history_appname' => array('type' => 'ascii','precision' => '16','nullable' => False),
'history_owner' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False),
'history_status' => array('type' => 'varchar','precision' => '32','nullable' => False),
'history_new_value' => array('type' => 'text','nullable' => False),
'history_timestamp' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp'),
'history_old_value' => array('type' => 'text','nullable' => False),
'sessionid' => array('type' => 'int','precision' => '4','comment' => 'primary key to egw_access_log')
),
'pk' => array('history_id'),
'fk' => array(),
'ix' => array(array('history_appname','history_record_id','history_id')),
'uc' => array()
),
'egw_async' => array(
'fd' => array(
'async_id' => array('type' => 'ascii','precision' => '64','nullable' => False),
'async_next' => array('type' => 'int','meta' => 'timestamp','precision' => '4','nullable' => False,'comment' => 'timestamp of next run'),
'async_times' => array('type' => 'ascii','precision' => '255','nullable' => False,'comment' => 'serialized array with values for keys hour,min,day,month,year'),
'async_method' => array('type' => 'ascii','precision' => '80','nullable' => False,'comment' => 'app.class.method class::method to execute'),
'async_data' => array('type' => 'varchar','precision' => '8192','nullable' => False,'comment' => 'serialized array with data to pass to method'),
'async_account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0','comment' => 'creator of job'),
'async_auto_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('async_auto_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('async_id')
),
'egw_links' => array(
'fd' => array(
'link_id' => array('type' => 'auto','nullable' => False),
'link_app1' => array('type' => 'ascii','precision' => '16','nullable' => False),
'link_id1' => array('type' => 'ascii','meta' => array("link_app1='home-accounts'" => 'account'),'precision' => '64','nullable' => False),
'link_app2' => array('type' => 'ascii','precision' => '16','nullable' => False),
'link_id2' => array('type' => 'ascii','meta' => array("link_app2='home-accounts'" => 'account'),'precision' => '64','nullable' => False),
'link_remark' => array('type' => 'varchar','precision' => '100'),
'link_lastmod' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False),
'link_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False),
'deleted' => array('type' => 'timestamp')
),
'pk' => array('link_id'),
'fk' => array(),
'ix' => array('deleted',array('link_app1','link_id1','link_lastmod'),array('link_app2','link_id2','link_lastmod')),
'uc' => array()
),
'egw_addressbook' => array(
'fd' => array(
'contact_id' => array('type' => 'auto','nullable' => False),
'contact_tid' => array('type' => 'char','precision' => '1','default' => 'n'),
'contact_owner' => array('type' => 'int','meta' => 'account','precision' => '8','nullable' => False,'comment' => 'account or group id of the adressbook'),
'contact_private' => array('type' => 'int','precision' => '1','default' => '0','comment' => 'privat or personal'),
'cat_id' => array('type' => 'ascii','meta' => 'category','precision' => '255','comment' => 'Category(s)'),
'n_family' => array('type' => 'varchar','precision' => '64','comment' => 'Family name'),
'n_given' => array('type' => 'varchar','precision' => '64','comment' => 'Given Name'),
'n_middle' => array('type' => 'varchar','precision' => '64'),
'n_prefix' => array('type' => 'varchar','precision' => '64','comment' => 'Prefix'),
'n_suffix' => array('type' => 'varchar','precision' => '64','comment' => 'Suffix'),
'n_fn' => array('type' => 'varchar','precision' => '128','comment' => 'Full name'),
'n_fileas' => array('type' => 'varchar','precision' => '255','comment' => 'sort as'),
'contact_bday' => array('type' => 'varchar','precision' => '12','comment' => 'Birtday'),
'org_name' => array('type' => 'varchar','precision' => '128','comment' => 'Organisation'),
'org_unit' => array('type' => 'varchar','precision' => '64','comment' => 'Department'),
'contact_title' => array('type' => 'varchar','precision' => '64','comment' => 'jobtittle'),
'contact_role' => array('type' => 'varchar','precision' => '64','comment' => 'role'),
'contact_assistent' => array('type' => 'varchar','precision' => '64','comment' => 'Name of the Assistent (for phone number)'),
'contact_room' => array('type' => 'varchar','precision' => '64','comment' => 'room'),
'adr_one_street' => array('type' => 'varchar','precision' => '64','comment' => 'street (business)'),
'adr_one_street2' => array('type' => 'varchar','precision' => '64','comment' => 'street (business) - 2. line'),
'adr_one_locality' => array('type' => 'varchar','precision' => '64','comment' => 'city (business)'),
'adr_one_region' => array('type' => 'varchar','precision' => '64','comment' => 'region (business)'),
'adr_one_postalcode' => array('type' => 'varchar','precision' => '64','comment' => 'postalcode (business)'),
'adr_one_countryname' => array('type' => 'varchar','precision' => '64','comment' => 'countryname (business)'),
'contact_label' => array('type' => 'text','comment' => 'currently not used'),
'adr_two_street' => array('type' => 'varchar','precision' => '64','comment' => 'street (private)'),
'adr_two_street2' => array('type' => 'varchar','precision' => '64','comment' => 'street (private) - 2. line'),
'adr_two_locality' => array('type' => 'varchar','precision' => '64','comment' => 'city (private)'),
'adr_two_region' => array('type' => 'varchar','precision' => '64','comment' => 'region (private)'),
'adr_two_postalcode' => array('type' => 'varchar','precision' => '64','comment' => 'postalcode (private)'),
'adr_two_countryname' => array('type' => 'varchar','precision' => '64','comment' => 'countryname (private)'),
'tel_work' => array('type' => 'varchar','precision' => '40','comment' => 'phone-number (business)'),
'tel_cell' => array('type' => 'varchar','precision' => '40','comment' => 'mobil phone (business)'),
'tel_fax' => array('type' => 'varchar','precision' => '40','comment' => 'fax-number (business)'),
'tel_assistent' => array('type' => 'varchar','precision' => '40','comment' => 'phone-number assistent'),
'tel_car' => array('type' => 'varchar','precision' => '40'),
'tel_pager' => array('type' => 'varchar','precision' => '40','comment' => 'pager'),
'tel_home' => array('type' => 'varchar','precision' => '40','comment' => 'phone-number (private)'),
'tel_fax_home' => array('type' => 'varchar','precision' => '40','comment' => 'fax-number (private)'),
'tel_cell_private' => array('type' => 'varchar','precision' => '40','comment' => 'mobil phone (private)'),
'tel_other' => array('type' => 'varchar','precision' => '40','comment' => 'other phone'),
'tel_prefer' => array('type' => 'varchar','precision' => '32','comment' => 'prefered phone-number'),
'contact_email' => array('type' => 'varchar','precision' => '128','comment' => 'email address (business)'),
'contact_email_home' => array('type' => 'varchar','precision' => '128','comment' => 'email address (private)'),
'contact_url' => array('type' => 'varchar','precision' => '128','comment' => 'website (business)'),
'contact_url_home' => array('type' => 'varchar','precision' => '128','comment' => 'website (private)'),
'contact_freebusy_uri' => array('type' => 'ascii','precision' => '128','comment' => 'freebusy-url for calendar of the contact'),
'contact_calendar_uri' => array('type' => 'ascii','precision' => '128','comment' => 'url for users calendar - currently not used'),
'contact_note' => array('type' => 'varchar','precision' => '8192','comment' => 'notes field'),
'contact_tz' => array('type' => 'varchar','precision' => '8','comment' => 'timezone difference'),
'contact_geo' => array('type' => 'ascii','precision' => '32','comment' => 'currently not used'),
'contact_pubkey' => array('type' => 'ascii','precision' => '16384','comment' => 'public key'),
'contact_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'timestamp of the creation'),
'contact_creator' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'account id of the creator'),
'contact_modified' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'timestamp of the last modified'),
'contact_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'account id of the last modified'),
'contact_jpegphoto' => array('type' => 'blob','comment' => 'photo of the contact (attachment)'),
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'account id'),
'contact_etag' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'etag of the changes'),
'contact_uid' => array('type' => 'ascii','precision' => '128','comment' => 'unique id of the contact'),
'adr_one_countrycode' => array('type' => 'ascii','precision' => '2','comment' => 'countrycode (business)'),
'adr_two_countrycode' => array('type' => 'ascii','precision' => '2','comment' => 'countrycode (private)'),
'carddav_name' => array('type' => 'ascii','precision' => '128','comment' => 'name part of CardDAV URL, if specified by client')
),
'pk' => array('contact_id'),
'fk' => array(),
'ix' => array('contact_owner','cat_id','n_fileas','contact_modified','contact_uid','carddav_name',array('n_family','n_given'),array('n_given','n_family'),array('org_name','n_family','n_given')),
'uc' => array('account_id')
),
'egw_addressbook_extra' => array(
'fd' => array(
'contact_id' => array('type' => 'int','precision' => '4','nullable' => False),
'contact_owner' => array('type' => 'int','meta' => 'account','precision' => '8'),
'contact_name' => array('type' => 'varchar','meta' => 'cfname','precision' => '64','nullable' => False,'comment' => 'custom-field name'),
'contact_value' => array('type' => 'varchar','meta' => 'cfvalue','precision' => '16384','comment' => 'custom-field value'),
'contact_extra_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('contact_extra_id'),
'fk' => array(),
'ix' => array('contact_name',array('contact_id','contact_name')),
'uc' => array()
),
'egw_addressbook_lists' => array(
'fd' => array(
'list_id' => array('type' => 'auto','nullable' => False),
'list_name' => array('type' => 'varchar','precision' => '80','nullable' => False),
'list_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False),
'list_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8'),
'list_creator' => array('type' => 'int','meta' => 'user','precision' => '4'),
'list_uid' => array('type' => 'ascii','precision' => '128'),
'list_carddav_name' => array('type' => 'ascii','precision' => '128'),
'list_etag' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'),
'list_modified' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp'),
'list_modifier' => array('type' => 'int','meta' => 'user','precision' => '4')
),
'pk' => array('list_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('list_uid','list_carddav_name',array('list_owner','list_name'))
),
'egw_addressbook2list' => array(
'fd' => array(
'contact_id' => array('type' => 'int','precision' => '4','nullable' => False),
'list_id' => array('type' => 'int','precision' => '4','nullable' => False),
'list_added' => array('type' => 'int','meta' => 'timestamp','precision' => '8'),
'list_added_by' => array('type' => 'int','meta' => 'user','precision' => '4')
),
'pk' => array('contact_id','list_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
),
'egw_sqlfs' => array(
'fd' => array(
'fs_id' => array('type' => 'auto','nullable' => False),
'fs_dir' => array('type' => 'int','precision' => '4','nullable' => False),
'fs_name' => array('type' => 'varchar','precision' => '200','nullable' => False),
'fs_mode' => array('type' => 'int','precision' => '2','nullable' => False),
'fs_uid' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0'),
'fs_gid' => array('type' => 'int','meta' => 'group-abs','precision' => '4','nullable' => False,'default' => '0'),
'fs_created' => array('type' => 'timestamp','precision' => '8','nullable' => False),
'fs_modified' => array('type' => 'timestamp','precision' => '8','nullable' => False),
'fs_mime' => array('type' => 'ascii','precision' => '96','nullable' => False),
'fs_size' => array('type' => 'int','precision' => '8','nullable' => False),
'fs_creator' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False),
'fs_modifier' => array('type' => 'int','meta' => 'user','precision' => '4'),
'fs_active' => array('type' => 'bool','nullable' => False,'default' => 't'),
'fs_content' => array('type' => 'blob'),
'fs_link' => array('type' => 'varchar','precision' => '255')
),
'pk' => array('fs_id'),
'fk' => array(),
'ix' => array(array('fs_dir','fs_active','fs_name(16)')),
'uc' => array()
),
'egw_index_keywords' => array(
'fd' => array(
'si_id' => array('type' => 'auto','nullable' => False),
'si_keyword' => array('type' => 'varchar','precision' => '64','nullable' => False),
'si_ignore' => array('type' => 'bool')
),
'pk' => array('si_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('si_keyword')
),
'egw_index' => array(
'fd' => array(
'si_app' => array('type' => 'varchar','precision' => '25','nullable' => False),
'si_app_id' => array('type' => 'varchar','precision' => '50','nullable' => False),
'si_id' => array('type' => 'int','precision' => '4','nullable' => False),
'si_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False)
),
'pk' => array('si_app','si_app_id','si_id'),
'fk' => array(),
'ix' => array('si_id'),
'uc' => array()
),
'egw_cat2entry' => array(
'fd' => array(
'ce_app' => array('type' => 'varchar','precision' => '25','nullable' => False),
'ce_app_id' => array('type' => 'varchar','precision' => '50','nullable' => False),
'cat_id' => array('type' => 'int','meta' => 'category','precision' => '4','nullable' => False),
'ce_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False)
),
'pk' => array('ce_app','ce_app_id','cat_id'),
'fk' => array(),
'ix' => array('cat_id'),
'uc' => array()
),
'egw_locks' => array(
'fd' => array(
'lock_token' => array('type' => 'ascii','precision' => '64','nullable' => False),
'lock_path' => array('type' => 'varchar','precision' => '255','nullable' => False),
'lock_expires' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False),
'lock_owner' => array('type' => 'varchar','precision' => '255'),
'lock_recursive' => array('type' => 'bool','nullable' => False,'default' => '0'),
'lock_write' => array('type' => 'bool','nullable' => False,'default' => '0'),
'lock_exclusive' => array('type' => 'bool','nullable' => False,'default' => '0'),
'lock_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','default' => '0'),
'lock_modified' => array('type' => 'int','meta' => 'timestamp','precision' => '8','default' => '0'),
'lock_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('lock_id'),
'fk' => array(),
'ix' => array('lock_path','lock_expires'),
'uc' => array('lock_token')
),
'egw_sqlfs_props' => array(
'fd' => array(
'fs_id' => array('type' => 'int','precision' => '4','nullable' => False),
'prop_namespace' => array('type' => 'ascii','precision' => '64','nullable' => False),
'prop_name' => array('type' => 'ascii','precision' => '64','nullable' => False),
'prop_value' => array('type' => 'varchar','precision' => '16384'),
'prop_id' => array('type' => 'auto','nullable' => False)
),
'pk' => array('prop_id'),
'fk' => array(),
'ix' => array(array('fs_id','prop_namespace','prop_name')),
'uc' => array()
),
'egw_customfields' => array(
'fd' => array(
'cf_id' => array('type' => 'auto','nullable' => False),
'cf_app' => array('type' => 'ascii','precision' => '16','nullable' => False,'comment' => 'app-name cf belongs too'),
'cf_name' => array('type' => 'varchar','precision' => '128','nullable' => False,'comment' => 'internal name'),
'cf_label' => array('type' => 'varchar','precision' => '128','comment' => 'label to display'),
'cf_type' => array('type' => 'varchar','precision' => '64','nullable' => False,'default' => 'text','comment' => 'type of field'),
'cf_type2' => array('type' => 'varchar','precision' => '2048','comment' => 'comma-separated subtypes of app, cf is valid for'),
'cf_help' => array('type' => 'varchar','precision' => '256','comment' => 'helptext'),
'cf_values' => array('type' => 'varchar','precision' => '8096','comment' => 'json object with value label pairs'),
'cf_len' => array('type' => 'int','precision' => '2','comment' => 'length or columns of field'),
'cf_rows' => array('type' => 'int','precision' => '2','comment' => 'rows of field'),
'cf_order' => array('type' => 'int','precision' => '2','comment' => 'order to display fields'),
'cf_needed' => array('type' => 'bool','default' => '0','comment' => 'field is required'),
'cf_private' => array('type' => 'ascii','meta' => 'account-commasep','precision' => '2048','comment' => 'comma-separated account_id'),
'cf_modifier' => array('type' => 'int','meta' => 'account','precision' => '4','comment' => 'last modifier'),
'cf_modified' => array('type' => 'timestamp','default' => 'current_timestamp','comment' => 'last modification time'),
'cf_tab' => array('type' => 'varchar','precision' => '64','comment' => 'tab customfield should be shown')
),
'pk' => array('cf_id'),
'fk' => array(),
'ix' => array(array('cf_app','cf_order')),
'uc' => array(array('cf_app','cf_name'))
),
'egw_sharing' => array(
'fd' => array(
'share_id' => array('type' => 'auto','nullable' => False,'comment' => 'auto-id'),
'share_token' => array('type' => 'ascii','precision' => '64','nullable' => False,'comment' => 'secure token'),
'share_path' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'path to share'),
'share_owner' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'owner of share'),
'share_expires' => array('type' => 'date','comment' => 'expire date of share'),
'share_writable' => array('type' => 'int','precision' => '1','nullable' => False,'default' => '0','comment' => '0=readable, 1=writable'),
'share_with' => array('type' => 'varchar','precision' => '4096','comment' => 'email addresses, comma seperated'),
'share_passwd' => array('type' => 'varchar','precision' => '128','comment' => 'optional password-hash'),
'share_created' => array('type' => 'timestamp','nullable' => False,'comment' => 'creation date'),
'share_last_accessed' => array('type' => 'timestamp','comment' => 'last access of share')
),
'pk' => array('share_id'),
'fk' => array(),
'ix' => array(),
'uc' => array('share_token')
)
);
$phpgw_baseline = array();

View File

@ -1052,7 +1052,7 @@ function phpgwapi_upgrade14_3_906()
}
/**
* Move content of (usually empty or for LDAP 2 rows) egw_nextid table to egw_config table and drop it
* Drop no longer used egw_hooks table
*/
function phpgwapi_upgrade14_3_907()
{
@ -1060,3 +1060,17 @@ function phpgwapi_upgrade14_3_907()
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '14.3.908';
}
/**
* Drop never used index tables
*/
function phpgwapi_upgrade14_3_908()
{
$GLOBALS['egw_setup']->oProc->DropTable('egw_index_keywords');
$GLOBALS['egw_setup']->oProc->DropTable('egw_index');
$GLOBALS['egw_setup']->oProc->DropTable('egw_cat2entry');
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '14.3.909';
}

View File

@ -68,7 +68,7 @@ $bgcolor = array('#DDDDDD','#EEEEEE');
function parsedep($depends,$main=True)
{
$depstring = '(';
foreach($depends as $a => $b)
foreach($depends as $b)
{
foreach($b as $c => $d)
{
@ -98,14 +98,11 @@ function parsedep($depends,$main=True)
$GLOBALS['egw_setup']->loaddb();
$GLOBALS['egw_info']['setup']['stage']['db'] = $GLOBALS['egw_setup']->detection->check_db();
$setup_info = $GLOBALS['egw_setup']->detection->get_versions();
//var_dump($setup_info);exit;
$setup_info = $GLOBALS['egw_setup']->detection->get_db_versions($setup_info);
//var_dump($setup_info);exit;
$setup_info = $GLOBALS['egw_setup']->detection->compare_versions($setup_info);
//var_dump($setup_info);exit;
$setup_info = $GLOBALS['egw_setup']->detection->check_depends($setup_info);
//var_dump($setup_info);exit;
$setup_info = $GLOBALS['egw_setup']->detection->check_depends(
$GLOBALS['egw_setup']->detection->compare_versions(
$GLOBALS['egw_setup']->detection->get_db_versions(
$GLOBALS['egw_setup']->detection->get_versions())));
@ksort($setup_info);
if(@get_var('cancel',Array('POST')))
@ -172,8 +169,8 @@ if(@get_var('submit',Array('POST')))
if ($setup_info[$appname]['tables'])
{
$terror = $GLOBALS['egw_setup']->process->current($terror,$DEBUG);
$terror = $GLOBALS['egw_setup']->process->default_records($terror,$DEBUG);
$terror_c = $GLOBALS['egw_setup']->process->current($terror, $DEBUG);
$terror = $GLOBALS['egw_setup']->process->default_records($terror_c, $DEBUG);
echo '<br />' . $app_title . ' '
. lang('tables installed, unless there are errors printed above') . '.';
}
@ -193,7 +190,7 @@ if(@get_var('submit',Array('POST')))
if ($setup_info[$appname]['hooks'])
{
$GLOBALS['egw_setup']->register_hooks($setup_info[$appname]['name']);
Api\Hooks::read(true);
echo '<br />' . $app_title . ' ' . lang('hooks registered') . '.';
}
}
@ -233,14 +230,9 @@ else
if(@get_var('hooks', Array('GET')))
{
egw_cache::flush(egw_cache::INSTANCE);
Api\Cache::flush(Api\Cache::INSTANCE);
// Find & register all application hooks
foreach($setup_info as $appname => $info)
{
if ($info['currentver']) $GLOBALS['egw_setup']->register_hooks($appname);
}
echo lang('All hooks registered') . '<br />';
echo lang('Cached cleared') . '<br />';
}
$detail = get_var('detail',Array('GET'));
$resolve = get_var('resolve',Array('GET'));
@ -256,29 +248,44 @@ if(@$detail)
foreach($setup_info[$detail] as $key => $val)
{
if($key != 'title')
{
$i = ($i ? 0 : 1);
if ($key == 'tables')
switch($key)
{
case 'title':
continue 2;
case 'tables':
$tblcnt = count($setup_info[$detail][$key]);
if(is_array($val))
{
$key = '<a href="sqltoarray.php?appname=' . $detail . '&submit=True&apps=True">' . $key . '(' . $tblcnt . ')</a>' . "\n";
$val = implode(',' . "\n",$val);
}
break;
case 'hooks':
foreach($val as &$hooks)
{
$hooks = (array)$hooks;
}
if ($key == 'hooks') { $val = implode(',',$val); }
if ($key == 'depends') { $val = parsedep($val); }
if (is_array($val)) { $val = implode(',',$val); }
$setup_tpl->set_var('bg_color',$bgcolor[$i]);
$val = str_replace('EGroupware\\', '', implode(', ', call_user_func_array('array_merge', $val)));
break;
case 'depends':
foreach($val as &$dep)
{
$dep = $dep['appname'].': '.implode(', ', $dep['versions']);
}
$val = implode('; ', $val);
break;
case 'check_install':
$val = array2string($val);
break;
default:
if (is_array($val)) $val = implode(', ', $val);
break;
}
$setup_tpl->set_var('bg_color', $bgcolor[++$i & 1]);
$setup_tpl->set_var('name',$key);
$setup_tpl->set_var('details',$val);
$setup_tpl->pparse('out','detail');
}
}
echo '<br /><a href="applications.php?debug='.$DEBUG.'">' . lang('Go back') . '</a>';
$setup_tpl->pparse('out','footer');
@ -345,8 +352,7 @@ elseif (@$resolve)
{
$list .= $y . ', ';
}
$list = substr($list,0,-2);
echo "$list\n";
echo substr($list,0,-2)."\n";
}
echo '<br /><br />' . lang('The table definition was correct, and the tables were installed') . '.';
}
@ -423,7 +429,7 @@ else
switch($value['status'])
{
case 'C':
$setup_tpl->set_var('remove',$key == 'phpgwapi' ? '&nbsp;' : '<input type="checkbox" name="remove[' . $value['name'] . ']" />');
$setup_tpl->set_var('remove', in_array($key, array('api', 'phpgwapi')) ? '&nbsp;' : '<input type="checkbox" name="remove[' . $value['name'] . ']" />');
$setup_tpl->set_var('upgrade','&nbsp;');
if (!$GLOBALS['egw_setup']->detection->check_app_tables($value['name']))
{

View File

@ -103,10 +103,9 @@ if($GLOBALS['error'] && is_array($newsettings))
}
else
{
$GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'*',false,__LINES__,__FILES__);
while($GLOBALS['egw_setup']->db->next_record())
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'*',false,__LINES__,__FILES__) as $row)
{
$GLOBALS['current_config'][$GLOBALS['egw_setup']->db->f('config_name')] = $GLOBALS['egw_setup']->db->f('config_value');
$GLOBALS['current_config'][$row['config_name']] = $row['config_value'];
}
}
$setup_tpl->pparse('out','T_config_pre_script');

View File

@ -114,13 +114,14 @@ class setup
}
try {
$GLOBALS['egw']->db = $this->db = new egw_db($GLOBALS['egw_domain'][$this->ConfigDomain]);
$GLOBALS['egw']->db = $this->db = new Api\Db\Deprecated($GLOBALS['egw_domain'][$this->ConfigDomain]);
$this->db->connect();
}
catch (Exception $e) {
unset($e);
return;
}
$this->db->set_app('phpgwapi');
$this->db->set_app(Api\Db::API_APPNAME);
if ($connect_and_setcharset)
{
@ -128,22 +129,19 @@ class setup
$this->set_table_names(); // sets/checks config- and applications-table-name
// Set the DB's client charset if a system-charset is set
$this->db->select($this->config_table,'config_value',array(
if (($this->system_charset = $this->db->select($this->config_table,'config_value',array(
'config_app' => 'phpgwapi',
'config_name' => 'system_charset',
),__LINE__,__FILE__);
if ($this->db->next_record() && $this->db->f(0))
),__LINE__,__FILE__)->fetchColumn()))
{
$this->system_charset = $this->db->f(0);
$this->db_charset_was = $this->db->Link_ID->GetCharSet(); // needed for the update
// we can NOT set the DB charset for mysql, if the api version < 1.0.1.019, as it would mess up the DB content!!!
if (substr($this->db->Type,0,5) == 'mysql') // we need to check the api version
{
$this->db->select($this->applications_table,'app_version',array(
$api_version = $this->db->select($this->applications_table,'app_version',array(
'app_name' => 'phpgwapi',
),__LINE__,__FILE__);
$api_version = $this->db->next_record() ? $this->db->f(0) : false;
),__LINE__,__FILE__)->fetchColumn();
}
if (!$api_version || !$this->alessthanb($api_version,'1.0.1.019'))
{
@ -454,12 +452,13 @@ class setup
/**
* Add an application to the phpgw_applications table
*
* @param $appname Application 'name' with a matching $setup_info[$appname] array slice
* @param string $appname Application 'name' with a matching $setup_info[$appname] array slice
* @param $_enable =99 set to True/False to override setup.inc.php setting
* @param array $setup_info =null default use $GLOBALS['setup_info']
*/
function register_app($appname, $_enable=99)
function register_app($appname, $_enable=99, array $setup_info=null)
{
$setup_info = $GLOBALS['setup_info'];
if (!isset($setup_info)) $setup_info = $GLOBALS['setup_info'];
if(!$appname)
{
@ -530,8 +529,7 @@ class setup
// _debug_array($setup_info[$appname]);
}
$this->db->select($this->applications_table,'COUNT(*)',array('app_name' => $appname),__LINE__,__FILE__);
if($this->db->next_record() && $this->db->f(0))
if ($this->db->select($this->applications_table,'COUNT(*)',array('app_name' => $appname),__LINE__,__FILE__)->fetchColumn())
{
if(@$GLOBALS['DEBUG'])
{
@ -549,12 +547,12 @@ class setup
/**
* Update application info in the db
*
* @param $appname Application 'name' with a matching $setup_info[$appname] array slice
* @param $enabled optional, set to False to not enable this app
* @param string $appname Application 'name' with a matching $setup_info[$appname] array slice
* @param array $setup_info =null default use $GLOBALS['setup_info']
*/
function update_app($appname)
function update_app($appname, array $setup_info=null)
{
$setup_info = $GLOBALS['setup_info'];
if (!isset($setup_info)) $setup_info = $GLOBALS['setup_info'];
if(!$appname)
{
@ -631,16 +629,16 @@ class setup
}
// Remove categories
$this->db->delete(categories::TABLE, array('cat_appname'=>$appname),__LINE__,__FILE__);
categories::invalidate_cache($appname);
$this->db->delete(Api\Categories::TABLE, array('cat_appname'=>$appname),__LINE__,__FILE__);
Api\Categories::invalidate_cache($appname);
// Remove config
$this->db->delete(config::TABLE, array('config_app'=>$appname),__LINE__,__FILE__);
$this->db->delete(Api\Config::TABLE, array('config_app'=>$appname),__LINE__,__FILE__);
//echo 'DELETING application: ' . $appname;
$this->db->delete($this->applications_table,array('app_name'=>$appname),__LINE__,__FILE__);
// Remove links to the app
egw_link::unlink(0, $appname);
Api\Link::unlink(0, $appname);
$this->clear_session_cache();
}
@ -731,32 +729,6 @@ class setup
return true;
}
/**
* Update an application's hooks
*
* @param $appname Application 'name' with a matching $setup_info[$appname] array slice
*/
function update_hooks($appname)
{
$this->register_hooks($appname);
}
/**
* de-Register an application's hooks
*
* @param $appname Application 'name' with a matching $setup_info[$appname] array slice
* @return boolean|int false on error or number of removed hooks
*/
function deregister_hooks($appname)
{
if(!$appname)
{
return False;
}
Api\Hooks::read(true);
}
/**
* call the hooks for a single application
*
@ -961,7 +933,7 @@ class setup
}
}
try {
$this->accounts = new accounts($config);
$this->accounts = new Api\Accounts($config);
}
catch (Exception $e) {
echo "<p><b>".$e->getMessage()."</b></p>\n";

View File

@ -62,20 +62,19 @@ class setup_detection
/* one of these tables exists. checking for post/pre beta version */
if($GLOBALS['egw_setup']->applications_table != 'applications')
{
$GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->applications_table,'*',false,__LINE__,__FILE__);
while(@$GLOBALS['egw_setup']->db->next_record())
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->applications_table,'*',false,__LINE__,__FILE__) as $row)
{
$app = $GLOBALS['egw_setup']->db->f('app_name');
$app = $row['app_name'];
if (!isset($setup_info[$app])) // app source no longer there
{
$setup_info[$app] = array(
'name' => $app,
'tables' => $GLOBALS['egw_setup']->db->f('app_tables'),
'tables' => $row['app_tables'],
'version' => 'deleted',
);
}
$setup_info[$app]['currentver'] = $GLOBALS['egw_setup']->db->f('app_version');
$setup_info[$app]['enabled'] = $GLOBALS['egw_setup']->db->f('app_enabled');
$setup_info[$app]['currentver'] = $row['app_version'];
$setup_info[$app]['enabled'] = $row['app_enabled'];
}
/* This is to catch old setup installs that did not have phpgwapi listed as an app */
$tmp = @$setup_info['phpgwapi']['version']; /* save the file version */
@ -98,14 +97,13 @@ class setup_detection
}
else
{
$GLOBALS['egw_setup']->db->query('select * from applications');
while(@$GLOBALS['egw_setup']->db->next_record())
foreach($GLOBALS['egw_setup']->db->query('select * from applications') as $row)
{
if($GLOBALS['egw_setup']->db->f('app_name') == 'admin')
if($row['app_name'] == 'admin')
{
$setup_info['phpgwapi']['currentver'] = $GLOBALS['egw_setup']->db->f('app_version');
$setup_info['phpgwapi']['currentver'] = $row['app_version'];
}
$setup_info[$GLOBALS['egw_setup']->db->f('app_name')]['currentver'] = $GLOBALS['egw_setup']->db->f('app_version');
$setup_info[$row['app_name']]['currentver'] = $row['app_version'];
}
}
}
@ -316,10 +314,24 @@ class setup_detection
{
$setup_info = $this->get_db_versions($setup_info);
}
//_debug_array($setup_info);
if (isset($setup_info['phpgwapi']['currentver']))
// first check new api installed and up to date
if (isset($setup_info['api']['currentver']))
{
if(@$setup_info['phpgwapi']['currentver'] == @$setup_info['phpgwapi']['version'])
if($setup_info['api']['currentver'] == $setup_info['api']['version'])
{
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables Complete)';
return 10;
}
else
{
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables need upgrading)';
return 4;
}
}
// then check old phpgwapi
elseif (isset($setup_info['phpgwapi']['currentver']))
{
if($setup_info['phpgwapi']['currentver'] == $setup_info['phpgwapi']['version'])
{
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables Complete)';
return 10;
@ -340,6 +352,7 @@ class setup_detection
return 3;
}
catch (Api\Db\Exception $e) {
unset($e);
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Create Database)';
return 1;
}
@ -359,10 +372,10 @@ class setup_detection
}
try { // catch db errors
$GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'config_name,config_value',array('config_app' => 'phpgwapi'),__LINE__,__FILE__);
while($GLOBALS['egw_setup']->db->next_record())
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,
'config_name,config_value',array('config_app' => 'phpgwapi'),__LINE__,__FILE__) as $row)
{
$config[$GLOBALS['egw_setup']->db->f(0)] = $GLOBALS['egw_setup']->db->f(1);
$config[$row['config_name']] = $row['config_value'];
}
}
catch (Api\Db\Exception $e) {
@ -432,46 +445,9 @@ class setup_detection
return 10;
}
function check_lang($check = True)
{
if($check && $GLOBALS['egw_info']['setup']['stage']['db'] != 10)
{
return '';
}
if (!$check)
{
$GLOBALS['setup_info'] = $GLOBALS['egw_setup']->detection->get_db_versions($GLOBALS['setup_info']);
}
try {
$GLOBALS['egw_setup']->db->query($q = "SELECT DISTINCT lang FROM {$GLOBALS['egw_setup']->lang_table}",__LINE__,__FILE__);
}
catch (Api\Db\Exception $e) {
// ignore db error
}
if($e || $GLOBALS['egw_setup']->db->num_rows() == 0)
{
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 3 (No languages installed)';
return 1;
}
while(@$GLOBALS['egw_setup']->db->next_record())
{
$GLOBALS['egw_info']['setup']['installed_langs'][$GLOBALS['egw_setup']->db->f('lang')] = $GLOBALS['egw_setup']->db->f('lang');
}
foreach($GLOBALS['egw_info']['setup']['installed_langs'] as $value)
{
$sql = "SELECT lang_name FROM {$GLOBALS['egw_setup']->languages_table} WHERE lang_id = '".$value."'";
$GLOBALS['egw_setup']->db->query($sql);
if ($GLOBALS['egw_setup']->db->next_record())
{
$GLOBALS['egw_info']['setup']['installed_langs'][$value] = $GLOBALS['egw_setup']->db->f('lang_name');
}
}
$GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 3 (Completed)';
return 10;
}
/**
* Verify that all of an app's tables exist in the db
*
* @param $appname
* @param $any optional, set to True to see if any of the apps tables are installed
*/

View File

@ -55,27 +55,45 @@ class setup_process
* @param array $setup_info array of application info from setup.inc.php files
* @param string $type='new' defaults to new(install), could also be 'upgrade'
* @param boolean $DEBUG=false print debugging info
* @param boolean $force_en=false install english language files
* @param boolean $force_en=false install english language files, not used anymore
* @param string $system_charset=null charset to use
* @param array $preset_config=array()
*/
function pass(array $setup_info,$method='new',$DEBUG=False,$force_en=False,$preset_config=array())
{
unset($force_en); // no longer used
if(!$method)
{
return False;
}
// Place api first
// update to 16.x with no api installed yet
if ($method == 'upgrade' && !isset($setup_info['api']['currentver']))
{
// remove api dependency
unset($setup_info['phpgwapi']['depends']['api']);
$pass['phpgwapi'] = $setup_info['phpgwapi'];
$pass['emailadmin'] = $setup_info['emailadmin'];
$pass['api'] = $setup_info['api'];
// mark api as already installed in version 14.3.907
$setup_info['api']['version'] = $setup_info['api']['currentversion'] = '14.3.907';
$GLOBALS['egw_setup']->register_app('api', 99, $setup_info);
$setup_info['api']['version'] = $pass['api']['version'];
}
// new install or upgrade after 16.x api is installed
else
{
$pass['api'] = $setup_info['api'];
$pass['phpgwapi'] = $setup_info['phpgwapi'];
}
$pass['admin'] = $setup_info['admin'];
$pass['preferences'] = $setup_info['preferences'];
$pass['etemplate'] = $setup_info['etemplate']; // helps to minimize passes, as many apps depend on it
@reset($setup_info);
$setup_info = $GLOBALS['egw_setup']->detection->get_versions($setup_info);
@reset($setup_info);
// setting api-target-version for general use
$this->api_version_target = $setup_info['phpgwapi']['version'];
$this->api_version_target = $setup_info['api']['version'];
$i = 1;
$passed = array();
@ -86,14 +104,13 @@ class setup_process
{
$passing = array();
if($DEBUG) { echo '<br>process->pass(): #' . $i . ' for ' . $method . ' processing' . "\n"; }
/* Check current versions and dependencies */
$setup_info = $GLOBALS['egw_setup']->detection->get_db_versions($setup_info);
$setup_info = $GLOBALS['egw_setup']->detection->compare_versions($setup_info,true);
//_debug_array($setup_info);exit;
$setup_info = $GLOBALS['egw_setup']->detection->check_depends($setup_info);
//if($i==2) { _debug_array($passed);exit; }
/* stuff the rest of the apps, but only those with available upgrades */
// Check current versions and dependencies
$setup_info = $GLOBALS['egw_setup']->detection->check_depends(
$GLOBALS['egw_setup']->detection->compare_versions(
$GLOBALS['egw_setup']->detection->get_db_versions($setup_info), true));
// stuff the rest of the apps, but only those with available upgrades
foreach($setup_info as $key => $value)
{
// check if app is either installed or supports the used database
@ -103,7 +120,7 @@ class setup_process
{
continue; // app does not support this db-type, dont try installing it
}
if($value['name'] != 'phpgwapi' && $value['status'] == 'U')
if(/*$value['name'] != 'phpgwapi' &&*/ $value['status'] == 'U')
{
if($passed[$value['name']]['status'] != 'F' && $passed[$value['name']]['status'] != 'C')
{
@ -116,9 +133,9 @@ class setup_process
{
case 'new':
/* Create tables and insert new records for each app in this list */
$passing = $this->current($pass,$DEBUG);
$passing_c = $this->current($pass,$DEBUG);
if (isset($pass['phpgwapi'])) $this->save_minimal_config($preset_config);
$passing = $this->default_records($passing,$DEBUG);
$passing = $this->default_records($passing_c,$DEBUG);
break;
case 'upgrade':
/* Run upgrade scripts on each app in the list */
@ -128,7 +145,6 @@ class setup_process
default:
/* What the heck are you doing? */
return False;
break;
}
$pass = array();
@ -170,23 +186,21 @@ class setup_process
$passing_string = implode (':', $passing);
}
try {
// flush instance cache
egw_cache::flush(egw_cache::INSTANCE);
// delete image-map, in case new apps get installed, or existing ones updated
common::delete_image_map();
// flush instance cache: also registers hooks and flushes image cache
Api\Cache::flush(Api\Cache::INSTANCE);
}
catch(Exception $e) {
unset($e);
// ignore exception, as during a new install, there's no cache configured and therefore no need to unset
}
/* now return the list */
return $setup_info = array_merge($setup_info,$passed);
return array_merge($setup_info,$passed);
}
/**
* saves a minimal default config, so you get a running install without entering and saveing Step #2 config
*
* @param array $preset_config=array()
* @param array $preset_config =array()
*/
function save_minimal_config(array $preset_config=array())
{
@ -272,6 +286,7 @@ class setup_process
}
catch(Exception $e)
{
unset($e);
// do nothing if new DateTimeZone fails (eg. 'System/Localtime' returned), specially do NOT store it!
error_log(__METHOD__."() NO valid 'date.timezone' set in your php.ini!");
}
@ -281,6 +296,7 @@ class setup_process
// use securest password hash by default
require_once EGW_SERVER_ROOT.'/setup/inc/hook_config.inc.php'; // for sql_passwdhashes, to get securest available password hash
$securest = null;
sql_passwdhashes(array(), true, $securest);
$current_config['sql_encryption_type'] = $current_config['ldap_encryption_type'] = $securest;
@ -310,8 +326,8 @@ class setup_process
// so the default_records use the current data
$GLOBALS['egw_info']['server'] = array_merge((array)$GLOBALS['egw_info']['server'], $current_config);
egw_cache::flush(); // flush whole instance cache
config::init_static(); // flush internal cache of config class
Api\Cache::flush(); // flush whole instance cache
Api\Config::init_static(); // flush internal cache of config class
$GLOBALS['egw_setup']->setup_account_object($current_config);
}
@ -368,7 +384,7 @@ class setup_process
* process current table setup in each application/setup dir
*
* @param array $setup_info array of application info from setup.inc.php files, etc.
* @param boolean $DEBUG=false output further diagnostics
* @param boolean $DEBUG =false output further diagnostics
* @return array $setup_info
*/
function current(array $setup_info,$DEBUG=False)
@ -390,6 +406,7 @@ class setup_process
if($appdata['tables'] && file_exists($appdir.'tables_current.inc.php'))
{
if($DEBUG) { echo '<br>process->current(): Including: ' . $appdir.'tables_current.inc.php'; }
$phpgw_baseline = null;
include ($appdir.'tables_current.inc.php');
$ret = $this->post_process($phpgw_baseline,$DEBUG);
if($ret)
@ -397,12 +414,10 @@ class setup_process
if($GLOBALS['egw_setup']->app_registered($appname))
{
$GLOBALS['egw_setup']->update_app($appname);
$GLOBALS['egw_setup']->update_hooks($appname);
}
else
{
$GLOBALS['egw_setup']->register_app($appname);
$GLOBALS['egw_setup']->register_hooks($appname);
$GLOBALS['egw_setup']->set_default_preferences($appname);
}
// Update the array values for return below
@ -430,12 +445,10 @@ class setup_process
if($GLOBALS['egw_setup']->app_registered($appname))
{
$GLOBALS['egw_setup']->update_app($appname);
$GLOBALS['egw_setup']->update_hooks($appname);
}
else
{
$GLOBALS['egw_setup']->register_app($appname,$enabled);
$GLOBALS['egw_setup']->register_hooks($appname);
$GLOBALS['egw_setup']->set_default_preferences($appname);
}
$appdata['status'] = 'C';
@ -443,6 +456,9 @@ class setup_process
if($DEBUG) { echo '<br>process->current(): Outgoing status: ' . $appname . ',status: '. $appdata['status']; }
}
// update hooks
Api\Hooks::read(true);
/* Done, return current status */
return $setup_info;
}
@ -451,7 +467,7 @@ class setup_process
* process default_records.inc.php in each application/setup dir
*
* @param array $setup_info array of application info from setup.inc.php files, etc.
* @param boolean $DEBUG=false output further diagnostics
* @param boolean $DEBUG =false output further diagnostics
* @return array $setup_info
*/
function default_records(array $setup_info,$DEBUG=False)
@ -478,6 +494,8 @@ class setup_process
}
/* $appdata['status'] = 'C'; */
}
unset($appdata, $oProc);
// Clear categories cache in case app adds categories
categories::invalidate_cache();
@ -491,7 +509,7 @@ class setup_process
* This data should work with the baseline tables
*
* @param array $setup_info array of application info from setup.inc.php files, etc.
* @param boolean $DEBUG=false output further diagnostics
* @param boolean $DEBUG =false output further diagnostics
* @return array $setup_info
*/
function test_data(array $setup_info,$DEBUG=False)
@ -515,6 +533,7 @@ class setup_process
$GLOBALS['egw_setup']->oProc->m_odb->transaction_commit();
}
}
unset($appdata);
/* Done, return current status */
return ($setup_info);
@ -524,7 +543,7 @@ class setup_process
* process baseline table setup in each application/setup dir
*
* @param array $setup_info array of application info from setup.inc.php files, etc.
* @param boolean $DEBUG=false output further diagnostics
* @param boolean $DEBUG =false output further diagnostics
* @return array $setup_info
*/
function baseline(array $setup_info,$DEBUG=False)
@ -543,6 +562,7 @@ class setup_process
{
echo '<br>process->baseline(): Including baseline tables for ' . $appname . "\n";
}
$phpgw_baseline = null;
include ($appdir.'tables_baseline.inc.php');
$GLOBALS['egw_setup']->oProc->GenerateScripts($phpgw_baseline, $DEBUG);
$this->post_process($phpgw_baseline,$DEBUG);
@ -559,6 +579,7 @@ class setup_process
//$setup_info[$key]['status'] = 'C';
}
}
unset($appdata);
/* Done, return current status */
return ($setup_info);
@ -568,7 +589,7 @@ class setup_process
* process available upgrades in each application/setup dir
*
* @param array $setup_info array of application info from setup.inc.php files, etc.
* @param boolean $DEBUG=false output further diagnostics
* @param boolean $DEBUG =false output further diagnostics
* @return array $setup_info
*/
function upgrade($setup_info,$DEBUG=False)
@ -589,8 +610,8 @@ class setup_process
if (isset($appdata['autoinstall']) && ($appdata['autoinstall'] === true ||
$appdata['autoinstall'] === $this->api_version_target))
{
$info = $this->current(array($appname => $appdata),$DEBUG);
$info = $this->default_records($info,$DEBUG);
$info_c = $this->current(array($appname => $appdata), $DEBUG);
$info = $this->default_records($info_c, $DEBUG);
$appdata = $info[$appname];
continue;
}
@ -677,12 +698,10 @@ class setup_process
if($GLOBALS['egw_setup']->app_registered($appname))
{
$GLOBALS['egw_setup']->update_app($appname);
$GLOBALS['egw_setup']->update_hooks($appname);
}
else
{
$GLOBALS['egw_setup']->register_app($appname);
$GLOBALS['egw_setup']->register_hooks($appname);
}
}
@ -703,6 +722,9 @@ class setup_process
$appdate['status'] = $appstatus;
}
// update hooks
Api\Hooks::read(true);
/* Done, return current status */
return $setup_info;
}
@ -737,7 +759,8 @@ class setup_process
$this->init_process();
}
$GLOBALS['egw_setup']->oProc->m_oTranslator->_GetColumns($GLOBALS['egw_setup']->oProc, $tablename, $sColumns, $sColumnName);
$sColumns = null;
$GLOBALS['egw_setup']->oProc->m_oTranslator->_GetColumns($GLOBALS['egw_setup']->oProc, $tablename, $sColumns);
while(list($key,$tbldata) = each($GLOBALS['egw_setup']->oProc->m_oTranslator->sCol))
{

View File

@ -86,8 +86,9 @@ $setup_info = $GLOBALS['egw_setup']->detection->get_versions();
$GLOBALS['egw_info']['setup']['stage']['db'] = $GLOBALS['egw_setup']->detection->check_db($setup_info);
if ($GLOBALS['egw_info']['setup']['stage']['db'] != 1)
{
$setup_info = $GLOBALS['egw_setup']->detection->get_versions();
$setup_info = $GLOBALS['egw_setup']->detection->get_db_versions($setup_info);
$setup_info = $GLOBALS['egw_setup']->detection->get_db_versions(
$GLOBALS['egw_setup']->detection->get_versions());
$GLOBALS['egw_info']['setup']['stage']['db'] = $GLOBALS['egw_setup']->detection->check_db($setup_info);
if($GLOBALS['DEBUG'])
{
@ -101,7 +102,7 @@ if ($GLOBALS['DEBUG']) { echo 'Stage: ' . $GLOBALS['egw_info']['setup']['stage']
//$action = 'Upgrade';
// end DEBUG code
switch(@get_var('action',Array('POST')))
switch($_POST['action'])
{
case 'Uninstall all applications':
$subtitle = lang('Deleting Tables');
@ -254,8 +255,9 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
break;
case 4:
$setup_tpl->set_var('hidden_vars', html::input_hidden('csrf_token', Api\Csrf::token(__FILE__)));
$setup_tpl->set_var('oldver',lang('You appear to be running version %1 of eGroupWare',$setup_info['phpgwapi']['currentver']));
$setup_tpl->set_var('automatic',lang('We will automatically update your tables/records to %1',$setup_info['phpgwapi']['version']));
$setup_tpl->set_var('oldver',lang('You appear to be running version %1 of eGroupWare',
isset($setup_info['api']['currentver']) ? $setup_info['api']['currentver'] : $setup_info['phpgwapi']['currentver']));
$setup_tpl->set_var('automatic',lang('We will automatically update your tables/records to %1',$setup_info['api']['version']));
$setup_tpl->set_var('backupwarn',lang('but we <u>highly recommend backing up</u> your tables in case the script causes damage to your data.<br /><strong>These automated scripts can easily destroy your data.</strong>'));
$setup_tpl->set_var('lang_backup',lang('create a backup before upgrading the DB'));
$setup_tpl->set_var('lang_debug',lang('enable for extra debug-messages'));
@ -301,14 +303,14 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
break;
case 'drop':
Api\Csrf::validate($_POST['csrf_token'], __FILE__);
$setup_info = $GLOBALS['egw_setup']->detection->get_versions($setup_info);
$setup_info = $GLOBALS['egw_setup']->process->droptables($setup_info);
$setup_info = $GLOBALS['egw_setup']->process->droptables(
$GLOBALS['egw_setup']->detection->get_versions($setup_info));
break;
case 'new':
// use uploaded backup, instead installing from scratch
if ($_POST['upload'])
{
$db_backup = new db_backup();
$db_backup = new Api\Db\Backup();
if (is_array($_FILES['uploaded']) && !$_FILES['uploaded']['error'] &&
is_uploaded_file($_FILES['uploaded']['tmp_name']))
{
@ -336,14 +338,14 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
}
else
{
$setup_info = $GLOBALS['egw_setup']->detection->upgrade_exclude($setup_info);
$s_info = $GLOBALS['egw_setup']->detection->upgrade_exclude($setup_info);
// Set the DB's client charset if a system-charset is set
if (preg_match('/^[a-z0-9-]+$/i', $_REQUEST['system_charset']))
{
$GLOBALS['egw_setup']->system_charset = $_REQUEST['system_charset'];
$GLOBALS['egw_setup']->db->Link_ID->SetCharSet($_REQUEST['system_charset']);
}
$setup_info = $GLOBALS['egw_setup']->process->pass($setup_info,'new',$_REQUEST['debug'],True);
$setup_info = $GLOBALS['egw_setup']->process->pass($s_info,'new',$_REQUEST['debug'],True);
$GLOBALS['egw_info']['setup']['currentver']['phpgwapi'] = 'oldversion';
}
break;
@ -468,54 +470,7 @@ switch($GLOBALS['egw_info']['setup']['stage']['config'])
$setup_tpl->set_var('admin_table_data',lang('Not ready for this stage yet'));
break;
}
/*
// Lang Section
$setup_tpl->set_var('lang_step_text',lang('Step %1 - Language Management', ++$num));
$GLOBALS['egw_info']['setup']['stage']['lang'] = $GLOBALS['egw_setup']->detection->check_lang();
// begin DEBUG code
//$GLOBALS['egw_info']['setup']['stage']['lang'] = 0;
// end DEBUG code
switch($GLOBALS['egw_info']['setup']['stage']['lang'])
{
case 1:
$setup_tpl->set_var('lang_status_img',$incomplete);
$setup_tpl->set_var('lang_status_alt','not completed');
$btn_install_lang = $GLOBALS['egw_setup']->html->make_frm_btn_simple(
lang('You do not have any languages installed. Please install one now <br />'),
'post','lang.php',
'submit',lang('Install Language'),
'');
$setup_tpl->set_var('lang_table_data',$btn_install_lang);
break;
case 10:
$langs_list = array();
$languages = setup_translation::get_supported_langs();
foreach ($GLOBALS['egw_info']['setup']['installed_langs'] as $key => $value)
{
$langs_list[] = isset($languages[$key]) ? $languages[$key]['descr'] : $value;
}
$setup_tpl->set_var('lang_status_img',$completed);
$setup_tpl->set_var('lang_status_alt','completed');
$btn_manage_lang = $GLOBALS['egw_setup']->html->make_frm_btn_simple(
lang('This stage is completed<br />') . lang('Currently installed languages: %1 <br />',implode(', ',$langs_list)),
'post','lang.php',
'submit',lang('Manage Languages'),
'');
// show system-charset and offer conversation
$btn_manage_lang .= lang('Current system-charset is %1.',$GLOBALS['egw_setup']->system_charset ?
"'<b>".$GLOBALS['egw_setup']->system_charset."</b>'" : lang('not set'))."\n";
$btn_manage_lang .= lang('To change the charset: back up your database, deinstall all applications and re-install the backup with "convert backup to charset selected" checked.');
$setup_tpl->set_var('lang_table_data',$btn_manage_lang);
break;
default:
$setup_tpl->set_var('lang_status_img',$incomplete);
$setup_tpl->set_var('lang_status_alt',lang('not completed'));
$setup_tpl->set_var('lang_table_data',lang('Not ready for this stage yet'));
break;
}
*/
$setup_tpl->set_var('apps_step_text',lang('Step %1 - Advanced Application Management', ++$num));
// $GLOBALS['egw_info']['setup']['stage']['apps'] = $GLOBALS['egw_setup']->check_apps();
switch($GLOBALS['egw_info']['setup']['stage']['db'])
@ -534,7 +489,7 @@ switch($GLOBALS['egw_info']['setup']['stage']['db'])
}
}
// warn if essential apps are not installed
foreach(array('phpgwapi','etemplate','home','admin','preferences','emailadmin') as $app)
foreach(array('api','phpgwapi','etemplate','home','admin','preferences') as $app)
{
if (!isset($setup_info[$app]) || empty($setup_info[$app]['currentver']))
{