1 <?php
2 class workstartup extends plugin
3 {
4 /* Ldap server list */
5 var $gotoLdapServers = array();
6 var $gotoLdapServerList = array();
7 var $gotoLdap_inherit = FALSE;
9 /* Generic terminal attributes */
10 var $bootmode = "G";
11 var $gotoBootKernel = "default-inherited";
12 var $gotoKernelParameters = "";
13 var $gotoLdapServer = "default-inherited";
14 var $gotoModules = array();
15 var $gotoAutoFs = array();
16 var $gotoFilesystem = array();
17 var $gotoTerminalPath = "";
18 var $gotoBootKernels = array();
20 /* attribute list for save action */
21 var $attributes = array("gotoLdapServer", "gotoBootKernel", "gotoKernelParameters",
22 "FAIclass", "FAIstatus", "gotoShare","FAIdebianMirror", "FAIrelease");
23 var $objectclasses = array("GOhard", "FAIobject");
25 /* Share */
26 var $gotoShares = array();// Currently Share Option
27 var $gotoShare = ""; // currently selected Share Option
28 var $gotoShareSelections= array();// Available Shares for this account in Listbox format
29 var $gotoAvailableShares= array();// Available Shares for this account
31 /* Helper */
32 var $customParameters = "";
33 var $orig_dn = "";
34 var $ignore_account = TRUE;
36 /* FAI class selection */
37 var $FAIclass = array(); // The currently selected classes
38 var $FAIrelease = "";
39 var $FAIdebianMirror = "auto";
41 var $cache = array(); // Used as cache in fai mehtods
43 var $FAIstatus = "";
44 var $FAIclasses = array();
46 var $view_logged = FALSE;
48 /* FAI class selection */
49 var $InheritedFAIclass = array();
50 var $InheritedFAIrelease = "";
51 var $InheritedFAIdebianMirror= "auto";
53 var $CopyPasteVars = array("gotoModules","gotoShares");
54 var $fai_activated = FALSE;
55 var $o_group_dn = "";
56 var $member_of_ogroup = FALSE;
58 function workstartup (&$config, $dn= NULL, $parent= NULL)
59 {
60 /* Check if FAI is active */
61 $tmp= $config->search("faiManagement", "CLASS",array('menu','tabs'));
62 if(!empty($tmp)){
63 $this->fai_activated = TRUE;
64 }else{
65 $this->attributes = array("gotoLdapServer", "gotoBootKernel", "gotoKernelParameters", "gotoShare");
66 $this->objectclasses = array("GOhard");
67 }
69 plugin::plugin ($config, $dn, $parent);
71 /* Check object group membership */
72 if(!isset($this->parent->by_object['ogroup'])){
73 $ldap = $this->config->get_ldap_link();
74 $ldap->cd ($this->config->current['BASE']);
75 $ldap->search("(&(objectClass=gotoWorkstationTemplate)(member=".LDAP::prepare4filter($this->dn)."))",array("cn","dn"));
76 if($ldap->count()){
77 $this->member_of_ogroup = TRUE;
78 $attrs = $ldap->fetch();
79 $this->o_group_dn = $attrs['dn'];
80 }
81 }
83 /* Creating a list of valid Mirrors
84 * none will not be saved to ldap.
85 */
86 $ldap = $this->config->get_ldap_link();
87 $ldap->cd($this->config->current['BASE']);
88 foreach($this->config->data['SERVERS']['LDAP'] as $server) {
89 $this->gotoLdapServerList[]= $server;
90 }
92 /* Get list of assigned ldap servers
93 */
94 if(isset($this->attrs['gotoLdapServer'])){
95 unset($this->attrs['gotoLdapServer']['count']);
96 sort($this->attrs['gotoLdapServer']);
97 foreach($this->attrs['gotoLdapServer'] as $value){
98 $this->gotoLdapServers[] = preg_replace("/^[0-9]*:/","",$value);
99 }
100 }
101 if(!count($this->gotoLdapServers) && $this->member_of_ogroup){
102 $this->gotoLdap_inherit = TRUE;
103 }
105 /* FAI Initialization
106 Skip this if FAI is not activated
107 */
108 if($this->fai_activated) {
110 $this->update_fai_cache(TRUE);
112 /* Parse used FAIclasses (stored as string).
113 * The single classes are seperated by ' '.
114 * There is also the release type given, after first
115 * occurrence of ':'.
116 */
117 $this->FAIclass =array();
118 if(isset($this->attrs['FAIclass'][0])){
119 $tmp = split(" ",$this->attrs['FAIclass'][0]);
120 $tmp2 =array();
122 foreach($tmp as $class){
123 if( ":" == $class[0] ) {
124 $this->FAIrelease = trim(substr($class, 1));
125 }else{
126 $tmp2[$class] = $class;
127 }
128 }
129 $this->FAIclass = $tmp2;
130 }
131 }
133 /* Get arrays */
134 foreach (array("gotoModules", "gotoAutoFs", "gotoFilesystem") as $val){
135 if (isset($this->attrs["$val"]["count"])){
136 for ($i= 0; $i<$this->attrs["count"]; $i++){
137 if (isset($this->attrs["$val"][$i])){
138 array_push($this->$val, $this->attrs["$val"][$i]);
139 }
140 }
141 }
142 sort ($this->$val);
143 $this->$val= array_unique($this->$val);
144 }
146 /* Parse Kernel Parameters to decide what boot mode is enabled */
147 if (preg_match("/ splash=silent/", $this->gotoKernelParameters)){
148 $this->bootmode= "G";
149 } elseif (preg_match("/ debug/", $this->gotoKernelParameters)){
150 $this->bootmode= "D";
151 } elseif ($this->gotoKernelParameters == "") {
152 $this->bootmode= "G";
153 } else {
154 $this->bootmode= "T";
155 }
156 if (preg_match("/ o /", $this->gotoKernelParameters)){
157 $this->customParameters= preg_replace ("/^.* o /", "", $this->gotoKernelParameters);
158 } else {
159 $this->customParameters= "";
160 }
162 /* Prepare Shares */
163 if((isset($this->attrs['gotoShare']))&&(is_array($this->attrs['gotoShare']))){
164 unset($this->attrs['gotoShare']['count']);
165 foreach($this->attrs['gotoShare'] as $share){
166 $tmp = $tmp2 = array();
167 $tmp = split("\|",$share);
168 $tmp2['server'] =$tmp[0];
169 $tmp2['name'] =$tmp[1];
170 $tmp2['mountPoint'] =$tmp[2];
171 $this->gotoShares[$tmp[1]."|".$tmp[0]]=$tmp2;
172 }
173 }
175 $this->gotoShareSelections= $config->getShareList(true);
176 $this->gotoAvailableShares= $config->getShareList(false);
177 $tmp2 = array();
180 $this->orig_dn= $this->dn;
182 /* Handle inheritance value "default" */
183 if ($this->member_of_ogroup){
184 $this->gotoBootKernels= array("default-inherited" => '['._("inherited").']');
185 }
187 /* If we are member in an object group,
188 * we have to handle inherited values.
189 * So you can see what is inherited.
190 */
191 if ($this->member_of_ogroup){
193 if(count($this->FAIclass)==0 && $this->FAIrelease == ""){
194 $this->FAIdebianMirror = "inherited";
195 }
197 if($this->fai_activated){
198 $map= array("gotoBootKernel","FAIclass","FAIdebianMirror");
199 }else{
200 $map= array("gotoBootKernel");
201 }
203 $ldap = $this->config->get_ldap_link();
204 $ldap->cat($this->o_group_dn);
205 $attrs= $ldap->fetch();
207 foreach ($map as $name){
208 if (!isset($attrs[$name][0])){
209 continue;
210 }
212 switch ($name){
213 case 'gotoBootKernel':
214 $this->gotoBootKernels['default-inherited']= _("inherited").' ['.$attrs[$name][0].']' ;
215 break;
217 case 'FAIclass':
218 $str = split(":",$attrs[$name][0]);
219 $this->InheritedFAIclass = split("\ ",trim($str[0]));
220 $this->InheritedFAIrelease = trim($str[1]);
221 break;
223 case 'FAIdebianMirror':
224 $this->InheritedFAIdebianMirror = $attrs[$name][0];
225 break;
226 }
227 }
228 }
231 if($this->fai_activated){
233 /* Check if the current mirror is available
234 */
235 if(!isset($this->cache['SERVERS'][$this->FAIdebianMirror])){
236 if(count($this->FAIclass)){
237 print_red(sprintf(_("The selected FAI mirror '%s' is no longer available, the mirror was set to 'auto'."),
238 $this->FAIdebianMirror));
239 }
240 $this->FAIdebianMirror = "auto";
241 $this->FAIrelease = key($this->cache['SERVERS'][$this->FAIdebianMirror]);
242 $this->cache =array();
243 $this->update_fai_cache();
245 }
247 /* Check if the current mirror is available
248 */
249 if(!isset($this->cache['SERVERS'][$this->FAIdebianMirror][$this->FAIrelease])){
250 $new_release = key($this->cache['SERVERS'][$this->FAIdebianMirror]);
251 if(count($this->FAIclass)){
252 print_red(sprintf(_("The selected FAI release '%s' is not available for mirror '%s', the release was set to '%s'."),
253 $this->FAIrelease,$this->FAIdebianMirror,$new_release));
254 }
255 $this->FAIrelease = $new_release;
256 $this->cache =array();
257 $this->update_fai_cache();
258 }
259 }
261 /* Get list of boot kernels */
262 if (isset($this->config->data['TABS'])){
263 $command= $this->config->search(get_class($this), "KERNELS",array('tabs'));
264 if (!check_command($command)){
265 $message[]= sprintf(_("Command '%s', specified as KERNELS hook for plugin '%s' doesn't seem to exist."), $command,
266 get_class($this));
267 } else {
268 $fh= popen($command, "r");
269 while (!feof($fh)) {
270 $buffer= trim(fgets($fh, 256));
271 if(!empty($buffer)){
272 $name=$value = $buffer;
273 if(preg_match("/:/",$buffer)){
274 $name = preg_replace("/:.*$/","",$buffer);
275 $value= preg_replace("/^.*:/","",$buffer);
276 $this->gotoBootKernels[$name]= $name.":".$value;
277 }else{
278 $this->gotoBootKernels[$name]= $value;
279 }
280 }
281 }
282 pclose($fh);
283 }
284 }
286 /* Turn to default, if we've nothing to inherit */
287 if (!isset($this->gotoBootKernels['default-inherited']) && $this->gotoBootKernel == "default-inherited"){
288 $this->gotoBootKernel= "default";
289 }
290 }
293 function check()
294 {
295 $messages = array();
297 /* Call common method to give check the hook */
298 $messages= plugin::check();
300 /* If there are packages selected, but no mirror show error */
301 if(($this->FAIdebianMirror == "none")&&(count($this->FAIclass)>0)){
302 $messages[]=_("Please select a 'FAI server' or remove the 'FAI classes'.");
303 }
305 return($messages);
306 }
308 function execute()
309 {
310 /* Call parent execute */
311 plugin::execute();
313 if($this->is_account && !$this->view_logged){
314 $this->view_logged = TRUE;
315 new log("view","workstation/".get_class($this),$this->dn);
316 }
318 /* Do we need to flip is_account state? */
319 if(isset($_POST['modify_state'])){
320 if($this->is_account && $this->acl_is_removeable()){
321 $this->is_account= FALSE;
322 }elseif(!$this->is_account && $this->acl_is_createable()){
323 $this->is_account= TRUE;
324 }
325 }
327 /* Do we represent a valid terminal? */
328 if (!$this->is_account && $this->parent === NULL){
329 $display= "<img alt=\"\" src=\"images/stop.png\" align=middle> <b>".
330 _("This 'dn' has no terminal features.")."</b>";
331 return ($display);
332 }
334 /* Add module */
335 if (isset ($_POST['add_module'])){
336 if ($_POST['module'] != "" && $this->acl_is_writeable("gotoModule")){
337 $this->add_list ($this->gotoModules, $_POST['module']);
338 }
339 }
341 /* Delete module */
342 if (isset ($_POST['delete_module'])){
343 if (count($_POST['modules_list']) && $this->acl_is_writeable("gotoModule")){
344 $this->del_list ($this->gotoModules, $_POST['modules_list']);
345 }
346 }
348 /* FAI class management */
349 if($this->fai_activated){
350 if(((isset($_POST['AddClass']))&&(isset($_POST['FAIclassesSel']))) && ($this->acl_is_writeable("FAIclass"))){
351 $found = 0 ;
353 /* If this new class/profile will attach a second partition table
354 * to our list of classes, abort and show a message.
355 */
356 foreach($this->FAIclass as $name){
357 if(isset($this->FAIclassInfo[$name])){
358 foreach($this->FAIclassInfo[$name] as $atr){
359 if(isset($atr['obj'])){
360 if($atr['obj'] == "FAIpartitionTable"){
361 $found ++ ;
362 }
363 }
364 }
365 }
366 }
368 if((isset($this->FAIclassInfo[$_POST['FAIclassesSel']]['FAIpartitionTable']))&&($found>0)){
369 print_red(_("There is already a profile in your selection that contain partition table configurations."));
370 }else{
371 $this->FAIclass[$_POST['FAIclassesSel']]=$_POST['FAIclassesSel'];
372 }
373 }
375 $sort = false;
377 /* Move one used class class one position up or down */
378 if($this->acl_is_writeable("FAIclass")){
379 foreach($_POST as $name => $val){
381 $sort_type = false;
382 if((preg_match("/sort_up/",$name))&&(!$sort)){
383 $sort_type = "sort_up_";
384 }
385 if((preg_match("/sort_down/",$name))&&(!$sort)){
386 $sort_type = "sort_down_";
387 }
389 if(($sort_type)&&(!$sort)){
390 $value = base64_decode(preg_replace("/_.*$/i","",preg_replace("/".$sort_type."/i","",$name)));
391 $sort = true;
393 $last = -1;
394 $change_down = -1;
396 /* Create array with numeric index */
397 $tmp = array();
398 foreach($this->FAIclass as $class){
399 $tmp [] = $class;
400 }
402 /* Walk trough array */
403 foreach($tmp as $key => $faiName){
404 if($faiName == $value){
405 if($sort_type == "sort_up_"){
406 if($last != -1){
407 $change_down= $last;
408 }
409 }else{
410 if(isset($tmp[$key+1])){
411 $change_down = $key;
412 }
413 }
414 }
415 $last = $key;
416 }
418 $tmp2 = array();
419 $skip = false;
421 foreach($tmp as $ky => $vl){
423 if($ky == $change_down){
424 $skip = $vl;
425 }else{
426 $tmp2[$vl] = $vl;
427 }
428 if(($skip != false)&&($ky != $change_down)){
429 $tmp2[$skip] = $skip;
430 $skip =false;
431 }
432 }
433 $this->FAIclass = $tmp2;
434 }
436 if(preg_match("/fai_remove/i",$name)){
437 $value = base64_decode(preg_replace("/_.*$/i","",preg_replace("/fai_remove_/i","",$name)));
438 unset($this->FAIclass[$value]);
439 }
440 }
441 }
443 /* Delete selected class from our list */
444 if($this->acl_is_writeable("FAIclass")){
445 if((isset($_POST['DelClass']))&&(isset($_POST['FAIclassSel']))){
446 if(isset($this->FAIclass[$_POST['FAIclassSel']])){
447 unset($this->FAIclass[$_POST['FAIclassSel']]);
448 }
449 }
450 }
451 }// END fai handling
453 /* Show main page */
454 $smarty= get_smarty();
456 /* Assign ACLs to smarty */
457 $tmp = $this->plInfo();
458 foreach($tmp['plProvidedAcls'] as $name => $translation){
459 $smarty->assign($name."ACL",$this->getacl($name));
460 }
462 $smarty->assign("member_of_ogroup",$this->member_of_ogroup);
464 /* In this section server shares will be defined
465 * A user can select one of the given shares and a mount point
466 * and attach this combination to his setup.
467 */
468 $smarty->assign("gotoShareSelections", $this->gotoShareSelections);
469 $smarty->assign("gotoShareSelectionKeys", array_flip($this->gotoShareSelections));
471 /* if $_POST['gotoShareAdd'] is set, we will try to add a new entry
472 * This entry will be, a combination of mountPoint and sharedefinitions
473 */
474 if((isset($_POST['gotoShareAdd'])) && ($this->acl_is_writeable("gotoShare"))) {
475 /* We assign a share to this user, if we don't know where to mount the share */
476 if((!isset($_POST['gotoShareMountPoint']))||(empty($_POST['gotoShareMountPoint']))||(preg_match("/[\|]/i",$_POST['gotoShareMountPoint']))){
477 print_red(_("You must specify a valid mount point."));
478 }else{
479 if(count($this->gotoAvailableShares)){
480 $a_share = $this->gotoAvailableShares[$_POST['gotoShareSelection']];
481 $s_mount = $_POST['gotoShareMountPoint'];
482 /* Preparing the new assignment */
483 $this->gotoShares[$a_share['name']."|".$a_share['server']]=$a_share;
484 $this->gotoShares[$a_share['name']."|".$a_share['server']]['mountPoint']=$s_mount;
485 }
486 }
487 }
489 /* if the Post gotoShareDel is set, someone asked GOsa to delete the selected entry (if there is one selected)
490 * If there is no defined share selected, we will abort the deletion without any message
491 */
492 if(($this->acl_is_writeable("gotoShare"))&& (isset($_POST['gotoShareDel']))&&(isset($_POST['gotoShare']))){
493 unset($this->gotoShares[$_POST['gotoShare']]);
494 }
496 $smarty->assign("gotoShares",$this->printOutAssignedShares());
497 $smarty->assign("gotoSharesCount",count($this->printOutAssignedShares()));
498 $smarty->assign("gotoShareKeys",array_flip($this->printOutAssignedShares()));
499 $smarty->assign("gotoBootKernels",$this->gotoBootKernels);
501 /* Create divSelectBox for ldap server selection
502 */
503 $SelectBoxLdapServer = new divSelectBox("LdapServer");
504 $SelectBoxLdapServer->SetHeight(130);
506 /* Add new ldap server to the list */
507 if(!$this->gotoLdap_inherit && isset($_POST['add_ldap_server']) && isset($_POST['ldap_server_to_add'])){
508 if(isset($this->gotoLdapServerList[$_POST['ldap_server_to_add']])){
509 $to_add = $this->gotoLdapServerList[$_POST['ldap_server_to_add']];
510 if(!in_array($to_add,$this->gotoLdapServers)){
511 $this->gotoLdapServers[] = $to_add;
512 }
513 }
514 }
516 /* Move ldap servers up and down */
517 if(!$this->gotoLdap_inherit){
518 foreach($_POST as $name => $value){
519 if(preg_match("/sort_ldap_up_/",$name)){
520 $id = preg_replace("/^sort_ldap_up_([0-9]*)_(x|y)$/","\\1",$name);
521 $from = $id;
522 $to = $id -1;
523 $tmp = $this->array_switch_item($this->gotoLdapServers,$from,$to);
524 if($tmp){
525 $this->gotoLdapServers = $tmp;
526 }
527 break;
528 }
529 if(preg_match("/sort_ldap_down_/",$name)){
530 $id = preg_replace("/^sort_ldap_down_([0-9]*)_(x|y)$/","\\1",$name);
531 $from = $id;
532 $to = $id +1;
533 $tmp = $this->array_switch_item($this->gotoLdapServers,$from,$to);
534 if($tmp){
535 $this->gotoLdapServers = $tmp;
536 }
537 break;
538 }
539 if(preg_match("/gotoLdapRemove_/",$name)){
540 $id = preg_replace("/^gotoLdapRemove_([0-9]*)_(x|y)$/","\\1",$name);
541 $value = $this->gotoLdapServers[$id];
542 $this->gotoLdapServers = array_remove_entries(array($value),$this->gotoLdapServers);
543 break;
544 }
545 }
546 }
548 /* Add Entries
549 */
550 foreach($this->gotoLdapServers as $key => $server){
551 if(!in_array($server,$this->gotoLdapServerList)){
552 $server = $server." <font style='color:red'>(missing)</font>";
553 }
555 $SelectBoxLdapServer->AddEntry(
556 array(array("string" => $server),
557 array("string" =>
558 "<input class='center' type='image' src='images/sort_up.png' name='sort_ldap_up_".$key."'> ".
559 "<input class='center' type='image' src='images/sort_down.png' name='sort_ldap_down_".$key."'> ".
560 "<input class='center' type='image' src='images/edittrash.png' name='gotoLdapRemove_".$key."'>",
561 "attach" => "style='text-align:right;width:40px;border-right:0px;'")));
562 }
564 if($this->gotoLdap_inherit){
565 $smarty->assign("gotoLdapServerACL_inherit", preg_replace("/w/","",$this->getacl("gotoLdapServer")));;
566 }else{
567 $smarty->assign("gotoLdapServerACL_inherit", $this->getacl("gotoLdapServer"));
568 }
570 $list = array();
571 foreach($this->gotoLdapServerList as $key => $entry){
572 if(!in_array($entry,$this->gotoLdapServers)){
573 $list[$key] = $entry;
574 }
575 }
576 $smarty->assign("gotoLdapServers", $SelectBoxLdapServer->DrawList());
577 $smarty->assign("gotoLdapServerList", $list);
578 $smarty->assign("gotoLdap_inherit", $this->gotoLdap_inherit);
579 $smarty->assign("JS", session::get('js'));
581 foreach (array("gotoModules", "gotoAutoFs", "gotoFilesystem") as $val){
582 $smarty->assign("$val", $this->$val);
583 }
585 /* Values */
586 foreach(array("gotoBootKernel", "customParameters", "gotoShare","FAIclasses","FAIclass","FAIdebianMirror","FAIrelease") as $val){
587 $smarty->assign($val, $this->$val);
588 }
590 $smarty->assign("fai_activated",$this->fai_activated);
592 /* Create FAI output */
593 if($this->fai_activated){
595 $this->update_fai_cache();
597 $smarty->assign("FAIservers" , $this->cache['SERVERS']);
598 $smarty->assign("FAIdebianMirror",$this->FAIdebianMirror);
599 $smarty->assign("FAIrelease" , $this->FAIrelease);
600 $smarty->assign("FAIclasses" , $this->selectable_classes());
602 $smarty->assign("InheritedFAIrelease",$this->InheritedFAIrelease);
604 $div = new divSelectBox("WSFAIscriptClasses");
605 $div -> SetHeight("110");
606 $str_up = " <input type='image' src='images/sort_up.png' name='sort_up_%s' value='%s'>";
607 $str_down = " <input type='image' src='images/sort_down.png' name='sort_down_%s' value='%s'>";
608 $str_remove = " <input type='image' src='images/edittrash.png' name='fai_remove_%s' value='%s'>";
609 $str_empty = " <img src='images/empty.png' alt=\"\" width='7'>";
611 /* Get classes */
612 if($this->FAIdebianMirror == "inherited"){
613 $tmp = $this->InheritedFAIclass;
614 }else{
615 $tmp = $this->FAIclass;
616 }
618 /* Get invalid classes */
619 $invalid = $this->get_invalid_classes($tmp);
621 /* Draw every single entry */
622 $i = 1;
623 foreach($tmp as $class){
625 /* Mark invalid classes. (Not in selected release)
626 */
627 $marker = "";
628 if(in_array_ics($class,$invalid)){
629 $marker = " <font color='red'>("._("Not available in current setup").")</font>";
630 }
632 /* Create up/down priority icons
633 * Skip this, if we have inherited the FAI classes.
634 */
635 if($this->FAIdebianMirror == "inherited"){
636 $str = "";
637 }else{
638 if($i==1){
639 $str = $str_empty.$str_down.$str_remove;
640 }elseif($i == count($this->FAIclass)){
641 $str = $str_up.$str_empty.$str_remove;
642 }else{
643 $str = $str_up.$str_down.$str_remove;
644 }
645 }
646 $i ++ ;
648 /* Get Description tag
649 * There may be several FAI objects with the same class name,
650 * use the description from FAIprofile, if possible.
651 */
652 $desc = "";
653 if(isset($this->cache['CLASSES'][$this->FAIrelease][$class])){
654 foreach($this->cache['CLASSES'][$this->FAIrelease][$class] as $types ){
655 if(isset($types['Desc'])){
656 $desc= $types['Desc'];
657 if($types['Type'] == "FAIprofile"){
658 break;
659 }
660 }
661 }
662 }
663 if(!empty($desc)){
664 $desc = " [".trim($desc)."]";
665 }
667 $div->AddEntry(array(
668 array("string"=>$class.$desc.$marker),
669 array("string"=>preg_replace("/\%s/",base64_encode($class),$str),"attach"=>"style='width:50px;border-right:none;'")
670 ));
671 }
672 $smarty->assign("FAIScriptlist",$div->DrawList());
673 }// END FAI output generation
675 /* Radio button group */
676 if (preg_match("/G/", $this->bootmode)) {
677 $smarty->assign("graphicalbootup", "checked");
678 } else {
679 $smarty->assign("graphicalbootup", "");
680 }
681 if (preg_match("/T/", $this->bootmode)) {
682 $smarty->assign("textbootup", "checked");
683 } else {
684 $smarty->assign("textbootup", "");
685 }
686 if (preg_match("/D/", $this->bootmode)) {
687 $smarty->assign("debugbootup", "checked");
688 } else {
689 $smarty->assign("debugbootup", "");
690 }
692 /* Show main page */
693 return($smarty->fetch (get_template_path('workstationStartup.tpl', TRUE,dirname(__FILE__))));
694 }
697 function remove_from_parent()
698 {
699 $this->handle_post_events("remove");
700 new log("remove","workstation/".get_class($this),$this->dn);
701 }
704 /* Save data to object */
705 function save_object()
706 {
707 $old_mirror = $this->FAIdebianMirror;
708 plugin::save_object();
710 /* Update release */
711 if($old_mirror != $this->FAIdebianMirror){
712 if(!isset($this->cache['SERVERS'][$this->FAIdebianMirror][$this->FAIrelease])){
713 $this->FAIrelease = key($this->cache['SERVERS'][$this->FAIdebianMirror]);
714 }
715 }
717 if(isset($_POST['WorkstationStarttabPosted'])){
718 if(isset($_POST['gotoLdap_inherit'])){
719 $this->gotoLdap_inherit = TRUE;
720 }else{
721 $this->gotoLdap_inherit = FALSE;
722 }
724 /* Save group radio buttons */
725 if ($this->acl_is_writeable("bootmode") && isset($_POST["bootmode"])){
726 $this->bootmode= $_POST["bootmode"];
727 }
729 /* Save kernel parameters */
730 if ($this->acl_is_writeable("gotoKernelParameters") && isset($_POST["customParameters"])){
731 $this->customParameters= $_POST["customParameters"];
732 }
733 }
734 }
737 /* Save to LDAP */
738 function save()
739 {
741 /* Depending on the baseobject (Ogroup / WS) we
742 * use another set of objectClasses
743 * In case of WS itself, we use "array("GOhard", "FAIobject");"
744 * if we are currently editing from ogroup menu we use (array("gotWorkstationTemplate","GOhard", "FAIobject"))
745 */
746 if(isset($this->parent->by_object['ogroup'])){
747 $this->objectclasses = array("gotoWorkstationTemplate");
748 }elseif(isset($this->parent->by_object['workgeneric'])){
749 $this->objectclasses = array("GOhard");
750 }elseif(isset($this->parent->by_object['servgeneric'])){
751 $this->objectclasses = array("GOhard","gotoWorkstationTemplate");
752 }else{
753 print "Object Type Configuration : unknown";
754 exit();
755 }
757 /* Append FAI class */
758 if($this->fai_activated){
759 $this->objectclasses[] = "FAIobject";
760 }
762 /* Find proper terminal path for tftp configuration
763 FIXME: This is suboptimal when the default has changed to
764 another location! */
765 if (($this->gotoTerminalPath == "default")){
766 $ldap= $this->config->get_ldap_link();
768 /* Strip relevant part from dn, keep trailing ',' */
769 $tmp= preg_replace("/^cn=[^,]+,".get_ou('terminalou')."/i", "", $this->dn);
770 $tmp= preg_replace("/".$this->config->current['BASE']."$/i", "", $tmp);
772 /* Walk from top to base and try to load default values for
773 'gotoTerminalPath'. Abort when an entry is found. */
774 while (TRUE){
775 $tmp= preg_replace ("/^[^,]+,/", "", $tmp);
777 $ldap->cat("cn=default,".get_ou('terminalou').$tmp.
778 $this->config->current['BASE'], array('gotoTerminalPath'));
779 $attrs= $ldap->fetch();
780 if (isset($attrs['gotoTerminalPath'])){
781 $this->gotoTerminalPath= $attrs['gotoTerminalPath'][0];
782 break;
783 }
785 /* Nothing left? */
786 if ($tmp == ""){
787 break;
788 }
789 }
790 }
792 /* Add semi automatic values */
793 // FIXME: LDAP Server may not be set here...
794 $this->gotoKernelParameters= "ldap=".base64_encode($this->gotoLdapServer);
796 switch ($this->bootmode){
797 case "D":
798 $this->gotoKernelParameters.= " debug";
799 break;
800 case "G":
801 $this->gotoKernelParameters.= " splash=silent";
802 break;
803 }
804 if ($this->customParameters != ""){
805 $this->gotoKernelParameters.= " o ".$this->customParameters;
806 }
808 plugin::save();
810 unset( $this->attrs['FAIrelease'] );
812 $str = "";
814 /* Skip FAI attribute handling if not necessary */
815 if($this->fai_activated){
816 if($this->FAIdebianMirror == "inherited"){
817 $this->attrs['FAIclass'] = $this->attrs['FAIrelease'] = $this->attrs['FAIdebianMirror'] = array();
818 }else{
819 foreach($this->FAIclass as $class){
820 $str .= $class." ";
821 }
822 $str .= ":" . $this->FAIrelease;
823 $this->attrs['FAIclass']= "";
824 $this->attrs['FAIclass']= trim($str);
826 if(empty($this->attrs['FAIclass'])){
827 $this->attrs['FAIclass'] = array();
828 }
829 }
830 }
832 /* Add missing arrays */
833 foreach (array("gotoFilesystem", "gotoAutoFs", "gotoModules") as $val){
834 if (isset ($this->$val) && count ($this->$val) != 0){
836 $this->attrs["$val"]= array_unique($this->$val);
837 }
838 if(!isset($this->attrs["$val"])) $this->attrs["$val"]=array();
839 }
841 /* Prepare list of ldap servers */
842 $this->attrs['gotoLdapServer'] = array();
843 if(!$this->gotoLdap_inherit){
844 $i = 0;
845 foreach($this->gotoLdapServers as $server){
846 $i ++;
847 $this->attrs['gotoLdapServer'][] = $i.":".$server;
848 }
849 }
851 /* Check if LDAP server has changed */
852 $ldap_changed= (isset($this->attrs['gotoLdapServer'])) &&
853 (isset($this->saved_attributes['gotoLdapServer'])) &&
854 ($this->attrs['gotoLdapServer'] != $this->saved_attributes['gotoLdapServer']);
856 if (($this->attrs['gotoBootKernel'] == "default-inherited") || ($this->attrs['gotoBootKernel'] == "%default%")){
857 $this->attrs['gotoBootKernel']= array();
858 }
860 /* if mirror == none stop saving this attribute */
861 if($this->FAIdebianMirror == "none"){
862 $this->FAIdebianMirror = "";
863 }
865 /* Get FAIstate from object, the generic tab could have changed it during execute */
866 $ldap= $this->config->get_ldap_link();
867 $ldap->cd($this->dn);
870 /* Skip FAI attribute handling if not necessary */
871 if($this->fai_activated){
872 $ldap->cat($this->dn,array("FAIstate"));
873 $checkFAIstate = $ldap->fetch();
875 /* Remove FAI objects if no FAI class is selected */
876 if((count($this->FAIclass)==0) && (!isset($checkFAIstate['FAIstate']))){
877 $this->attrs['FAIclass'] = array();
878 $this->attrs['FAIdebianMirror'] = array();
879 }
880 }
883 /* prepare share settings */
884 $tmp = array();
885 foreach($this->gotoShares as $name => $settings){
886 $tmp2= split("\|",$name);
887 $name = $tmp2[0];
888 $tmp[] = $settings['server']."|".$name."|".$settings['mountPoint'];
889 }
890 $this->attrs['gotoShare']=$tmp;
892 $this->cleanup();
893 $ldap->modify ($this->attrs);
894 new log("modify","workstation/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
896 show_ldap_error($ldap->get_error(), sprintf(_("Saving of system workstation/startup with dn '%s' failed."),$this->dn));
897 $this->handle_post_events("modify");
899 /* Check if LDAP server has changed */
900 if ($ldap_changed && class_available("DaemonEvent")){
901 $events = DaemonEvent::get_event_types(SYSTEM_EVENT | HIDDEN_EVENT);
902 $o_queue = new gosaSupportDaemon();
903 if(isset($events['TRIGGERED']['DaemonEvent_reload_ldap_config'])){
904 $evt = $events['TRIGGERED']['DaemonEvent_reload_ldap_config'];
905 $tmp = new $evt['CLASS_NAME']($this->config);
906 $tmp->set_type(TRIGGERED_EVENT);
907 $tmp->add_targets(array($this->parent->by_object['workgeneric']->netConfigDNS->macAddress));
908 if(!$o_queue->append($tmp)){
909 msg_dialog::display(_("Daemon"),sprintf(_("Something went wrong while talking to the daemon: %s."),
910 $o_queue->get_error()),ERROR_DIALOG);
911 }
912 }
913 }
914 }
917 /* Add value to array, check if unique */
918 function add_list (&$array, $value)
919 {
920 if ($value != ""){
921 $array[]= $value;
922 sort($array);
923 array_unique ($array);
924 }
925 }
928 /* Delete value to array, check if unique */
929 function del_list (&$array, $list)
930 {
931 $tmp= array();
932 foreach ($array as $mod){
933 if (!in_array($mod, $list)){
934 $tmp[]= $mod;
935 }
936 }
937 $array= $tmp;
938 }
940 /* Generate ListBox frindly output for the defined shares
941 * Possibly Add or remove an attribute here,
942 */
943 function printOutAssignedShares()
944 {
945 $a_return = array();
946 if(is_array($this->gotoShares)){
947 foreach($this->gotoShares as $share){
948 $a_return[$share['name']."|".$share['server']]= $share['name']." [".$share['server']."]";
949 }
950 }
951 return($a_return);
952 }
956 function PrepareForCopyPaste($source)
957 {
958 plugin::PrepareForCopyPaste($source);
959 $source_o = new workstartup ($this->config, $source['dn']);
960 foreach(array("FAIclass","gotoModules", "gotoAutoFs", "gotoFilesystem",
961 "gotoKernelParameters","gotoShares","customParameters") as $attr){
962 $this->$attr = $source_o->$attr;
963 }
964 }
967 function array_switch_item($ar,$from,$to)
968 {
969 if(!is_array($ar)){
970 return(false);
971 }
972 if(!isset($ar[$from])){
973 return(false);
974 }
975 if(!isset($ar[$to])){
976 return(false);
977 }
979 $tmp = $ar[$from];
980 $ar[$from] = $ar[$to];
981 $ar[$to] = $tmp;
982 return($ar);
983 }
986 /* Return plugin informations for acl handling */
987 static function plInfo()
988 {
989 return (array(
990 "plShortName" => _("Startup"),
991 "plDescription" => _("System startup"),
992 "plSelfModify" => FALSE,
993 "plDepends" => array(),
994 "plPriority" => 9,
995 "plSection" => array("administration"),
996 "plCategory" => array("workstation","server","ogroups"),
998 "plProvidedAcls"=> array(
999 "gotoLdapServer" => _("Ldap server"),
1000 "gotoBootKernel" => _("Boot kernel"),
1001 "gotoKernelParameters" => _("Kernel parameter"),
1003 "gotoModules" => _("Kernel modules"),
1004 "gotoShare" => _("Shares"),
1006 "FAIclass" => _("FAI classes"),
1007 "FAIdebianMirror" => _("Debian mirror"),
1008 "FAIrelease" => _("Debian release"),
1010 "FAIstatus" => _("FAI status flag")) // #FIXME is this acl realy necessary ?
1011 ));
1012 }
1015 /* Updates release dns
1016 * and reads all classes for the current release,
1017 * if not already done ($this->cache).
1018 */
1019 function update_fai_cache($first_call = FALSE)
1020 {
1021 $force = FALSE;
1023 /* Get the list of available servers and their releases.
1024 */
1025 if($force || !isset($this->cache['SERVERS'])){
1026 $ldap = $this->config->get_ldap_link();
1027 $ldap->cd($this->config->current['BASE']);
1029 $server_list = get_sub_list("(&(FAIrepository=*)(objectClass=FAIrepositoryServer))",
1030 "",get_ou("serverou"),$this->config->current['BASE'],array("FAIrepository"),GL_NO_ACL_CHECK);
1032 /* Only add inherit option, if we are part in an object group
1033 */
1034 if($this->member_of_ogroup){
1035 $this->cache['SERVERS']['inherited']=array();
1036 }
1038 /* Add auto value
1039 */
1040 $this->cache['SERVERS']['auto'] = array();
1041 $sort_by = array("auto");
1042 $server_tmp = array("auto"=>array());
1043 foreach($server_list as $attr){
1044 if(isset($attr['FAIrepository'])){
1045 for($i = 0 ; $i < $attr['FAIrepository']['count'] ; $i ++ ){
1046 $rep = $attr['FAIrepository'][$i];
1047 $tmp = split("\|",$rep);
1048 if(count($tmp)==4){
1049 $sections = split(",",$tmp[3]);
1050 $release = $tmp[2];
1051 $server = $tmp[1];
1052 $url = $tmp[0];
1053 $server_tmp[$url][$release]=$release;
1054 $server_tmp['auto'][$release]=$release;
1055 $sort_by[$url] = $url;
1056 }
1057 }
1058 }
1059 }
1060 natcasesort($sort_by);
1061 foreach($sort_by as $name){
1062 $releases = $server_tmp[$name];
1063 natcasesort($releases);
1064 $this->cache['SERVERS'][$name] = $releases;
1065 }
1066 }
1068 /* Build up arrays, without checks */
1069 if(!$first_call){
1071 /* Check if the selected mirror is available */
1072 if(!isset($this->cache['SERVERS'][$this->FAIdebianMirror])){
1073 $this->FAIdebianMirror = "auto";
1074 $this->FAIrelease = key($this->cache['SERVERS'][$this->FAIdebianMirror]);
1075 trigger_error("There was a problem with the selected FAIdebianMirror. This mirror ('".$this->FAIdebianMirror."') is not available");
1076 }
1078 /* Check if the selected release is available */
1079 if($this->FAIdebianMirror != "inherited" && !isset($this->cache['SERVERS'][$this->FAIdebianMirror][$this->FAIrelease])){
1080 trigger_error("There was a problem with the selected FAIrelease. This release ('".$this->FAIrelease."') is not available");
1081 $this->FAIrelease = key($this->cache['SERVERS'][$this->FAIdebianMirror]);
1082 }
1083 }
1085 /* Get classes for release from cache.
1086 * Or build cache
1087 */
1088 if($this->FAIdebianMirror == "inherited"){
1089 $release = $this->InheritedFAIrelease;
1090 }else{
1091 $release = $this->FAIrelease;
1092 }
1093 if($force || !isset($this->cache['CLASSES'][$release])){
1095 /* Create a list of available releases.
1096 * $this->cache['RELEASE_DNS'][ou=siga...,c=de] = "siga";
1097 * $this->cache['RELEASE_DNS'][ou=siga,ou=rc1,...,c=de] = "siga/rc1";
1098 */
1099 if($force || !isset($this->cache['RELEASE_DNS'])){
1100 $this->cache['RELEASE_DNS'] = array();
1101 $fai_ou_parts = preg_replace("/\/.*$/","",$this->FAIrelease);
1103 $tmp = get_sub_list("(objectClass=FAIbranch)","",get_ou("faiou"),
1104 $this->config->current['BASE'],array("ou"),GL_NO_ACL_CHECK | GL_SUBSEARCH);
1106 foreach($tmp as $attrs){
1107 if(preg_match("/".normalizePreg(get_ou("faiou"))."/",$attrs['dn'])){
1108 $this->cache['RELEASE_DNS'][$attrs['dn']] = $this->dn_to_release_name($attrs['dn']);
1109 }
1110 }
1111 }
1113 /* Create list of available classes for the currenlty selected release.
1114 */
1115 $base = array_search($release,$this->cache['RELEASE_DNS']);
1116 $this->cache['CLASSES'][$release] = array();
1118 if(class_exists("FAI")){
1119 if(!empty($base)){
1120 $filter = "(|(objectClass=FAIpackageList)(objectClass=FAItemplate)(objectClass=FAIvariable)".
1121 "(objectClass=FAIscript)(objectClass=FAIhook)(objectClass=FAIprofile)".
1122 "(objectClass=FAIpartitionTable))";
1123 $list = FAI::get_all_objects_for_given_base($base,$filter,TRUE);
1124 foreach($list as $attrs){
1125 $info = $this->analyse_fai_object($attrs);
1126 if(count($info)){
1127 $this->cache['CLASSES'][$release][$attrs['cn'][0]][] = $info;
1128 }
1129 }
1130 }
1131 }else{
1132 print_red(_("Could not load available classes, the fai extension plugin seems not to be installed."));
1133 }
1135 /* Add object caught from external hook
1136 */
1137 $lines= $this->GetHookElements();
1138 foreach ($lines as $hline){
1139 $entries= split(";", $hline);
1140 $server = $entries['0'];
1141 $url = $entries['1'];
1142 if (!empty($url)){
1144 /* Split releases */
1145 if (isset($entries[2])){
1146 $releases= split(",", $entries[2]);
1148 foreach ($releases as $release_data){
1149 $release= preg_replace('/:.*$/', '', $release_data);
1150 $sections = split(':', preg_replace('/^[^:]+:([^|]+)|.*$/', '\1', $release_data));
1151 $classes = split('\|', preg_replace('/^[^|]+\|(.*)$/', '\1', $release_data));
1152 $this->cache['SERVERS'][$url][$release]=$release;
1153 $this->cache['SERVERS']['auto'][$release]=$release;
1154 foreach ($classes as $class){
1155 if ($class != ""){
1156 $this->cache['CLASSES'][$release][$class]= array();
1157 }
1158 }
1159 }
1160 }
1161 }
1162 }
1163 }
1164 }
1167 /* This function return an array containing all
1168 * invalid classes for the selected server/release
1169 */
1170 function get_invalid_classes($classes)
1171 {
1172 $this->update_fai_cache();
1173 if($this->FAIdebianMirror == "inherited"){
1174 $release_classes = $this->cache['CLASSES'][$this->InheritedFAIrelease];
1175 }else{
1176 $release_classes = $this->cache['CLASSES'][$this->FAIrelease];
1177 }
1180 /* Detect all classes that are not valid
1181 * for the selected release
1182 */
1183 $NA = array();
1184 foreach($classes as $class){
1185 if(!isset($release_classes[$class])){
1186 $NA[] = $class;
1187 }
1188 }
1189 return($NA);
1190 }
1193 /* Get all selectable classes for the ui select box
1194 */
1195 function selectable_classes()
1196 {
1197 $this->update_fai_cache();
1199 if($this->FAIdebianMirror == "inherited"){
1200 $classes = $this->cache['CLASSES'][$this->InheritedFAIrelease];
1201 }else{
1202 $classes = $this->cache['CLASSES'][$this->FAIrelease];
1203 }
1205 $Abbr ="";
1206 $ret= array();
1207 foreach($classes as $class_name => $class_types){
1208 if(!in_array($class_name,$this->FAIclass)){
1209 foreach($class_types as $type){
1210 if(!preg_match("/".$type['Abbr']."/",$Abbr)){
1211 $Abbr .= $type['Abbr']." ";
1212 }
1213 }
1214 $ret[$class_name] = trim($Abbr);
1215 }
1216 }
1217 uksort($ret, 'strnatcasecmp');
1218 return($ret);
1219 }
1222 /* Analyse FAI object and return an array with usefull informations like
1223 * FAIobject type.
1224 */
1225 function analyse_fai_object($attr)
1226 {
1227 $tmp2 = array();
1228 if(!isset($attr['description'])){
1229 $attr['description'][0] ="";
1230 }
1231 if(in_array('FAIpackageList',$attr['objectClass'])){
1232 $tmp2["Type"] = 'FAIpackageList';
1233 $tmp2["Abbr"] = 'Pl';
1234 $tmp2["Desc"] = $attr['description'][0];
1235 }
1236 if(in_array('FAItemplate',$attr['objectClass'])){
1237 $tmp2["Type"] = 'FAItemplate';
1238 $tmp2["Abbr"] = 'T';
1239 $tmp2["Desc"] = $attr['description'][0];
1240 }
1241 if(in_array('FAIvariable',$attr['objectClass'])){
1242 $tmp2["Type"] = 'FAIvariable';
1243 $tmp2["Abbr"] = 'V';
1244 $tmp2["Desc"] = $attr['description'][0];
1245 }
1246 if(in_array('FAIscript',$attr['objectClass'])){
1247 $tmp2["Type"] = 'FAIscript';
1248 $tmp2["Abbr"] = 'S';
1249 $tmp2["Desc"] = $attr['description'][0];
1250 }
1251 if(in_array('FAIhook',$attr['objectClass'])){
1252 $tmp2["Type"] = 'FAIhook';
1253 $tmp2["Abbr"] = 'H';
1254 $tmp2["Desc"] = $attr['description'][0];
1255 }
1256 if(in_array('FAIpartitionTable',$attr['objectClass'])){
1257 $tmp2["Type"]= 'FAIpartitionTable';
1258 $tmp2["Abbr"]= 'Pt';
1259 $tmp2["Desc"] = $attr['description'][0];
1260 }
1261 if(in_array('FAIprofile',$attr['objectClass'])){
1262 $tmp2["Type"]= 'FAIprofile';
1263 $tmp2["Abbr"]= 'P';
1264 $tmp2["Desc"] = $attr['description'][0];
1265 }
1266 return($tmp2);
1267 }
1270 /* Return repository hook output, if possible.
1271 */
1272 function GetHookElements()
1273 {
1274 $ret = array();
1275 $cmd= $this->config->search("servrepository", "REPOSITORY_HOOK",array('tabs'));
1276 if(!empty($cmd)){
1277 $res = shell_exec($cmd);
1278 $res2 = trim($res);
1279 if((!$res)){
1280 print_red(sprintf(_("Can't execute specified REPOSITORY_HOOK '%s' please check your gosa.conf."),$cmd));
1281 }elseif(empty($res2)){
1282 print_red(sprintf(_("The specified REPOSITORY_HOOK '%s', specified in your gosa.conf, returns an empty string."),$cmd));
1283 }else{
1284 $tmp = split("\n",$res);
1285 foreach($tmp as $line){
1286 if(empty($line)) continue;
1287 $ret[]= $line;
1288 }
1289 }
1290 }
1291 return($ret);
1292 }
1295 /* This function creates the release name out of a dn
1296 * e.g. "ou=1.0rc2,ou=siga,ou=fai,..." => "siga/1.0rc2"
1297 */
1298 function dn_to_release_name($dn)
1299 {
1300 $relevant = preg_replace("/,".normalizePreg(get_ou("faiou")).".*$/","",$dn);
1301 $parts = array_reverse(split("\,",$relevant));
1302 $str ="";
1303 foreach($parts as $part){
1304 $str .= preg_replace("/^ou=/","",$part)."/";
1305 }
1306 return(preg_replace("/\/$/","",$str));
1307 }
1308 }
1310 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1311 ?>