Code

Backport from trunk
[gosa.git] / gosa-plugins / netatalk / personal / netatalk / class_netatalk.inc
1 <?php
2 /*
3    This code is part of GOsa (https://gosa.gonicus.de)
4    Copyright (C) 2006  Gina Haeussge <osd@foosel.net>
5    Copyright (C) 2006  Bernd Zeimetz <bernd@zeimetz.de>
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
22 /*! \brief   netatalk plugin
23   \author  Gina Haeussge <osd@foosel.net>
24   \author  Bernd Zeimetz <bernd@zeimetz.de>
25   \version 0.1
26   \date    21.3.2006
28   This class provides the functionality to read and write all attributes
29   relevant for netatalk from/to the LDAP. It does syntax checking
30   and displays the formulars required.
31  */
33 class netatalk extends plugin {
35   /* Definitions */
36   var $plHeadline     = "Netatalk";
37   var $plDescription  = "Manage Netatalk account";
39   var $view_logged = FALSE;
41   /* Plugin specific values */
42   var $apple_user_homepath_raw   = "";
43   var $apple_user_homeurl_raw     = "";
44   var $apple_user_homeurl_xml     = "";
45   var $apple_user_homeurl       = "";
46   var $apple_user_homeDirectory   = "";
47   var $apple_user_share       = "";
48   var $shares             = array();
49   var $shares_settings        = array();
50   var $selectedshare        = "";
51   var $mountDirectory         = "/Network/Servers";
53   /* Attributes to save to LDAP */
54   var $attributes = array ("apple_user_homeurl", "apple_user_homeDirectory");
55   var $CopyPasteVars= array("apple_user_homeurl", "apple_user_homeDirectory",
56       "apple_user_share","shares_settings","apple_user_homepath_raw",
57       "apple_user_homeurl_raw","apple_user_homeurl_xml","apple_user_homeurl",
58       "selectedshare","mountDirectory");
60   /* Attributes to use in smarty template */
61   var $smarty_attributes = array ("apple_user_homepath_raw", "shares", "selectedshare");
63   /* Attributes to save from $_POST */
64   var $post_attributes = array ("netatalkShare"         => "apple_user_share", 
65                                 "netatalkUserHomepath"  => "apple_user_homepath_raw");
67   /* Objectclasses */
68   var $objectclasses = array ("apple-user");
69   var $uid ="";  
71   /* The constructor just saves a copy of the config. You may add what ever you need. */
72   function netatalk(&$config, $dn = NULL) 
73   {
75     /* Include config object */
76     $this->config = $config;
77     plugin::plugin($config, $dn);
79     /* set user id */    
80     if(isset($this->attrs['uid'])){
81       $this->uid = $this->attrs['uid'][0];
82     }
84     /* Netatalk attribute include '-' and we can't handle thos attribute names.
85        Copy all thos attribute into a useable name.
86      */
87     foreach($this->attributes as $val) {
88       $name = str_replace('_', '-', $val);
89       if (isset($this->attrs[$name][0])) {
90         $this->$val = $this->attrs[$name][0];
91       }
92     }
94     /* Extract homepath value 
95      */
96     if (strlen($this->apple_user_homeDirectory) >0) {
97       $this->apple_user_homepath_raw = 
98         substr($this->apple_user_homeDirectory, strrpos($this->apple_user_homeDirectory, '/') + 1 );
99     }
101     /* get share list an set default values */
102     $this->get_netatalk_shares(); 
103     $this->apple_user_share = $this->selectedshare;
105     if(!$this->is_account){
106         $this->apple_user_share = key($this->shares);
107     }
109     /* Save initial account state */
110     $this->initially_was_account = $this->is_account;
111   }
115   /* Get netatalk shares */
116   function get_netatalk_shares()
117   {
118     /* Get netatalk shares */
119     $this->shares = array();
120     $ldap = $this->config->get_ldap_link();
121     $ldap->cd($this->config->current['BASE']);
122     $ldap->search ("(&(objectClass=mount)(|(mountType=url)(mountType=nfs))(cn=*))");
124     while ($attrs = $ldap->fetch()){
125       $tmp  = explode(":", $attrs["cn"][0]);
126       $host = trim($tmp[0]);
127       $dir  = trim($tmp[1]);
128       $mountType = trim($attrs["mountType"][0]);
129       if ($mountType == "url") {
130         $mountTypeReal = "netatalk";
131       } else {
132         $mountTypeReal = $mountType;
133       } 
134       $share = $attrs["cn"][0]. " (" . $mountTypeReal . ")";
135       $this->shares[$share] = $share;
136       $this->shares_settings[$share]["mountType"]=$mountType;
137       $this->shares_settings[$share]["dir"]=$dir;
138       $this->shares_settings[$share]["host"]=$host;
140       $oldShare=substr($this->apple_user_homeDirectory, 0, strrpos($this->apple_user_homeDirectory, '/'));
141       $newShare=($this->mountDirectory . "/". $host . $dir );
142       if (strcmp($oldShare, $newShare)==0) {
143         $this->selectedshare = $share;
144       }
145     }
146     asort($this->shares);
147   }
150   /* Execute the plugin, produce the output. */
151   function execute() 
152   {
153     plugin :: execute();
155     /* Log view */
156     if($this->is_account && !$this->view_logged){
157       $this->view_logged = TRUE;
158       new log("view","users/".get_class($this),$this->dn);
159     }
161     /* Use the smarty templating engine here... */
162     $smarty = get_smarty();
163     $display = "";
165     /* Do we need to flip is_account state? */
166     if (isset ($_POST['modify_state'])) {
167       $this->is_account = !$this->is_account;
168     }
170     /* Do we represent a valid account? */
171     if (!$this->is_account && $this->parent === NULL) {
172       $display = "<img alt=\"\"src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
173         msgPool::noValidExtension(_("Netatalk"))."</b>";
174       $display .= back_to_main();
175       return ($display);
176     }
178     /* Show tab dialog headers */
179     if ($this->parent !== NULL) {
180       if ($this->is_account) {
181         $display = $this->show_disable_header(msgPool::removeFeaturesButton(_("Netatalk")), 
182             msgPool::featuresEnabled(_("Netatalk")));
183       } else {
184         $errmsg="";
185         $obj = $this->parent->by_object['posixAccount'];
186         if  (!($obj->is_account) ) {
187           $display = $this->show_enable_header(msgPool::addFeaturesButton(_("Netatalk")), 
188               msgPool::featuresDisabled(_("Netatalk"), _("POSIX")), TRUE);
189         } elseif (count($this->shares)== 0) {
190           $display = $this->show_enable_header(msgPool::addFeaturesButton(_("Netatalk")), 
191               msgPool::featuresDisabled(_("Netatalk"), _("Netatalk or NFS share")), TRUE);
192         } else {
193           $display = $this->show_enable_header(msgPool::addFeaturesButton(_("Netatalk")), 
194               msgPool::featuresDisabled(_("Netatalk")));
195         } 
196         return ($display);
197       }
198     }
200     /* Assign attributes 
201      */
202     foreach ($this->smarty_attributes as $val) {
203       $smarty->assign("$val", set_post($this-> $val));
204     }
206     /* Assign ACLs 
207      */
208     $tmp = $this->plInfo();
209     foreach($tmp['plProvidedAcls'] as $name => $desc){
210       $smarty->assign($name."ACL",$this->getacl($name));
211     }
213     /* Let smarty fetch and process the page. */
214     $display .= ($smarty->fetch(get_template_path('netatalk.tpl', TRUE, dirname(__FILE__))));
215     return ($display);
216   }
219   /* Check if we have correct data */
220   function check() 
221   {
222     $message = array ();
223     if (strlen($this->apple_user_share) == 0) {
224       $message[] = msgPool::required(_("Share"));
225     }
226     return ($message);
227   }
230   /* Save to LDAP */
231   function save() 
232   {
234     /* remove a / at the end of the homepath, we neither need it there nor
235      * do we want to check for it later.
236      */
237     if(substr($this->apple_user_homepath_raw, -1, 1) === '/') {
238       $this->apple_user_homepath_raw=substr($this->apple_user_homepath_raw, 0, -1);
239     }
241     $mountType=$this->shares_settings[$this->apple_user_share]["mountType"];
242     $dir=$this->shares_settings[$this->apple_user_share]["dir"];
243     $host=$this->shares_settings[$this->apple_user_share]["host"];
245     /* Convert raw data to wished format */
246     if ($this->is_account) {
247       if($mountType=="url") {
248         $this->apple_user_homeurl_xml = '<home_dir><url>afp://'.$host.$dir . '</url><path>'.
249           $this->apple_user_homepath_raw.'</path></home_dir>';
250         $this->apple_user_homeurl = $this->apple_user_homeurl_xml;
251       } else {
252         $this->apple_user_homeurl = "";
253       }
254       $this->apple_user_homeDirectory = $this->mountDirectory . '/' . $host .
255         $dir . '/' . $this->apple_user_homepath_raw;
256     } else {
257       $this->apple_user_homeurl = "";
258       $this->apple_user_homeDirectory = "";
259     }
261     $ldap = $this->config->get_ldap_link();
262     plugin :: save();
264     /* Transform variable names from '_' to '-'.
265      */
266     foreach ($this->attributes as $val) {
267       unset($this->attrs[$val]);
268       $name = str_replace('_', '-', $val);
269       if ($this->$val != "") {
270         $this->attrs[$name] = $this->$val;
271       } else {
272         $this->attrs[$name] = array();
273       }
274     }
276     /* Write back to ldap */
277     $ldap->cd($this->dn);
278     $this->cleanup();
279     $ldap->modify($this->attrs);
281     if($this->initially_was_account){
282       new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
283     }else{
284       new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
285     }
287     if (!$ldap->success()){
288       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
289     }
291     /* Optionally execute a command after we're done */
292     if ($this->initially_was_account == $this->is_account) {
293       if ($this->is_modified) {
294         $this->handle_post_events("modify",array("uid" => $this->uid));
295       }
296     } else {
297       $this->handle_post_events("add",array("uid" => $this->uid));
298     }
299   }
302   /* Use Save_object for every Post handling 
303    */
304   function save_object() 
305   {
306     if (isset ($_POST['netatalkTab'])) {
307       /* Save ldap attributes */
308       plugin :: save_object();
310       foreach($this->post_attributes as $acl => $val) {
311         if(!preg_match("/w/",$this->getacl($acl))) continue;
312         if (isset ($_POST[$val])) {
313           $this->$val = get_post($val);
314         } else {
315           $this->$val = "";
316         }
317       }
318       $this->apple_user_homeurl_raw = 'afp://' . $this->apple_user_share;
319     }
320   }
323   function remove_from_parent() 
324   {
326     /* Cancel if there's nothing to do here */
327     if (!$this->initially_was_account) {
328       return;
329     }
331     /* include global link_info */
332     $ldap = $this->config->get_ldap_link();
334     /* Remove and write to LDAP */
335     plugin :: remove_from_parent();
336     $this->cleanup();
338     /* Attribute name conversion "_" to "-" */
339     foreach($this->attributes as $val){
340       unset($this->attrs[$val]);
341       $name = preg_replace("/_/","-",$val);
342       $this->attrs[$name] = array();
343     }
345     @ DEBUG(DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $this->attributes, "Save");
346     $ldap->cd($this->dn);
348     $ldap->modify($this->attrs);
350     new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
352     if (!$ldap->success()){
353       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
354     }
356     /* remove the entry from LDAP */
357     unset ($this->attrs['uid']);
359     /* Optionally execute a command after we're done */
360     $this->handle_post_events('remove', array("uid" => $this->uid));
361   }
364   /* Return plugin informations for acl handling*/
365   static function plInfo()
366   {
367     return (array(
368           "plDescription"     => _("Netatalk"),
369           "plSelfModify"      => TRUE,
370           "plDepends"         => array("user"),
371           "plPriority"        => 6,
372           "plSection"     => array("personal" => _("My account")),
373           "plCategory"    => array("users"),
374           "plOptions"         => array(),
375           "plRequirements"=> array(
376               'ldapSchema' => array('apple-user' => ''),
377               'onFailureDisablePlugin' => array(get_class())),
378           "plProvidedAcls"  => array(
379             "netatalkUserHomepath"   =>  _("User home path"),
380             "netatalkShare"          =>  _("Share"))
381           ));
382   }
384   function adapt_from_template($dn, $skip= array())
385   {
386     /* As the 'apple-user-homeDirectory' LDAP attribute is stored as
387      * 'apple_user_homeDirectory' internally by GOsa (to avoid problem with
388      * dashes as variable names), we need to add the dashed version to
389      * $this->attributes so that the adapt_from_template function in the plugin
390      * class will find the dashed LDAP attribute and substitute possibly
391      * placeholders like %uid. We remove the dashed version of
392      * 'apple_user_homeDirectory' from the attributes again afterwards. */
393     array_push($this->attributes, "apple-user-homeDirectory");
394     plugin::adapt_from_template($dn, $skip);
395     array_pop($this->attributes);
396   
397     /* Loop through the available shares and find out which is the share from
398      * 'apple-user-homeDirectory'. Remove its host and directory (as well as
399      * the default 'mountDirectory' prefix) to get 'apple_user_homepath_raw'
400      * and store that share as 'selectedshare' so that it gets displayed by
401      * default in the netatalk tab. */
402     foreach($this->shares as $share) {
403       $apple_user_homepath = $this->mountDirectory."/".
404                         $this->shares_settings[$share]["host"].
405                         $this->shares_settings[$share]["dir"]."/";
406       if (preg_match("#$apple_user_homepath#", $this->{'apple-user-homeDirectory'})) {
407         $this->apple_user_homepath_raw =  preg_replace("#$apple_user_homepath#", "", $this->{'apple-user-homeDirectory'});
408         $this->selectedshare = $share;
409       }
410     }
411   }   
414 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
415 ?>