Code

Applied in_array strict patches from trunk
[gosa.git] / gosa-core / plugins / addons / dyngroup / class_DynamicLdapGroup.inc
1 <?php
3 /*
4  * This code is part of GOsa (http://www.gosa-project.org)
5  * Copyright (C) 2003-2008 GONICUS GmbH
6  * Copyright (C) 2010 Thomas CHEMINEAU
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
23 /**
24  * This class will allow user to parameter dynamic group.
25  * @author Thomas Chemineau - thomas.chemineau<at>gmail.com
26  * @version 0.01
27  */
28 class DynamicLdapGroup extends plugin
29 {
31     /**
32      * The attribute that will use GOsa to store LDAP URI.
33      * @var array
34      */
35     public $attributes = array('labeledURI');
37     /**
38      * The objectClass that will use GOsa to identify a group as dynamic.
39      * @var array
40      */
41     public $objectclasses = array('labeledURIObject');
43     /**
44      * Default value for the corresponding attribute found in the $this->attributes
45      * array of this plugin.
46      * @var string
47      */
48     public $labeledURI = array();
49     public $labeledURIparsed = array();
50     public $labeledURIdefault = 'ldap:///dc=example,dc=com?memberUid?sub?(objectClass=posixGroup)';
51     
52     public $scopes = array('base','one','sub');
54     /**
55      * Store values of memberUrl.
56      * @var Array
57      */
58     private $_memberUrls = Array();
60     public $orig_dn ="";
62     /**
63      * Create this object.
64      * @param Array $config GOsa config.
65      * @param string $dn Current DN.
66      */
67     public function __construct ($config, $dn)
68     {
69         parent::__construct($config, $dn);
71         // Load labeledURI values.
72         $this->labeledURI = array();
73         if(!$this->is_account){
74             $this->labeledURI[] = str_replace('dc=example,dc=com', LDAP::fix($this->dn), $this->labeledURIdefault);
75         }elseif(isset($this->attrs['labeledURI'])){
76             for($i =0; $i < $this->attrs['labeledURI']['count']; $i++) {
77                 $this->labeledURI[] = $this->attrs['labeledURI'][$i];
78             }
79         }
81         // Parse labeledURI entries
82         $this->labeledURIparsed = array();
83         foreach($this->labeledURI as $entry){
84             list($base,$attr,$scope,$filter) = preg_split("/\?/",$entry); 
85             
86             // Ignore entries that do not have a valid scope value (one,base,sub)
87             if(!in_array_strict($scope,array('base','one','sub'))) continue;
89             // Append parsed uri
90             $scope = array_search($scope,$this->scopes);
91             $this->labeledURIparsed[] = array('base' => $base, 'attr' => $attr, 'scope' => $scope,'filter' => $filter);
92         }
93    
94         // Save dn, to be able the check for object movements - put this in plugin::move 
95         $this->orig_dn = $this->dn;
96     }
99     public function check ()
100     {
101         $messages = plugin::check();
102         
103         // At least one entry is required. 
104         if(!count($this->labeledURIparsed)){
105             $messages[] = msgPool::required(_("Labeled URI"));
106         }  
108         // Check entries
109         foreach($this->labeledURIparsed as $key => $entry){
110             $nr = $key +1;
112             // A base is required
113             if(empty($entry['base'])){
114                 $messages[] = msgPool::required(_("Base")." {$nr}");
115             }
117             // Check for invalid attributes
118             if(empty($entry['attr'])){
119                 $messages[] = msgPool::required(_("Attribute")." {$nr}");
120             }elseif(in_array_strict(strtolower($entry['attr']), array('objectclass'))){
121                 $messages[] = msgPool::reserved(_("Attribute")." {$nr}");
122             }
124             // A filter is required
125             if(empty($entry['filter'])){
126                 $messages[] = msgPool::required(_("Filter")." {$nr}");
127             }elseif(!preg_match("/^\(/", $entry['filter'])){
128                 $messages[] = msgPool::invalid(_("Filter")." {$nr}",  $entry['filter'],'', '(objectClass=gosaAccount)'." - "._("Surrounding brackets are required!"));
129             }else{
131                 // Check if filter is valid
132                 $ldap = $this->config->get_ldap_link();
133                 $ldap->cd($this->config->current['BASE']);
134                 $ldap->search($entry['filter']);
135                 if(!$ldap->success()){
136                     $messages[] = sprintf(_("The given filter '%s' for entry %s seems to be invalid!"),
137                             bold($entry['filter']), $nr);
138                 }
139             }
140         }
141  
142         return($messages);
143     }
146     /**
147      * Execute this plugin.
148      * @return string HTML to print.
149      */
150     public function execute ()
151     {
152         //
153         // Are we trying to modify state of this group ? If so,
154         // we can edit the current object.
155         //
156         if (isset($_POST['modify_state']))
157         {
158             $this->is_account = !$this->is_account;
159         }
161         //
162         // Display a message if this feature is disabled.
163         //
164         if (!$this->is_account)
165         {
166             return $this->show_disable_header(msgPool::addFeaturesButton(_("Dynamic object")), msgPool::featuresDisabled(_("Dynamic object")));
167         }
168         $display = $this->show_disable_header(msgPool::removeFeaturesButton(_("Dynamic object")), msgPool::featuresEnabled(_("Dynamic object")));
170         // Display values.
171         //
172         $smarty = get_smarty();
173         $smarty->assign('labeledURIparsed',  set_post($this->labeledURIparsed));
174         $smarty->assign('scopes', set_post($this->scopes));
175         $display .= $smarty->fetch(get_template_path('dyngroup.tpl', TRUE, dirname(__FILE__)));
176         return $display;
177     }
181     /**
182      * This plugin does nothing when this method is invoked.
183      */
184     public function remove_from_parent ()
185     {
186         parent::remove_from_parent();
187         $ldap = $this->config->get_ldap_link();
188         $ldap->cd($this->dn);
189         $ldap->modify($this->attrs);
190         if(!$ldap->success()){
191             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
192         }
193         return;
194     }
197     /**
198      * This function is called when tab is undisplayed. For example, the current user
199      * wants to change other settings of this group, but not save it to the LDAP
200      * directory directly.
201      */
202     public function save_object ()
203     {
204         parent::save_object();
206         // Add a new labeled Uri
207         if(isset($_POST['addUri'])){
208             $this->labeledURIparsed[] = 
209                 array(
210                         'base' => 'ldap:///'.$this->dn,
211                         'attr' => 'memberUid', 
212                         'scope' => 2,
213                         'filter' => '(objectClass=posixGroup)');
214         }
216         // Remove a labeled Uri and get posts
217         foreach($this->labeledURIparsed as $key => $data){
218             foreach(array('scope','attr','filter','base') as $attr){
219                 if(isset($_POST[$attr.'_'.$key])){
220                     $this->labeledURIparsed[$key][$attr] = get_post($attr.'_'.$key);
221                 }
222             }
223         
224             // Remove labeled uri if requested
225             if(isset($_POST['delUri_'.$key])){
226                 unset($this->labeledURIparsed[$key]);
227             }
228         }
229         $this->labeledURIparsed = array_values($this->labeledURIparsed);
230     }
233     /**
234      * That will add additionnal information into the current LDAP entry.
235      * If this plugin is disable, then it will remove any data that references
236      * this plugin into the LDAP directory.
237      * @return boolean
238      */
239     public function save ()
240     {
241         // Build up labeledUri entries
242         $this->labeledURI = array();
243         foreach($this->labeledURIparsed as $entry){
244             $scope = $this->scopes[$entry['scope']];
245             $filter = $entry['filter'];
246             $this->labeledURI[] = "{$entry['base']}?{$entry['attr']}?{$scope}?{$filter}";
247         }
248         $this->labeledURI = array_unique($this->labeledURI);
250         parent::save();
251         $this->cleanup();
252         $ldap = $this->config->get_ldap_link();
253         $ldap->cd($this->dn);
254         $ldap->modify($this->attrs);
255         if(!$ldap->success()){
256             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
257         }
258     }
261     /*! \brief      Updates labeledURI entries in ldap.
262      *              Check whether the given src_dn is part of some labeledURI entries
263      *               and then updates the entries to use the dst_dn.
264      * @param       $config     The GOsa configuration object.
265      * @param       $src_dn     The source 'dn' of the object that was moved.
266      * @param       $dst_dn     The target 'dn' of the object that was moved.
267      */
268     public static function moveDynGroup($config,$src_dn,$dst_dn)
269     {
270         // Fetch all dynamic group definitions 
271         $objs = get_list("(&(objectClass=labeledURIObject)(labeledURI=*))",array("all"),$config->current['BASE'],
272                 array("dn","labeledURI"),GL_SUBSEARCH | GL_NO_ACL_CHECK);
273         $newAttrs = array();
274         foreach($objs as $obj){
275             $changes = false;
276             $attrs = array();
277             for($i = 0; $i < $obj['labeledURI']['count']; $i++){
278                 $c = $obj['labeledURI'][$i];
279                 $c = preg_replace('/'.preg_quote($src_dn,'/').'/',$dst_dn,$c);
280                 $attrs['labeledURI'][] = $c;
282                 // Check if something has changed
283                 if($c != $obj['labeledURI'][$i]){
284                     $changes =TRUE;
285                 }
286             }
288             // If at least one line of 'labeledURI' has changed then we have to update the whole entry.
289             if($changes)      $newAttrs[$obj['dn']] = $attrs;
290         }
291  
292         // If we've at least one entry to update then 
293         if(count($newAttrs)){
294             $ldap = $config->get_ldap_link();
295             foreach($newAttrs as $dn => $data){
296                 $ldap->cd($dn);
297                 $ldap->modify($data);
298                 if(!$ldap->success()){
299                     trigger_error(sprintf("Failed to dynamic group object for %s: %s", bold($dn), $ldap->get_error()));
300                     new log("debug",
301                             "plugin/plugin::move()",$dn,array(),
302                             " -- ERROR -- Failed to update dynamic groups (labeledURI) - ".$ldap->get_error());
303                 }else{
304                     new log("modify",
305                             "plugin/plugin::move()",$dn,array_keys($data),
306                             "Updated dynamic group entries (labeledURI)");
307                 }
308             }
309         }
310     }
313     /**
314      * Static method to set ACL for this plugin.
315      */
316     public static function plInfo()
317     {
318         return Array(
319                 "plShortName"   => _("Dynamic object"),
320                 "plDescription" => _("Dynamic object"),
321                 "plSelfModify"  => TRUE,
322                 "plDepends"     => Array(),
323                 "plPriority"    => 1,
324                 "plSection"     => Array("addon"),
325                 "plCategory"    => Array("groups", "department", "ogroups"),
326                 "plProvidedAcls" => array(
327                     'labeledURI' =>  _('Labeled URI'),
328                     )
329                 );
330     }
333 ?>