Merge branch '2013.10' into 2014.11
[tine20] / tine20 / Tinebase / Group / LdapPlugin / Samba.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Samba
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2010 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Lars Kneschke <l.kneschke@metaways.de>
10  */
11
12 /**
13  * class Tinebase_SambaSAM_Ldap
14  * 
15  * Samba Account Managing
16  * 
17  * todo: what about primaryGroupSID?
18  *
19  * @package Tinebase
20  * @subpackage Samba
21  */
22 class Tinebase_Group_LdapPlugin_Samba
23 {
24
25     /**
26      * @var Tinebase_Ldap
27      */
28     protected $_ldap = NULL;
29
30     /**
31      * group properties mapping
32      *
33      * @var array
34      */
35     protected $_rowNameMapping = array(
36         'sid'              => 'sambasid', 
37         'groupType'        => 'sambagrouptype',
38     );
39
40     /**
41      * objectclasses required for groups
42      *
43      * @var array
44      */
45     protected $_requiredObjectClass = array(
46         'sambaGroupMapping'
47     );
48         
49     /**
50      * the constructor
51      *
52      * @param  Tinebase_Ldap  $_ldap    the ldap resource
53      * @param  array          $options  options used in connecting, binding, etc.
54      */
55     public function __construct(Tinebase_Ldap $_ldap, $_options = null) 
56     {
57         if (!isset($_options[Tinebase_Group_Ldap::PLUGIN_SAMBA]) || empty($_options[Tinebase_Group_Ldap::PLUGIN_SAMBA]['sid'])) {
58             throw new Exception('you need to configure the sid of the samba installation');
59         }
60         
61         $this->_ldap    = $_ldap;
62         $this->_options = $_options;
63     }
64     
65     /**
66      * inspect data used to create user
67      * 
68      * @param Tinebase_Model_FullUser  $_user
69      * @param array                    $_ldapData  the data to be written to ldap
70      */
71     public function inspectAddGroup(Tinebase_Model_Group $_group, array &$_ldapData)
72     {
73         $this->_group2ldap($_group, $_ldapData);
74     }
75     
76     /**
77      * inspect data used to update user
78      * 
79      * @param Tinebase_Model_FullUser  $_user
80      * @param array                    $_ldapData  the data to be written to ldap
81      */
82     public function inspectUpdateGroup(Tinebase_Model_Group $_group, array &$_ldapData)
83     {
84         $this->_group2ldap($_group, $_ldapData);
85     }
86     
87     /**
88      * convert objects with user data to ldap data array
89      * 
90      * @param Tinebase_Model_FullUser  $_user
91      * @param array                    $_ldapData  the data to be written to ldap
92      */
93     protected function _group2ldap(Tinebase_Model_Group $_group, array &$_ldapData)
94     {
95         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ENCRYPT ' . print_r($_ldapData, true));
96         
97         if (isset($_ldapData['objectclass'])) {
98             $_ldapData['objectclass'] = array_unique(array_merge($_ldapData['objectclass'], $this->_requiredObjectClass));
99         }
100         
101         if(isset($_ldapData['gidnumber'])) {
102             $gidNumber = $_ldapData['gidnumber'];
103         } else {
104             $gidNumber = $this->_getGidNumber($_group->getId());
105         }
106         
107         // when we try to add a group, $_group has no id which leads to Tinebase_Exception_InvalidArgument in $this->_getGroupMetaData
108         try {
109             $metaData = $this->_getGroupMetaData($_group);
110         } catch (Tinebase_Exception_InvalidArgument $teia) {
111             $metaData = array();
112         }
113         
114         if (!isset($metaData['sambasid'])) {
115             $_ldapData['sambasid']       = $this->_options[Tinebase_Group_Ldap::PLUGIN_SAMBA]['sid'] . '-' . (2 * $gidNumber + 1001);
116             $_ldapData['sambagrouptype'] = 2;
117         }
118         
119         $_ldapData['displayname']    = $_group->name;
120     }
121     
122     /**
123      * return gidnumber of group
124      * 
125      * @param string $_gid
126      * @return string
127      */
128     protected function _getGidNumber($_gid)
129     {
130         $filter = Zend_Ldap_Filter::equals(
131             $this->_options['groupUUIDAttribute'], Zend_Ldap::filterEscape($_gid)
132         );
133         
134         $groups = $this->_ldap->search(
135             $filter, 
136             $this->_options['groupsDn'], 
137             $this->_options['groupSearchScope'], 
138             array('gidnumber')
139         );
140         
141         if (count($groups) == 0) {
142             throw new Tinebase_Exception_NotFound('Group not found! Filter: ' . $filter->toString());
143         }
144         
145         $group = $groups->getFirst();
146         
147         if (empty($group['gidnumber'][0])) {
148             throw new Tinebase_Exception_NotFound('Group has no gidnumber');
149         }
150         
151         return $group['gidnumber'][0];
152     }
153     
154     /**
155      * get group by id
156      *
157      * @param   int         $_groupId
158      * @return  Tinebase_Model_SAMGroup group
159      */
160     public function getGroupById($_groupId)
161     {
162         $groupId = Tinebase_Model_Group::convertGroupIdToInt($_groupId);
163
164         $filter = Zend_Ldap_Filter::equals(
165             $this->_options['groupUUIDAttribute'], Zend_Ldap::filterEscape($groupId)
166         );
167         
168         $groups = $this->_ldap->search(
169             $filter, 
170             $this->_options['groupsDn'], 
171             Zend_Ldap::SEARCH_SCOPE_SUB, 
172             array()
173         );
174         
175         if(count($groups) == 0) {
176             throw new Exception('Group not found');
177         }
178         
179         $group = $this->_ldap2Group($groups->getFirst());
180         
181         return $group;
182     }
183     
184     /**
185      * returns ldap metadata of given group
186      *
187      * @param  int         $_groupId
188      * @return array 
189      * 
190      * @todo remove obsolete code
191      */
192     protected function _getGroupMetaData($_groupId)
193     {
194         $groupId = Tinebase_Model_Group::convertGroupIdToInt($_groupId);
195         
196         $filter = Zend_Ldap_Filter::equals(
197             $this->_options['groupUUIDAttribute'], Zend_Ldap::filterEscape($groupId)
198         );
199         
200         $result = $this->_ldap->search(
201             $filter, 
202             $this->_options['groupsDn'], 
203             Zend_Ldap::SEARCH_SCOPE_SUB, 
204             array('objectclass', 'sambasid')
205         )->getFirst();
206         
207         return $result;
208         
209         /*
210         } catch (Tinebase_Exception_NotFound $e) {
211             throw new Exception("group with id $groupId not found");
212         }
213         */
214     }
215     
216     /**
217      * Returns a group obj with raw data from ldap
218      *
219      * @param array $_ldapData
220      * @return Tinebase_Model_SAMGroup
221      */
222     protected function _ldap2Group($_ldapData)
223     {
224         $groupArray = array();
225         
226         foreach ($_ldapData as $key => $value) {
227             if (is_int($key)) {
228                 continue;
229             }
230             $keyMapping = array_search($key, $this->_groupPropertyNameMapping);
231             if ($keyMapping !== FALSE) {
232                 switch($keyMapping) {
233                    default: 
234                         $groupArray[$keyMapping] = $value[0];
235                         break;
236                 }
237             }
238         }
239
240         $group = new Tinebase_Model_SAMGroup($groupArray);
241         
242         return $group;
243     }
244 }