mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-02-16 18:31:26 +01:00
- added LDAP ACL stuff to the readme
- reworked Admin >> Addressbook >> Site config - fixed for LDAP and SQL (eg. LDAP error are now forwarded to the UI)
This commit is contained in:
parent
ebdec8bcbb
commit
5e0d628d93
@ -10,9 +10,100 @@ like eg. the home-address you need to use some other supported schema:
|
|||||||
- mozillaOrgPerson older mozilla schema (depricated, but mostly compatible to mozillaAbPersonAlpha)
|
- mozillaOrgPerson older mozilla schema (depricated, but mostly compatible to mozillaAbPersonAlpha)
|
||||||
|
|
||||||
Please note:
|
Please note:
|
||||||
You can install the evolutionPerson schema together with ONE
|
You can or should install the evolutionPerson schema together with ONE
|
||||||
of the mozilla schemas. You can NOT install both mozilla schema!
|
of the mozilla schemas. You can NOT install both mozilla schema!
|
||||||
|
|
||||||
If the addressbook detects the schemas, it fills the extra fields of each schema.
|
If the addressbook detects a schema, it fills the extra fields of that schema.
|
||||||
|
|
||||||
Ralf
|
LDAP layout used for the eGroupWare addressbook
|
||||||
|
-----------------------------------------------
|
||||||
|
|
||||||
|
dc=domain,dc=com base DN of your LDAP server
|
||||||
|
|
|
||||||
|
+-o=default base DN for the addressbook of eGroupWare domain / DB instance "default"
|
||||||
|
| | (specified in Admin >> Addressbook >> Site config)
|
||||||
|
| |
|
||||||
|
| +-ou=accounts base DN for accounts (specified in Setup >> Configuration)
|
||||||
|
| | +-uid=ralf entry for user ralf
|
||||||
|
| | +-uid=lars entry for user lars
|
||||||
|
| | +-uid=... other users
|
||||||
|
| |
|
||||||
|
| +-ou=groups base DN for groups (specified in Setup >> Configuration)
|
||||||
|
| | +-cn=Default entry for the group Default
|
||||||
|
| | +-cn=... other groups
|
||||||
|
| |
|
||||||
|
| +ou=contacts
|
||||||
|
| |
|
||||||
|
| +-ou=shared shared addressbooks of the groups
|
||||||
|
| | +-cn=default addressbook of group Default
|
||||||
|
| | +-cn=...
|
||||||
|
| |
|
||||||
|
| +-ou=personal personal addressbooks of the users
|
||||||
|
| +-cn=ralf addressbook of user ralf
|
||||||
|
| +-cn=lars addressbook of user lars
|
||||||
|
| +-cn=...
|
||||||
|
|
|
||||||
|
+-o=other other eGroupWare domain / DB instance
|
||||||
|
+-...
|
||||||
|
|
||||||
|
The contact base DN must include the accounts and groups base DN, otherwise they will not be
|
||||||
|
searched AND the ACL given below does NOT work!
|
||||||
|
|
||||||
|
The following ACL in slapd conf allow:
|
||||||
|
-------------------------------------
|
||||||
|
- everyone to read the account addressbook
|
||||||
|
- the user to edit his account (incl. password)
|
||||||
|
- the egwadmin user for each domain to edit all accounts (eGW uses it when admins edit accounts)
|
||||||
|
- only the user to read, edit or delete in his personal addressbook
|
||||||
|
- group-members to read, edit or delete in their group addressbook
|
||||||
|
|
||||||
|
Add or include the rows after the line behind the exiting ACL rules in your slapd.conf
|
||||||
|
|
||||||
|
Please note:
|
||||||
|
-----------
|
||||||
|
- You need to change all dc=domain,dc=com with the base DN your LDAP uses!!!
|
||||||
|
- If you want to use the old mozillaOrgPerson schema, you need to change it here too!
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
# Access to users personal addressbooks
|
||||||
|
|
||||||
|
# allow read of addressbook by owner and egwadmin account
|
||||||
|
access to dn.regex="^cn=([^,]+),ou=personal,ou=contacts,o=([^,]+),dc=domain,dc=com$"
|
||||||
|
attrs=entry
|
||||||
|
by dn.regex="uid=$1,ou=accounts,o=$2,dc=domain,dc=com" read
|
||||||
|
by dn.regex="cn=egwadmin,o=$2,dc=domain,dc=com" write
|
||||||
|
by users none
|
||||||
|
|
||||||
|
# allow user to create entries in own addressbook; no-one else can access it
|
||||||
|
# needs write access to the entries ENTRY attribute ...
|
||||||
|
access to dn.regex="cn=([^,]+),ou=personal,ou=contacts,o=([^,]+),dc=domain,dc=com$"
|
||||||
|
attrs=children
|
||||||
|
by dn.regex="uid=$1,ou=accounts,o=$2,dc=domain,dc=com" write
|
||||||
|
by users none
|
||||||
|
|
||||||
|
# ... and the entries CHILDREN
|
||||||
|
access to dn.regex="cn=([^,]+),ou=personal,ou=contacts,o=([^,]+),dc=domain,dc=com$"
|
||||||
|
attrs=entry,@inetOrgPerson,@mozillaAbPersonAlpha,@evolutionPerson
|
||||||
|
by dn.regex="uid=$1,ou=accounts,o=$2,dc=domain,dc=com" write
|
||||||
|
by users none
|
||||||
|
|
||||||
|
# Access to groups addressbooks
|
||||||
|
|
||||||
|
# allow read of addressbook by members and egwadmin account
|
||||||
|
access to dn.regex="^cn=([^,]+),ou=shared,ou=contacts,o=([^,]+),dc=domain,dc=com$"
|
||||||
|
attrs=entry
|
||||||
|
by group.expand="cn=$1,ou=groups,o=$2,dc=domain,dc=com" read
|
||||||
|
by dn.regex="cn=egwadmin,o=$2,dc=domain,dc=com" write
|
||||||
|
by users none
|
||||||
|
|
||||||
|
# allow members to create entries in there group addressbooks; no-one else can access it
|
||||||
|
# needs write access to the entries ENTRY attribute ...
|
||||||
|
access to dn.regex="cn=([^,]+),ou=shared,ou=contacts,o=([^,]+),dc=domain,dc=com$"
|
||||||
|
attrs=children
|
||||||
|
by group.expand="cn=$1,ou=groups,o=$2,dc=domain,dc=com" write
|
||||||
|
by users none
|
||||||
|
|
||||||
|
# ... and the entries CHILDREN
|
||||||
|
access to dn.regex="cn=([^,]+),ou=shared,ou=contacts,o=([^,]+),dc=domain,dc=com$"
|
||||||
|
attrs=entry,@inetOrgPerson,@mozillaAbPersonAlpha,@evolutionPerson
|
||||||
|
by group.expand="cn=$1,ou=groups,o=$2,dc=domain,dc=com" write
|
||||||
|
by users none
|
||||||
|
@ -91,6 +91,13 @@ class bocontacts extends socontacts
|
|||||||
var $business_contact_fields = array();
|
var $business_contact_fields = array();
|
||||||
var $home_contact_fields = array();
|
var $home_contact_fields = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number and message of last error or false if no error, atm. only used for saving
|
||||||
|
*
|
||||||
|
* @var string/boolean
|
||||||
|
*/
|
||||||
|
var $error;
|
||||||
|
|
||||||
function bocontacts($contact_app='addressbook')
|
function bocontacts($contact_app='addressbook')
|
||||||
{
|
{
|
||||||
$this->socontacts($contact_app);
|
$this->socontacts($contact_app);
|
||||||
@ -403,6 +410,7 @@ class bocontacts extends socontacts
|
|||||||
}
|
}
|
||||||
if($contact['id'] && !$this->check_perms(EGW_ACL_EDIT,$contact))
|
if($contact['id'] && !$this->check_perms(EGW_ACL_EDIT,$contact))
|
||||||
{
|
{
|
||||||
|
$this->error = 'access denied';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// convert categories
|
// convert categories
|
||||||
@ -414,11 +422,11 @@ class bocontacts extends socontacts
|
|||||||
$contact['n_fn'] = $this->fullname($contact);
|
$contact['n_fn'] = $this->fullname($contact);
|
||||||
$contact['n_fileas'] = $this->fileas($contact);
|
$contact['n_fileas'] = $this->fileas($contact);
|
||||||
|
|
||||||
if(!($error_nr = parent::save($contact)))
|
if(!($this->error = parent::save($contact)))
|
||||||
{
|
{
|
||||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'],$isUpdate ? 'modify' : 'add', time());
|
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'],$isUpdate ? 'modify' : 'add', time());
|
||||||
}
|
}
|
||||||
return !$error_nr;
|
return !$this->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
/**************************************************************************\
|
/**
|
||||||
* eGroupWare - Addressbook Admin-, Preferences- and SideboxMenu-Hooks *
|
* Addressbook - admin, preferences and sidebox-menus
|
||||||
* http://www.eGroupWare.org *
|
*
|
||||||
* Written and (c) 2006 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
* @link http://www.egroupware.org
|
||||||
* ------------------------------------------------------------------------ *
|
* @package addressbook
|
||||||
* This program is free software; you can redistribute it and/or modify it *
|
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||||
* under the terms of the GNU General Public License as published by the *
|
* @copyright (c) 2006 by Ralf Becker <RalfBecker@outdoor-training.de>
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* option) any later version. *
|
* @version $Id$
|
||||||
\**************************************************************************/
|
*/
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class containing admin, preferences and sidebox-menus (used as hooks)
|
* Class containing admin, preferences and sidebox-menus (used as hooks)
|
||||||
@ -22,14 +20,14 @@
|
|||||||
*/
|
*/
|
||||||
class contacts_admin_prefs
|
class contacts_admin_prefs
|
||||||
{
|
{
|
||||||
var $contacts_repository = 'sql';
|
var $contact_repository = 'sql';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
*/
|
*/
|
||||||
function contacts_admin_prefs()
|
function contacts_admin_prefs()
|
||||||
{
|
{
|
||||||
if($GLOBALS['egw_info']['server']['contact_repository'] == 'ldap') $this->contacts_repository = 'ldap';
|
if($GLOBALS['egw_info']['server']['contact_repository'] == 'ldap') $this->contact_repository = 'ldap';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +67,7 @@ class contacts_admin_prefs
|
|||||||
'Grant Access' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
|
'Grant Access' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
|
||||||
'Edit Categories' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=' . $appname . '&cats_level=True&global_cats=True')
|
'Edit Categories' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=' . $appname . '&cats_level=True&global_cats=True')
|
||||||
);
|
);
|
||||||
if ($this->contacts_repository == 'ldap' || $GLOBALS['egw_info']['server']['deny_user_grants_access'])
|
if ($this->contact_repository == 'ldap' || $GLOBALS['egw_info']['server']['deny_user_grants_access'])
|
||||||
{
|
{
|
||||||
unset($file['Grant Access']);
|
unset($file['Grant Access']);
|
||||||
}
|
}
|
||||||
@ -176,7 +174,7 @@ class contacts_admin_prefs
|
|||||||
'admin' => false,
|
'admin' => false,
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($this->contacts_repository == 'sql')
|
if ($this->contact_repository == 'sql')
|
||||||
{
|
{
|
||||||
$GLOBALS['settings']['private_addressbook'] = array(
|
$GLOBALS['settings']['private_addressbook'] = array(
|
||||||
'type' => 'check',
|
'type' => 'check',
|
||||||
|
@ -294,7 +294,7 @@ class so_ldap
|
|||||||
if((int)$data['owner'])
|
if((int)$data['owner'])
|
||||||
{
|
{
|
||||||
// group address book
|
// group address book
|
||||||
if(!$cn = strtolower($GLOBALS['egw']->accounts->id2name((int)$data['owner'])))
|
if(!($cn = strtolower($GLOBALS['egw']->accounts->id2name((int)$data['owner']))))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -313,49 +313,27 @@ class so_ldap
|
|||||||
return true; // only admin is allowd to write accounts!
|
return true; // only admin is allowd to write accounts!
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if $baseDN exists. If not create new one
|
// check if $baseDN exists. If not create it
|
||||||
if(!($result = ldap_read($this->ds, $baseDN, 'objectclass=*')))
|
if (($err = $this->_check_create_dn($baseDN)))
|
||||||
{
|
{
|
||||||
if(ldap_errno($this->ds) == 32 && $cn)
|
return $err;
|
||||||
{
|
|
||||||
// create a admin connection to add the needed DN
|
|
||||||
$adminLDAP =& new ldap;
|
|
||||||
$adminDS = $adminLDAP->ldapConnect();
|
|
||||||
|
|
||||||
// emtry does not exist, lets try to create it
|
|
||||||
$baseDNData['objectClass'] = 'organizationalRole';
|
|
||||||
$baseDNData['cn'] = $cn;
|
|
||||||
if(!ldap_add($adminDS, $baseDN, $baseDNData))
|
|
||||||
{
|
|
||||||
$adminLDAP->ldapDisconnect();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$adminLDAP->ldapDisconnect();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the existing objectclasses of an entry, none = array() for new ones
|
// check the existing objectclasses of an entry, none = array() for new ones
|
||||||
$oldObjectclasses = array();
|
$oldObjectclasses = array();
|
||||||
$attributes = array('dn','cn','objectClass','uid');
|
$attributes = array('dn','cn','objectClass','uid');
|
||||||
if(!empty($this->data[$this->contacts_id]))
|
$contactUID = $this->data[$this->contacts_id];
|
||||||
|
if(!empty($contactUID) &&
|
||||||
|
($result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||||
|
'(|(entryUUID='.ldap::quote($contactUID).')(uid='.ldap::quote($contactUID).'))', $attributes)) &&
|
||||||
|
($oldContactInfo = ldap_get_entries($this->ds, $result)) && $oldContactInfo['count'])
|
||||||
{
|
{
|
||||||
$contactUID = $this->data[$this->contacts_id];
|
|
||||||
|
|
||||||
$result = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_contact_context'],
|
|
||||||
'(|(entryUUID='.ldap::quote($contactUID).')(uid='.ldap::quote($contactUID).'))', $attributes);
|
|
||||||
|
|
||||||
$oldContactInfo = ldap_get_entries($this->ds, $result);
|
|
||||||
foreach($oldContactInfo[0]['objectclass'] as $objectclass)
|
foreach($oldContactInfo[0]['objectclass'] as $objectclass)
|
||||||
{
|
{
|
||||||
$oldObjectclasses[] = strtolower($objectclass);
|
$oldObjectclasses[] = strtolower($objectclass);
|
||||||
}
|
}
|
||||||
$isUpdate = true;
|
$isUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$contactUID)
|
if(!$contactUID)
|
||||||
{
|
{
|
||||||
$contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
$contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
||||||
@ -370,7 +348,7 @@ class so_ldap
|
|||||||
|
|
||||||
if(!in_array($objectclass, $oldObjectclasses))
|
if(!in_array($objectclass, $oldObjectclasses))
|
||||||
{
|
{
|
||||||
$newObjectClasses['objectClass'][] = $objectclass;
|
$ldapContact['objectClass'][] = $objectclass;
|
||||||
}
|
}
|
||||||
if (isset($this->required_subs[$objectclass]))
|
if (isset($this->required_subs[$objectclass]))
|
||||||
{
|
{
|
||||||
@ -378,7 +356,7 @@ class so_ldap
|
|||||||
{
|
{
|
||||||
if(!in_array($sub, $oldObjectclasses))
|
if(!in_array($sub, $oldObjectclasses))
|
||||||
{
|
{
|
||||||
$newObjectClasses['objectClass'][] = $sub;
|
$ldapContact['objectClass'][] = $sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,20 +388,21 @@ class so_ldap
|
|||||||
$needRecreation = false;
|
$needRecreation = false;
|
||||||
|
|
||||||
// add missing objectclasses
|
// add missing objectclasses
|
||||||
if(count($newObjectClasses) > 0)
|
if($ldapContact['objectClass'] && array_diff($ldapContact['objectClass'],$oldObjectclasses))
|
||||||
{
|
{
|
||||||
$result = @ldap_mod_add($this->ds, $dn, $newObjectClasses);
|
if (!@ldap_mod_add($this->ds, $dn, array('objectClass' => $ldapContact['objectClass'])))
|
||||||
if(!$result)
|
|
||||||
{
|
{
|
||||||
if(ldap_errno($this->ds) == 69)
|
if(ldap_errno($this->ds) == 69)
|
||||||
{
|
{
|
||||||
// need to modify structural objectclass
|
// need to modify structural objectclass
|
||||||
$needRecreation = true;
|
$needRecreation = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//echo "<p>ldap_mod_add($this->ds,'$dn',array(objectClass =>".print_r($ldapContact['objectClass'],true)."))</p>\n";
|
||||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||||
return ldap_errno($this->ds).': '.ldap_error($this->ds);
|
return $this->_error(__LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,45 +424,46 @@ class so_ldap
|
|||||||
}
|
}
|
||||||
$newContact['uid'] = $contactUID;
|
$newContact['uid'] = $contactUID;
|
||||||
|
|
||||||
if(is_array($newObjectClasses['objectClass']) && count($newObjectClasses['objectClass']) > 0)
|
if(is_array($ldapContact['objectClass']) && count($ldapContact['objectClass']) > 0)
|
||||||
{
|
{
|
||||||
$newContact['objectclass'] = array_merge($newContact['objectclass'], $newObjectClasses['objectClass']);
|
$newContact['objectclass'] = array_merge($newContact['objectclass'], $ldapContact['objectClass']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ldap_delete($this->ds, $dn))
|
if(ldap_delete($this->ds, $dn))
|
||||||
{
|
{
|
||||||
if(!ldap_add($this->ds, $newDN, $newContact))
|
if(!@ldap_add($this->ds, $newDN, $newContact))
|
||||||
{
|
{
|
||||||
|
//echo "<p>recreate: ldap_add($this->ds,'$newDN',".print_r($newContact,true).")</p>\n";
|
||||||
//print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';_debug_array($newContact);exit;
|
//print 'class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')';_debug_array($newContact);exit;
|
||||||
return ldap_errno($this->ds).': '.ldap_error($this->ds);
|
return $this->_error(__LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') delete of old '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') delete of old '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||||
return ldap_errno($this->ds).': '.ldap_error($this->ds);
|
return $this->_error(__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dn = $newDN;
|
$dn = $newDN;
|
||||||
}
|
}
|
||||||
|
unset($ldapContact['objectClass']);
|
||||||
|
|
||||||
$result = ldap_modify($this->ds, $dn, $ldapContact);
|
if (!@ldap_modify($this->ds, $dn, $ldapContact))
|
||||||
if (!$result)
|
|
||||||
{
|
{
|
||||||
|
//echo "<p>ldap_modify($this->ds,'$dn',".print_r($ldapContact,true).")</p>\n";
|
||||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') update of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||||
return ldap_errno($this->ds).': '.ldap_error($this->ds);
|
return $this->_error(__LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$dn = 'uid='. ldap::quote($ldapContact['uid']) .','. $baseDN;
|
$dn = 'uid='. ldap::quote($ldapContact['uid']) .','. $baseDN;
|
||||||
|
|
||||||
$result = ldap_add($this->ds, $dn, $ldapContact);
|
if (!@ldap_add($this->ds, $dn, $ldapContact))
|
||||||
|
|
||||||
if (!$result)
|
|
||||||
{
|
{
|
||||||
|
//echo "<p>ldap_add($this->ds,'$dn',".print_r($ldapContact,true).")</p>\n";
|
||||||
error_log('class.so_ldap.inc.php ('. __LINE__ .') add of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
error_log('class.so_ldap.inc.php ('. __LINE__ .') add of '. $dn .' failed errorcode: '. ldap_errno($this->ds) .' ('. ldap_error($this->ds) .')');
|
||||||
return ldap_errno($this->ds).': '.ldap_error($this->ds);
|
return $this->_error(__LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0; // Ok, no error
|
return 0; // Ok, no error
|
||||||
@ -516,7 +496,7 @@ class so_ldap
|
|||||||
"(|(entryUUID=$entry)(uid=$entry))", $attributes))
|
"(|(entryUUID=$entry)(uid=$entry))", $attributes))
|
||||||
{
|
{
|
||||||
$contactInfo = ldap_get_entries($this->ds, $result);
|
$contactInfo = ldap_get_entries($this->ds, $result);
|
||||||
if(ldap_delete($this->ds, $contactInfo[0]['dn']))
|
if(@ldap_delete($this->ds, $contactInfo[0]['dn']))
|
||||||
{
|
{
|
||||||
$ret++;
|
$ret++;
|
||||||
}
|
}
|
||||||
@ -861,6 +841,68 @@ class so_ldap
|
|||||||
return mktime(substr($date,8,2),substr($date,10,2),substr($date,12,2),
|
return mktime(substr($date,8,2),substr($date,10,2),substr($date,12,2),
|
||||||
substr($date,4,2),substr($date,6,2),substr($date,0,4));
|
substr($date,4,2),substr($date,6,2),substr($date,0,4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if $baseDN exists. If not create it
|
||||||
|
*
|
||||||
|
* @param string $baseDN cn=xxx,ou=yyy,ou=contacts,$GLOBALS['egw_info']['server']['ldap_contact_context']
|
||||||
|
* @return boolean/string fase on success or string with error-message
|
||||||
|
*/
|
||||||
|
function _check_create_dn($baseDN)
|
||||||
|
{
|
||||||
|
// check if $baseDN exists. If not create new one
|
||||||
|
if(@ldap_read($this->ds, $baseDN, 'objectclass=*'))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(ldap_errno($this->ds) != 32 || substr($baseDN,0,3) != 'cn=')
|
||||||
|
{
|
||||||
|
return $this->_error(__LINE__); // baseDN does NOT exist and we cant/wont create it
|
||||||
|
}
|
||||||
|
// create a admin connection to add the needed DN
|
||||||
|
$adminLDAP =& new ldap;
|
||||||
|
$adminDS = $adminLDAP->ldapConnect();
|
||||||
|
|
||||||
|
list(,$ou) = explode(',',$baseDN);
|
||||||
|
foreach(array(
|
||||||
|
'ou=contacts,'.$GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||||
|
$ou.',ou=contacts,'.$GLOBALS['egw_info']['server']['ldap_contact_context'],
|
||||||
|
$baseDN,
|
||||||
|
) as $dn)
|
||||||
|
{
|
||||||
|
if (!@ldap_read($this->ds, $dn, 'objectclass=*') && ldap_errno($this->ds) == 32)
|
||||||
|
{
|
||||||
|
// entry does not exist, lets try to create it
|
||||||
|
list($top) = explode(',',$dn);
|
||||||
|
list($var,$val) = explode('=',$top);
|
||||||
|
$data = array(
|
||||||
|
'objectClass' => $var == 'cn' ? 'organizationalRole' : 'organizationalUnit',
|
||||||
|
$var => $val,
|
||||||
|
);
|
||||||
|
if(!@ldap_add($adminDS, $dn, $data))
|
||||||
|
{
|
||||||
|
//echo "<p>ldap_add($adminDS,'$dn',".print_r($data,true).")</p>\n";
|
||||||
|
$err = $this->_error(__LINE__,$adminDS);
|
||||||
|
$adminLDAP->ldapDisconnect();
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$adminLDAP->ldapDisconnect();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* error message for failed ldap operation
|
||||||
|
*
|
||||||
|
* @param int $line
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function _error($line,$ds=null)
|
||||||
|
{
|
||||||
|
return ldap_error($ds ? $ds : $this->ds).': so_ldap: '.$line;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special handling for mapping of eGW contact-data to the evolutionPerson objectclass
|
* Special handling for mapping of eGW contact-data to the evolutionPerson objectclass
|
||||||
|
@ -643,7 +643,6 @@ class socontacts
|
|||||||
$rows[$n] = $this->db2data($row);
|
$rows[$n] = $this->db2data($row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ToDo: read custom-fields, if displayed in the index page
|
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +295,10 @@ class socontacts_sql extends so_sql
|
|||||||
$join .= $this->extra_join;
|
$join .= $this->extra_join;
|
||||||
if (is_string($only_keys)) $only_keys = 'DISTINCT '.str_replace(array('contact_id','contact_owner'),
|
if (is_string($only_keys)) $only_keys = 'DISTINCT '.str_replace(array('contact_id','contact_owner'),
|
||||||
array($this->table_name.'.contact_id',$this->table_name.'.contact_owner'),$only_keys);
|
array($this->table_name.'.contact_id',$this->table_name.'.contact_owner'),$only_keys);
|
||||||
|
|
||||||
|
// only return the egw_addressbook columns, to not generate dublicates by the left join
|
||||||
|
// and to not return the NULL for contact_{id|owner} of not found custom fields!
|
||||||
|
if (is_bool($only_keys)) $only_keys = 'DISTINCT '.$this->table_name.'.*';
|
||||||
|
|
||||||
if (isset($filter['owner']))
|
if (isset($filter['owner']))
|
||||||
{
|
{
|
||||||
|
@ -57,8 +57,8 @@ class uicontacts extends bocontacts
|
|||||||
$this->$my = &$GLOBALS['egw']->$class;
|
$this->$my = &$GLOBALS['egw']->$class;
|
||||||
}
|
}
|
||||||
$this->prefs =& $GLOBALS['egw_info']['user']['preferences']['addressbook'];
|
$this->prefs =& $GLOBALS['egw_info']['user']['preferences']['addressbook'];
|
||||||
$this->private_addressbook = $this->contacts_repository == 'sql' && $this->prefs['private_addressbook'];
|
$this->private_addressbook = $this->contact_repository == 'sql' && $this->prefs['private_addressbook'];
|
||||||
|
|
||||||
$this->org_views = array(
|
$this->org_views = array(
|
||||||
'org_name' => lang('Organisations'),
|
'org_name' => lang('Organisations'),
|
||||||
'org_name,adr_one_locality' => lang('Organisations by location'),
|
'org_name,adr_one_locality' => lang('Organisations by location'),
|
||||||
@ -187,7 +187,7 @@ class uicontacts extends bocontacts
|
|||||||
$sel_options['org_view'][(string) $content['nm']['org_view']] = $org_name;
|
$sel_options['org_view'][(string) $content['nm']['org_view']] = $org_name;
|
||||||
}
|
}
|
||||||
$content['nm']['org_view_label'] = $sel_options['org_view'][(string) $content['nm']['org_view']];
|
$content['nm']['org_view_label'] = $sel_options['org_view'][(string) $content['nm']['org_view']];
|
||||||
|
|
||||||
$this->tmpl->read('addressbook.index');
|
$this->tmpl->read('addressbook.index');
|
||||||
return $this->tmpl->exec('addressbook.uicontacts.index',$content,$sel_options,$readonlys,$preserv);
|
return $this->tmpl->exec('addressbook.uicontacts.index',$content,$sel_options,$readonlys,$preserv);
|
||||||
}
|
}
|
||||||
@ -339,6 +339,20 @@ class uicontacts extends bocontacts
|
|||||||
//echo "<p>uicontacts::get_rows(".print_r($query,true).")</p>\n";
|
//echo "<p>uicontacts::get_rows(".print_r($query,true).")</p>\n";
|
||||||
if (!$id_only)
|
if (!$id_only)
|
||||||
{
|
{
|
||||||
|
// check if accounts are stored in ldap, which does NOT yet support the org-views
|
||||||
|
if ($this->so_accounts && $query['filter'] === '0' && $query['org_view'])
|
||||||
|
{
|
||||||
|
$old_state = $GLOBALS['egw']->session->appsession('index','addressbook');
|
||||||
|
if ($old_state['filter'] === '0') // user changed to org_view
|
||||||
|
{
|
||||||
|
$query['filter'] = ''; // --> change filter to all contacts
|
||||||
|
}
|
||||||
|
else // user changed to accounts
|
||||||
|
{
|
||||||
|
$query['org_view'] = ''; // --> change to regular contacts view
|
||||||
|
}
|
||||||
|
unset($old_state);
|
||||||
|
}
|
||||||
$GLOBALS['egw']->session->appsession('index','addressbook',$query);
|
$GLOBALS['egw']->session->appsession('index','addressbook',$query);
|
||||||
// save the state of the index in the user prefs
|
// save the state of the index in the user prefs
|
||||||
$state = serialize(array(
|
$state = serialize(array(
|
||||||
@ -352,7 +366,8 @@ class uicontacts extends bocontacts
|
|||||||
if ($state != $this->prefs['index_state'])
|
if ($state != $this->prefs['index_state'])
|
||||||
{
|
{
|
||||||
$GLOBALS['egw']->preferences->add('addressbook','index_state',$state);
|
$GLOBALS['egw']->preferences->add('addressbook','index_state',$state);
|
||||||
$GLOBALS['egw']->preferences->save_repository();
|
// save prefs, but do NOT invalid the cache (unnecessary)
|
||||||
|
$GLOBALS['egw']->preferences->save_repository(false,'user',false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($query['col_filter']['cat_id'])) unset($query['col_filter']['cat_id']);
|
if (isset($query['col_filter']['cat_id'])) unset($query['col_filter']['cat_id']);
|
||||||
@ -426,7 +441,7 @@ class uicontacts extends bocontacts
|
|||||||
}
|
}
|
||||||
$rows = parent::search($query['search'],$id_only ? array('id','org_name','n_family','n_given','n_fileas') : false,
|
$rows = parent::search($query['search'],$id_only ? array('id','org_name','n_family','n_given','n_fileas') : false,
|
||||||
$order,'','%',false,'OR',array((int)$query['start'],(int) $query['num_rows']),$query['col_filter']);
|
$order,'','%',false,'OR',array((int)$query['start'],(int) $query['num_rows']),$query['col_filter']);
|
||||||
|
|
||||||
if (!$id_only && $this->prefs['custom_colum'] != 'never' && $rows) // do we need the custom fields
|
if (!$id_only && $this->prefs['custom_colum'] != 'never' && $rows) // do we need the custom fields
|
||||||
{
|
{
|
||||||
foreach((array) $rows as $n => $val)
|
foreach((array) $rows as $n => $val)
|
||||||
@ -718,7 +733,8 @@ class uicontacts extends bocontacts
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$content['msg'] = lang('Error saving the contact !!!');
|
$content['msg'] = lang('Error saving the contact !!!').
|
||||||
|
($this->error ? ' '.$this->error : '');
|
||||||
$button = 'apply'; // to not leave the dialog
|
$button = 'apply'; // to not leave the dialog
|
||||||
}
|
}
|
||||||
// writing links for new entry, existing ones are handled by the widget itself
|
// writing links for new entry, existing ones are handled by the widget itself
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**************************************************************************\
|
|
||||||
* eGroupWare *
|
|
||||||
* http://www.egroupware.org *
|
|
||||||
* Written by Miles Lott <milos@groupwhere.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$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Set a global flag to indicate this file was found by admin/config.php.
|
|
||||||
config.php will unset it after parsing the form values.
|
|
||||||
*/
|
|
||||||
$GLOBALS['egw_info']['server']['found_validation_hook'] = True;
|
|
||||||
|
|
||||||
/* Check a specific setting. Name must match the setting. */
|
|
||||||
function ldap_contact_context($value='')
|
|
||||||
{
|
|
||||||
if($value == $GLOBALS['egw_info']['server']['ldap_context'])
|
|
||||||
{
|
|
||||||
$GLOBALS['config_error'] = 'Contact context for ldap must be different from the context used for accounts';
|
|
||||||
}
|
|
||||||
elseif($value == $GLOBALS['egw_info']['server']['ldap_group_context'])
|
|
||||||
{
|
|
||||||
$GLOBALS['config_error'] = 'Contact context for ldap must be different from the context used for groups';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$GLOBALS['config_error'] = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check all settings to validate input. Name must be 'final_validation' */
|
|
||||||
function final_validation($value='')
|
|
||||||
{
|
|
||||||
if($value['contact_repository'] == 'ldap' && !$value['ldap_contact_dn'])
|
|
||||||
{
|
|
||||||
$GLOBALS['config_error'] = 'Contact dn must be set';
|
|
||||||
}
|
|
||||||
elseif($value['contact_repository'] == 'ldap' && !$value['ldap_contact_context'])
|
|
||||||
{
|
|
||||||
$GLOBALS['config_error'] = 'Contact context must be set';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$GLOBALS['config_error'] = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -5,22 +5,14 @@
|
|||||||
<tr class="th">
|
<tr class="th">
|
||||||
<td colspan="2"><font color="{th_text}"> <b>{title}</b></font></td>
|
<td colspan="2"><font color="{th_text}"> <b>{title}</b></font></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr bgcolor="{th_err}">
|
<tr>
|
||||||
<td colspan="2"> <b>{error}</b></font></td>
|
<td colspan="2"> <i><font color="red">{error}</i></font></td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- END header -->
|
<!-- END header -->
|
||||||
<!-- BEGIN body -->
|
<!-- BEGIN body -->
|
||||||
<tr class="th">
|
<tr class="th">
|
||||||
<td colspan="2"> <b>{lang_Addressbook}/{lang_Contact_Settings}</b></font></td>
|
<td colspan="2"> <b>{lang_Addressbook}/{lang_Contact_Settings}</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
<!--
|
|
||||||
<tr class="row_on">
|
|
||||||
<td>{lang_Contact_application}:</td>
|
|
||||||
<td><input name="newsettings[contact_application]" value="{value_contact_application}"></td>
|
|
||||||
</tr>
|
|
||||||
<tr class="row_off">
|
|
||||||
<td align="center" colspan="2">{lang_WARNING!!_LDAP_is_valid_only_if_you_are_NOT_using_contacts_for_accounts_storage!}</td>
|
|
||||||
</tr> -->
|
|
||||||
<tr class="row_off">
|
<tr class="row_off">
|
||||||
<td>{lang_Select_where_you_want_to_store_/_retrieve_contacts}.</td>
|
<td>{lang_Select_where_you_want_to_store_/_retrieve_contacts}.</td>
|
||||||
<td>
|
<td>
|
||||||
@ -38,22 +30,15 @@
|
|||||||
<td>{lang_LDAP_context_for_contacts}:</td>
|
<td>{lang_LDAP_context_for_contacts}:</td>
|
||||||
<td><input name="newsettings[ldap_contact_context]" value="{value_ldap_contact_context}" size="40"></td>
|
<td><input name="newsettings[ldap_contact_context]" value="{value_ldap_contact_context}" size="40"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="row_on">
|
<tr class="th">
|
||||||
<td>{lang_LDAP_root_dn_for_contacts}:</td>
|
<td colspan="2">
|
||||||
<td><input name="newsettings[ldap_contact_dn]" value="{value_ldap_contact_dn}" size="40"></td>
|
{lang_Additional_information_about_using_LDAP_as_contact_repository}:
|
||||||
</tr>
|
<a href="addressbook/doc/README" target="_blank">README</a>
|
||||||
<tr class="row_off">
|
</td>
|
||||||
<td>{lang_LDAP_root_pw_for_contacts}:</td>
|
</tr>
|
||||||
<td><input name="newsettings[ldap_contact_pw]" type="password" value=""></td>
|
|
||||||
</tr>
|
|
||||||
<!-- END body -->
|
<!-- END body -->
|
||||||
<!-- BEGIN footer -->
|
<!-- BEGIN footer -->
|
||||||
<tr class="th">
|
<tr valign="bottom" style="height: 30px;">
|
||||||
<td colspan="2">
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" align="center">
|
<td colspan="2" align="center">
|
||||||
<input type="submit" name="submit" value="{lang_submit}">
|
<input type="submit" name="submit" value="{lang_submit}">
|
||||||
<input type="submit" name="cancel" value="{lang_cancel}">
|
<input type="submit" name="cancel" value="{lang_cancel}">
|
||||||
|
Loading…
Reference in New Issue
Block a user