Code

Updated translation
[gosa.git] / gosa-core / plugins / personal / posix / class_posixAccount.inc
1 <?php
2 /*!
3   \brief   posixAccount plugin
4   \author  Cajus Pollmeier <pollmeier@gonicus.de>
5   \version 2.00
6   \date    24.07.2003
8   This class provides the functionality to read and write all attributes
9   relevant for posixAccounts and shadowAccounts from/to the LDAP. It
10   does syntax checking and displays the formulars required.
11  */
13 class posixAccount extends plugin
14 {
15   /* Definitions */
16   var $plHeadline= "UNIX";
17   var $plDescription= "This does something";
19   /* CLI vars */
20   var $cli_summary= "Manage users posix account";
21   var $cli_description= "Some longer text\nfor help";
22   var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
24   /* Plugin specific values */
25   var $homeDirectory= "";
26   var $loginShell= "/bin/bash";
27   var $uidNumber= "";
28   var $gidNumber= "";
29   var $gecos= "";
30   var $shadowMin= "0";
31   var $shadowMax= "0";
32   var $shadowWarning= "0";
33   var $shadowLastChange= "0";
34   var $shadowInactive= "0";
35   var $shadowExpire= "0";
36   var $gosaDefaultPrinter= "";
37   var $accessTo= array();
38   var $trustModel= "";
40   var $glist=array();
41   var $status= "";
42   var $loginShellList= array();
43   var $groupMembership= array();
44   var $savedGroupMembership= array();
45   var $savedUidNumber= "";
46   var $savedGidNumber= "";
47   var $activate_shadowMin= "0";
48   var $activate_shadowMax= "0";
49   var $activate_shadowWarning= "0";
50   var $activate_shadowInactive= "0";
51   var $activate_shadowExpire= "0";
52   var $mustchangepassword= "0";
53   var $force_ids= 0;
54   var $group_dialog= FALSE;
55   var $show_ws_dialog= FALSE;
56   var $secondaryGroups= array();
57   var $primaryGroup= 0;
58   var $was_trust_account= FALSE;
59   var $memberGroup = array();
60   var $grouplist  = array();
61   var $ui         = array();
63   var $GroupRegex       = "*";
64   var $GroupUserRegex   = "*";
65   var $SubSearch        = false;
67   var $view_logged = FALSE;
69   /* attribute list for save action */
70   var $CopyPasteVars  = 
71       array("grouplist","groupMembership","activate_shadowMin",
72       "activate_shadowMax","activate_shadowWarning","activate_shadowInactive","activate_shadowExpire",
73       "must_change_password","printerList","grouplist","savedGidNumber","savedUidNumber");
75   var $attributes     = array("homeDirectory", "loginShell", "uidNumber", "gidNumber", "gecos",
76       "shadowMin", "shadowMax", "shadowWarning", "shadowInactive", "shadowLastChange",
77       "shadowExpire", "gosaDefaultPrinter", "uid","accessTo","trustModel");
79   var $objectclasses= array("posixAccount", "shadowAccount");
81   var $uid= "";
82   var $multiple_support = TRUE;
83   var $groupMembership_some = array();
85   /* constructor, if 'dn' is set, the node loads the given
86      'dn' from LDAP */
87   function posixAccount (&$config, $dn= NULL)
88   {
89     /* Configuration is fine, allways */
90     $this->config= $config;
92     /* Load bases attributes */
93     plugin::plugin($config, $dn);
95     /* Setting uid to default */
96     if(isset($this->attrs['uid'][0])){
97       $this->uid = $this->attrs['uid'][0];
98     }
100     $ldap= $this->config->get_ldap_link();
102     if ($dn !== NULL){
104       /* Correct is_account. shadowAccount is not required. */
105       if (isset($this->attrs['objectClass']) &&
106           in_array ('posixAccount', $this->attrs['objectClass'])){
108         $this->is_account= TRUE;
109       }
111       /* Is this account a trustAccount? */
112       if ($this->is_account && isset($this->attrs['trustModel'])){
113         $this->trustModel= $this->attrs['trustModel'][0];
114         $this->was_trust_account= TRUE;
115       } else {
116         $this->was_trust_account= FALSE;
117         $this->trustModel= "";
118       }
120       $this->accessTo = array(); 
121       if ($this->is_account && isset($this->attrs['accessTo'])){
122         for ($i= 0; $i<$this->attrs['accessTo']['count']; $i++){
123           $tmp= $this->attrs['accessTo'][$i];
124           $this->accessTo[$tmp]= $tmp;
125         }
126       }
127       $this->initially_was_account= $this->is_account;
129       /* Fill group */
130       $this->primaryGroup= $this->gidNumber;
132       /* Generate status text */
133       $current= date("U");
135       $current= floor($current / 60 /60 / 24);
137       if (($current >= $this->shadowExpire) && $this->shadowExpire){
138         $this->status= _("expired");
139         if (($current - $this->shadowExpire) < $this->shadowInactive){
140           $this->status.= ", "._("grace time active");
141         }
142       } elseif (($this->shadowLastChange + $this->shadowMin) >= $current){
143         $this->status= _("active, password not changable");
144       } elseif (($this->shadowLastChange + $this->shadowMax) >= $current){
145         $this->status= _("active, password expired");
146       } else {
147         $this->status= _("active");
148       }
150       /* Get group membership */
151       $ldap->cd($this->config->current['BASE']);
152       $ldap->search("(&(objectClass=posixGroup)(memberUid=".$this->uid."))", array("cn", "description"));
154       while ($attrs= $ldap->fetch()){
155         if (!isset($attrs["description"][0])){
156           $entry= $attrs["cn"][0];
157         } else {
158           $dsc= preg_replace ('/^Group of user/', _("Group of user"), $attrs["description"][0]);
159           $entry= $attrs["cn"][0]." [$dsc]";
160         }
161         $this->groupMembership[$ldap->getDN()]= $entry;
162       }
163       asort($this->groupMembership);
164       reset($this->groupMembership);
165       $this->savedGroupMembership= $this->groupMembership;
166       $this->savedUidNumber= $this->uidNumber;
167       $this->savedGidNumber= $this->gidNumber;
168     }
170     /* Adjust shadow checkboxes */
171     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
172           "shadowExpire") as $val){
174       if ($this->$val != 0){
175         $oval= "activate_".$val;
176         $this->$oval= "1";
177       }
178     }
180     /* Convert to seconds */
181     $this->shadowExpire= $this->convertToSeconds($this->shadowExpire);
183     /* Generate shell list from CONFIG_DIR./shells */
184     if (file_exists(CONFIG_DIR.'/shells')){
185       $shells = file (CONFIG_DIR.'/shells');
186       foreach ($shells as $line){
187         if (!preg_match ("/^#/", $line)){
188           $this->loginShellList[]= trim($line);
189         }
190       }
191     } else {
192       if ($this->loginShell == ""){
193         $this->loginShellList[]= _("unconfigured");
194       }
195     }
197     /* Insert possibly missing loginShell */
198     if ($this->loginShell != "" && !in_array($this->loginShell, $this->loginShellList)){
199       $this->loginShellList[]= $this->loginShell;
200     }
202     /* Generate group list */
203     $this->ui = get_userinfo(); 
204     $this->secondaryGroups[]= "- "._("automatic")." -";
205     $ldap->cd($this->config->current['BASE']);
206     $ldap->search("(objectClass=posixGroup)", array("cn", "gidNumber"));
207     while($attrs = $ldap->fetch()){
208       $this->secondaryGroups[$attrs['gidNumber'][0]]= $attrs['cn'][0];
209     }
210     asort ($this->secondaryGroups);
212     /* Get global filter config */
213     if (!session::is_set("sysfilter")){
214       $ui= get_userinfo();
215       $base= get_base_from_people($ui->dn);
216       $sysfilter= array( "depselect"       => $base,
217           "regex"           => "*");
218       session::set("sysfilter", $sysfilter);
219     }
220     $this->ui = get_userinfo();
221   }
224   /* execute generates the html output for this node */
225   function execute($isCopyPaste = false)
226   {
227     /* Call parent execute */
228     plugin::execute();
229     $display= "";
231     /* Log view */
232     if($this->is_account && !$this->view_logged){
233       $this->view_logged = TRUE;
234       new log("view","users/".get_class($this),$this->dn);
235     }
237     /* Department has changed? */
238     if(isset($_POST['depselect'])){
239       session::set('CurrentMainBase',validate($_POST['depselect']));
240     }
242     if($this->multiple_support_active){
243       $this->is_account = TRUE;
244     }
246     if(!$isCopyPaste && ! $this->multiple_support_active){
248       /* Do we need to flip is_account state? */
249       if(isset($_POST['modify_state'])){
250         if($this->is_account && $this->acl_is_removeable()){
251           $this->is_account= FALSE;
252         }elseif(!$this->is_account && $this->acl_is_createable()){
253           $this->is_account= TRUE;
254         }
255       }
257       /* Do we represent a valid posixAccount? */
258       if (!$this->is_account && $this->parent === NULL ){
259         $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\">&nbsp;<b>".
260           _("This account has no unix extensions.")."</b>";
261         $display.= back_to_main();
262         return ($display);
263       }
266       /* Show tab dialog headers */
267       if ($this->parent !== NULL){
268         if ($this->is_account){
269           if (isset($this->parent->by_object['sambaAccount'])){
270             $obj= $this->parent->by_object['sambaAccount'];
271           }
272           if (isset($obj) && $obj->is_account == TRUE &&
273               ((isset($this->parent->by_object['sambaAccount']))&&($this->parent->by_object['sambaAccount']->is_account))
274               ||(isset($this->parent->by_object['environment'] ))&&($this->parent->by_object['environment'] ->is_account)){
276             /* Samba3 dependency on posix accounts are enabled
277                in the moment, because I need to rely on unique
278                uidNumbers. There'll be a better solution later
279                on. */
280             $display= $this->show_disable_header(_("Remove posix account"),
281                 _("This account has unix features enabled. To disable them, you'll need to remove the samba / environment account first."), TRUE);
282           } else {
283             $display= $this->show_disable_header(_("Remove posix account"),
284                 _("This account has posix features enabled. You can disable them by clicking below."));
285           }
286         } else {
287           $display= $this->show_enable_header(_("Create posix account"),
288               _("This account has posix features disabled. You can enable them by clicking below."));
289           return($display);
290         }
291       }
292     }
293     /* Trigger group edit? */
294     if (isset($_POST['edit_groupmembership'])){
295       $this->group_dialog= TRUE;
296       $this->dialog= TRUE;
297     }
299     /* Cancel group edit? */
300     if (isset($_POST['add_groups_cancel']) ||
301         isset($_POST['add_groups_finish'])){
302       $this->group_dialog= FALSE;
303       $this->dialog= FALSE;
304     }
306     /* Add selected groups */
307     if (isset($_POST['add_groups_finish']) && isset($_POST['groups']) &&
308         count($_POST['groups'])){
310       $this->addGroup ($_POST['groups']);
311     }
313     /* Delete selected groups */
314     if (isset($_POST['delete_groupmembership']) && 
315         isset($_POST['group_list']) && count($_POST['group_list'])){
317       $this->delGroup ($_POST['group_list']);
318     }
320     /* Add user workstation? */
321     if (isset($_POST["add_ws"])){
322       $this->show_ws_dialog= TRUE;
323       $this->dialog= TRUE;
324     }
326     /* Add user workstation? */
327     if (isset($_POST["add_ws_finish"]) && isset($_POST['wslist'])){
328       foreach($_POST['wslist'] as $ws){
329         $this->accessTo[$ws]= $ws;
330       }
331       ksort($this->accessTo);
332       $this->is_modified= TRUE;
333     }
335     /* Remove user workstations? */
336     if (isset($_POST["delete_ws"]) && isset($_POST['workstation_list'])){
337       foreach($_POST['workstation_list'] as $name){
338         unset ($this->accessTo[$name]);
339       }
340       $this->is_modified= TRUE;
341     }
343     /* Add user workstation finished? */
344     if (isset($_POST["add_ws_finish"]) || isset($_POST["add_ws_cancel"])){
345       $this->show_ws_dialog= FALSE;
346       $this->dialog= FALSE;
347     }
349     /* Templates now! */
350     $smarty= get_smarty();
352     /* Show ws dialog */
353     if ($this->show_ws_dialog){
354       /* Save data */
355       $sysfilter= session::get("sysfilter");
356       foreach( array("depselect", "regex") as $type){
357         if (isset($_POST[$type])){
358           $sysfilter[$type]= $_POST[$type];
359         }
360       }
361       if (isset($_GET['search'])){
362         $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
363         if ($s == "**"){
364           $s= "*";
365         }
366         $sysfilter['regex']= $s;
367       }
368       session::set("sysfilter", $sysfilter);
370       /* Get workstation list */
371       $exclude= "";
372       foreach($this->accessTo as $ws){
373         $exclude.= "(cn=$ws)";
374       }
375       if ($exclude != ""){
376         $exclude= "(!(|$exclude))";
377       }
378       $regex= $sysfilter['regex'];
379       $filter= "(&(|(objectClass=goServer)(objectClass=gotoWorkstation)(objectClass=gotoTerminal))$exclude(cn=*)(cn=$regex))";
380       $res= get_list($filter, "groups", $sysfilter['depselect'], array("cn"), GL_SUBSEARCH | GL_SIZELIMIT);
381       $wslist= array();
382       foreach ($res as $attrs){
383         $wslist[]= preg_replace('/\$/', '', $attrs['cn'][0]);
384       }
385       asort($wslist);
386       $smarty->assign("search_image", get_template_path('images/search.png'));
387       $smarty->assign("launchimage", get_template_path('images/small_filter.png'));
388       $smarty->assign("tree_image", get_template_path('images/tree.png'));
389       $smarty->assign("deplist", $this->config->idepartments);
390       $smarty->assign("alphabet", generate_alphabet());
391       foreach( array("depselect", "regex") as $type){
392         $smarty->assign("$type", $sysfilter[$type]);
393       }
394       $smarty->assign("hint", print_sizelimit_warning());
395       $smarty->assign("wslist", $wslist);
396       $smarty->assign("apply", apply_filter());
397       $display= $smarty->fetch (get_template_path('trust_machines.tpl', TRUE, dirname(__FILE__)));
398       return ($display);
399     }
401     /* Manage group add dialog */
402     if ($this->group_dialog){
404       /* Get global filter config */
405       $this->reload();
407       /* remove already assigned groups */
408       $glist= array();
409       foreach ($this->grouplist as $key => $value){
410         if (!isset($this->groupMembership[$key]) && obj_is_writable($key,"groups/group","memberUid")){
411           $glist[$key]= $value;
412         }
413       }
415       if($this->SubSearch){
416         $smarty->assign("SubSearchCHK"," checked ");
417       }else{
418         $smarty->assign("SubSearchCHK","");
419       }
421       $smarty->assign("regex",$this->GroupRegex);
422       $smarty->assign("guser",$this->GroupUserRegex);
423       $smarty->assign("groups", $glist);
424       $smarty->assign("search_image", get_template_path('images/search.png'));
425       $smarty->assign("launchimage", get_template_path('images/small_filter.png'));
426       $smarty->assign("tree_image", get_template_path('images/tree.png'));
427       $smarty->assign("deplist", $this->config->idepartments);
428       $smarty->assign("alphabet", generate_alphabet());
429       $smarty->assign("depselect", session::get('CurrentMainBase'));
430       $smarty->assign("hint", print_sizelimit_warning());
432       $smarty->assign("apply", apply_filter());
433       $display.= $smarty->fetch (get_template_path('posix_groups.tpl', TRUE, dirname(__FILE__)));
434       return ($display);
435     }
437     /* Show main page */
438     $smarty= get_smarty();
440     /* In 'MyAccount' mode, we must remove write acls if we are not in editing mode. */ 
441     $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
443     /* Depending on pwmode, currently hardcoded because there are no other methods */
444     if ( 1 == 1 ){
445       $smarty->assign("pwmode", dirname(__FILE__)."/posix_shadow");
447       $shadowMinACL     =  $this->getacl("shadowMin",$SkipWrite);
448       $smarty->assign("shadowmins", sprintf(_("Password can't be changed up to %s days after last change"), 
449                                               "<input name=\"shadowMin\" size=3 maxlength=4 value=\"".$this->shadowMin."\">"));
451       $shadowMaxACL     =  $this->getacl("shadowMax",$SkipWrite);
452       $smarty->assign("shadowmaxs", sprintf(_("Password must be changed after %s days"), 
453                                               "<input name=\"shadowMax\" size=3 maxlength=4 value=\"".$this->shadowMax."\">"));
455       $shadowInactiveACL=  $this->getacl("shadowInactive",$SkipWrite);
456       $smarty->assign("shadowinactives", sprintf(_("Disable account after %s days of inactivity after password expiery"), 
457                                               "<input name=\"shadowInactive\" size=3 maxlength=4 value=\"".$this->shadowInactive."\">"));
459       $shadowWarningACL =  $this->getacl("shadowWarning",$SkipWrite);
460       $smarty->assign("shadowwarnings", sprintf(_("Warn user %s days before password expiery"), 
461                                               "<input name=\"shadowWarning\" size=3 maxlength=4 value=\"".$this->shadowWarning."\">"));
463       foreach( array("activate_shadowMin", "activate_shadowMax",
464                      "activate_shadowExpire", "activate_shadowInactive","activate_shadowWarning") as $val){
465         if ($this->$val == 1){
466           $smarty->assign("$val", "checked");
467         } else {
468           $smarty->assign("$val", "");
469         }
470         $smarty->assign("$val"."ACL", $this->getacl($val,$SkipWrite));
471       }
473       $smarty->assign("mustchangepasswordACL", $this->getacl("mustchangepassword",$SkipWrite));
474     }
476     /* Fill calendar */
477     /* If this $this->shadowExpire is empty 
478         use current date as base for calculating selectbox values.
479        (This attribute is empty if this is a new user )*/ 
480     if(empty($this->shadowExpire)){
481       $date= getdate(time());
482     }else{
483       $date= getdate($this->shadowExpire);
484     }
485  
486     $days= array();
487     for($d= 1; $d<32; $d++){
488       $days[$d]= $d;
489     }
490     $years= array();
491     for($y= $date['year']-10; $y<$date['year']+10; $y++){
492       $years[]= $y;
493     }
494     $months= array(_("January"), _("February"), _("March"), _("April"),
495         _("May"), _("June"), _("July"), _("August"), _("September"),
496         _("October"), _("November"), _("December"));
497     $smarty->assign("day", $date["mday"]);
498     $smarty->assign("days", $days);
499     $smarty->assign("months", $months);
500     $smarty->assign("month", $date["mon"]-1);
501     $smarty->assign("years", $years);
502     $smarty->assign("year", $date["year"]);
504     /* Fill arrays */
505     $smarty->assign("shells", $this->loginShellList);
506     $smarty->assign("secondaryGroups", $this->secondaryGroups);
507     $smarty->assign("primaryGroup", $this->primaryGroup);
508     if(!$this->multiple_support_active){
509       if (!count($this->groupMembership)){
510         $smarty->assign("groupMembership", array("&nbsp;"));
511       } else {
512         $smarty->assign("groupMembership", $this->groupMembership);
513       }
514     }else{
515       $smarty->assign("groupMembership", $this->groupMembership);
516       $smarty->assign("groupMembership_some", $this->groupMembership_some);
517     }
518     if (count($this->groupMembership) > 16){
519       $smarty->assign("groups", "too_many_for_nfs");
520     } else {
521       $smarty->assign("groups", "");
522     }
524     /* Avoid "Undefined index: forceMode" */
525     $smarty->assign("forceMode", "");
527     /* Checkboxes */
528     if ($this->force_ids == 1){
529       $smarty->assign("force_ids", "checked");
530       if (session::get('js')){
531         $smarty->assign("forceMode", "");
532       }
533     } else {
534       if (session::get('js')){
535         $smarty->assign("forceMode", "disabled");
536       }
537       $smarty->assign("force_ids", "");
538     }
539     
541     $smarty->assign("force_idsACL", $this->getacl("uidNumber",$SkipWrite).$this->getacl("gidNumber",$SkipWrite));
543     foreach(array("primaryGroup","trustmode","activate_shadowWarning","activate_shadowInactive","activate_shadowMin","activate_shadowMax","activate_shadowExpire","mustchangepassword") as $val){
544       if(in_array($val,$this->multi_boxes)){
545         $smarty->assign("use_".$val,TRUE);
546       }else{
547         $smarty->assign("use_".$val,FALSE);
548       }
549     }
552     /* Load attributes and acl's */
553     foreach($this->attributes as $val){
554       if(in_array($val,$this->multi_boxes)){
555         $smarty->assign("use_".$val,TRUE);
556       }else{
557         $smarty->assign("use_".$val,FALSE);
558       }
560       if((session::get("js"))&&(($val=="uidNumber")||($val=="gidNumber")))
561       {
562         $smarty->assign("$val"."ACL",$this->getacl($val,$SkipWrite));
563         $smarty->assign("$val", $this->$val);
564         continue;
565       }
566       $smarty->assign("$val", $this->$val);
567       $smarty->assign("$val"."ACL", $this->getacl($val,$SkipWrite));
568     }
569     if($SkipWrite){
570       $smarty->assign("groupMembershipACL","r");
571     }else{
572       $smarty->assign("groupMembershipACL","rw");
573     }
574     $smarty->assign("status", $this->status);
576     /* Work on trust modes */
577     $smarty->assign("trusthide", " disabled ");
578     $smarty->assign("trustmodeACL",  $this->getacl("trustModel",$SkipWrite));
579     if ($this->trustModel == "fullaccess"){
580       $trustmode= 1;
581       // pervent double disable tag in html code, this will disturb our clean w3c html
582       $smarty->assign("trustmode",  $this->getacl("trustModel",$SkipWrite));
584     } elseif ($this->trustModel == "byhost"){
585       $trustmode= 2;
586       $smarty->assign("trusthide", "");
587     } else {
588       // pervent double disable tag in html code, this will disturb our clean w3c html
589       $smarty->assign("trustmode",  $this->getacl("trustModel",$SkipWrite));
590       $trustmode= 0;
591     }
592     $smarty->assign("trustmode", $trustmode);
593     $smarty->assign("trustmodes", array( 0 => _("disabled"), 1 => _("full access"),
594           2 => _("allow access to these hosts")));
598     if((count($this->accessTo))==0)
599       $smarty->assign("emptyArrAccess",true);
600     else
601       $smarty->assign("emptyArrAccess",false);
603       if($this->mustchangepassword){
604         $smarty->assign("mustchangepassword", " checked ");
605       } else {
606         $smarty->assign("mustchangepassword", "");
607       }
609     $smarty->assign("workstations", $this->accessTo);
611     $smarty->assign("apply", apply_filter());
612     $smarty->assign("multiple_support" , $this->multiple_support_active);
613     $display.= $smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
614     return($display);
615   }
618   /* remove object from parent */
619   function remove_from_parent()
620   {
621     /* Cancel if there's nothing to do here */
622     if ((!$this->initially_was_account) || (!$this->acl_is_removeable())){
623       return;
624     }
626     /* include global link_info */
627     $ldap= $this->config->get_ldap_link();
629     /* Remove and write to LDAP */
630     plugin::remove_from_parent();
632     /* Zero out array */
633     $this->attrs['gosaHostACL']= array();
635     /* Keep uid, because we need it for authentification! */
636     unset($this->attrs['uid']);
637     unset($this->attrs['trustModel']);
639     @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,
640         $this->attributes, "Save");
641     $ldap->cd($this->dn);
642     $this->cleanup();
643     $ldap->modify ($this->attrs); 
645     new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
647     show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/posix account with dn '%s' failed."),$this->dn));
649     /* Delete group only if cn is uid and there are no other
650        members inside */
651     $ldap->cd ($this->config->current['BASE']);
652     $ldap->search ("(&(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))", array("cn", "memberUid"));
653     if ($ldap->count() != 0){
654       $attrs= $ldap->fetch();
655       if ($attrs['cn'][0] == $this->uid &&
656           !isset($this->attrs['memberUid'])){
658         $ldap->rmDir($ldap->getDN());
659       }
660     }
662     /* Optionally execute a command after we're done */
663     $this->handle_post_events("remove",array("uid" => $this->uid));
664   }
667   function save_object()
668   {
669     if (isset($_POST['posixTab'])){
670       /* Save values to object */
671       plugin::save_object();
674       /* Save force GID checkbox */
675       if($this->acl_is_writeable("gidNumber") || $this->acl_is_writeable("uidNumber")){
676         if (isset ($_POST['force_ids'])){
677           $data= 1;
678         } else {
679           $data= 0;
680         }
681         if ($this->force_ids != $data){
682           $this->is_modified= TRUE;
683         }
684         $this->force_ids= $data;
685       }
687       /*Save primary group settings */
688       if($this->acl_is_writeable("primaryGroup") && isset($_POST['primaryGroup'])){
689         $data= $_POST['primaryGroup'];
690         if ($this->primaryGroup != $data){
691           $this->is_modified= TRUE;
692         }
693         $this->primaryGroup= $_POST['primaryGroup'];
694       }
696       /* Get seelcted shadow checkboxes */
697       foreach(array("shadowMin","shadowMax","shadowExpire","shadowInactive","shadowWarning") as $var) {
698         if($this->acl_is_writeable($var)){
699           $activate_var = "activate_".$var;
700           if(isset($_POST['activate_'.$var])){
701             $this->$activate_var  = true;
702             $this->$var      = $_POST[$var];
703           }else{
704             $this->$activate_var  = false;
705             $this->$var      = 0;
706           }
707         }
708       }
710       /* Force change password ? */
711       if(isset($_POST['mustchangepassword'])){
712         $this->mustchangepassword = TRUE;
713       }else{
714         $this->mustchangepassword = FALSE;
715       }
717       /* Trust mode - special handling */
718       if($this->acl_is_writeable("trustModel")){
719         if (isset($_POST['trustmode'])){
720           $saved= $this->trustModel;
721           if ($_POST['trustmode'] == "1"){
722             $this->trustModel= "fullaccess";
723           } elseif ($_POST['trustmode'] == "2"){
724             $this->trustModel= "byhost";
725           } else {
726             $this->trustModel= "";
727           }
728           if ($this->trustModel != $saved){
729             $this->is_modified= TRUE;
730           }
731         }
732       }
733     }
735     /* Get regex from alphabet */
736     if(isset($_GET['search'])){
737       $this->GroupRegex = $_GET['search']."*";
738     }
740     /* Check checkboxes and regexes */
741     if(isset($_POST["PosixGroupDialogPosted"])){
743       if(isset($_POST['SubSearch']) && ($_POST['SubSearch'])){
744         $this->SubSearch = true;
745       }else{
746         $this->SubSearch = false;
747       }
748       if(isset($_POST['guser'])){
749         $this->GroupUserRegex = $_POST['guser'];
750       }
751       if(isset($_POST['regex'])){
752         $this->GroupRegex = $_POST['regex'];
753       }
754     }
755     $this->GroupRegex = preg_replace("/\*\**/","*",$this->GroupRegex);
756     $this->GroupUserRegex = preg_replace("/\*\**/","*",$this->GroupUserRegex);
757   }
760   /* Save data to LDAP, depending on is_account we save or delete */
761   function save()
762   {
764     /* include global link_info */
765     $ldap= $this->config->get_ldap_link();
767     /* Adapt shadow values */
768     if (!$this->activate_shadowExpire){
769       $this->shadowExpire= "0";
770     } else {
771       /* Transform seconds to days here */
772       $this->shadowExpire= (int)($this->shadowExpire / (60 * 60 * 24)) ;
773     }
774     if (!$this->activate_shadowMax){
775       $this->shadowMax= "0";
776     }
777     if ($this->mustchangepassword){
778       $this->shadowLastChange= (int)(date("U") / 86400) - $this->shadowMax - 1;
779     } else {
780       $this->shadowLastChange= (int)(date("U") / 86400);
781     }
782     if (!$this->activate_shadowWarning){
783       $this->shadowWarning= "0";
784     }
786     /* Check what to do with ID's */
787     if ($this->force_ids == 0){
789       /* Use id's that are already set */
790       if ($this->savedUidNumber != ""){
791         $this->uidNumber= $this->savedUidNumber;
792         $this->gidNumber= $this->savedGidNumber;
793       } else {
795         /* Calculate new id's. We need to place a lock before calling get_next_id
796            to get real unique values. */
797         $wait= 10;
798         while (get_lock("uidnumber") != ""){
799           sleep (1);
801           /* Oups - timed out */
802           if ($wait-- == 0){
803             msg_dialog::display(_("Warning"), _("Timeout while waiting for lock! Ignoring lock."), WARNING_DIALOG);
804             break;
805           }
806         }
808         add_lock ("uidnumber", "gosa");
809         $this->uidNumber= $this->get_next_id("uidNumber", $this->dn);
810         if ($this->savedGidNumber != ""){
811           $this->gidNumber= $this->savedGidNumber;
812         } else {
813           $this->gidNumber= $this->get_next_id("gidNumber", $this->dn);
814         }
815       }
817       if ($this->primaryGroup != 0){
818         $this->gidNumber= $this->primaryGroup;
819       }
820     }
822     if ($this->activate_shadowMin != "1" ) {
823       $this->shadowMin = "";
824     }
826     if (($this->activate_shadowMax != "1") && ($this->mustchangepassword != "1")) {
827       $this->shadowMax = "";
828     }
830     if ($this->activate_shadowWarning != "1" ) {
831       $this->shadowWarning = "";
832     }
834     if ($this->activate_shadowInactive != "1" ) {
835       $this->shadowInactive = "";
836     }
838     if ($this->activate_shadowExpire != "1" ) {
839       $this->shadowExpire = "";
840     }
842     /* Fill gecos */
843     if (isset($this->parent) && $this->parent !== NULL){
844       $this->gecos= rewrite($this->parent->by_object['user']->cn);
845       if (!preg_match('/^[a-z0-9 -]+$/i', $this->gecos)){
846         $this->gecos= "";
847       }
848     }
850     foreach(array("shadowMin","shadowMax","shadowWarning","shadowInactive","shadowExpire") as $attr){
851       $this->$attr = (int) $this->$attr;
852     }
853     /* Call parents save to prepare $this->attrs */
854     plugin::save();
856     /* Trust accounts */
857     $objectclasses= array();
858     foreach ($this->attrs['objectClass'] as $key => $class){
859       if (preg_match('/trustAccount/i', $class)){
860         continue;
861       }
862       $objectclasses[]= $this->attrs['objectClass'][$key];
863     }
864     $this->attrs['objectClass']= $objectclasses;
865     if ($this->trustModel != ""){
866       $this->attrs['objectClass'][]= "trustAccount";
867       $this->attrs['trustModel']= $this->trustModel;
868       $this->attrs['accessTo']= array();
869       if ($this->trustModel == "byhost"){
870         foreach ($this->accessTo as $host){
871           $this->attrs['accessTo'][]= $host;
872         }
873       }
874     } else {
875       if ($this->was_trust_account){
876         $this->attrs['accessTo']= array();
877         $this->attrs['trustModel']= array();
878       }
879     }
881     if(empty($this->attrs['gosaDefaultPrinter'])){
882       $thid->attrs['gosaDefaultPrinter']=array();
883     }
886     /* Save data to LDAP */
887     $ldap->cd($this->dn);
888     $this->cleanup();
889     unset($this->attrs['uid']);
890     $ldap->modify ($this->attrs); 
892     /* Log last action */ 
893     if($this->initially_was_account){
894       new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
895     }else{
896       new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
897     }
899     show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/posix account with dn '%s' failed."),$this->dn));
901     /* Remove lock needed for unique id generation */
902     del_lock ("uidnumber");
904     /* Posix accounts have group interrelationship, 
905        take care about these here if this is a new user without forced gidNumber. */
906     if ($this->force_ids == 0 && $this->primaryGroup == 0 && !$this->initially_was_account){
907       $ldap->cd($this->config->current['BASE']);
908       $ldap->search("(&(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))", array("cn"));
910       /* Create group if it doesn't exist */
911       if ($ldap->count() == 0){
912         $groupdn= preg_replace ('/^'.$this->config->current['DNMODE'].'=[^,]+,'.get_people_ou().'/i', 'cn='.$this->uid.','.get_groups_ou(), $this->dn);
914         $g= new group($this->config, $groupdn);
915         $g->cn= $this->uid;
916         $g->force_gid= 1;
917         $g->gidNumber= $this->gidNumber;
918         $g->description= _("Group of user")." ".$this->givenName." ".$this->sn;
919         $g->save ();
920       }
921     }
923     /* Take care about groupMembership values: add to groups */
924     foreach ($this->groupMembership as $key => $value){
925       if (!isset($this->savedGroupMembership[$key])){
926         $g= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $key,"groups");
927         $g->set_acl_base($key);
928         $g->by_object['group']->addUser($this->uid);
929         $g->save();
930       }
931     }
933     /* Remove from groups not listed in groupMembership */
934     foreach ($this->savedGroupMembership as $key => $value){
935       if (!isset($this->groupMembership[$key])){
936         $g= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $key,"groups");
937         $g->set_acl_base($key);
938         $g->by_object['group']->removeUser ($this->uid);
939         $g->save();
940       }
941     }
943     /* Optionally execute a command after we're done */
944     if ($this->initially_was_account == $this->is_account){
945       if ($this->is_modified){
946         $this->handle_post_events("modify",array("uid" => $this->uid));
947       }
948     } else {
949       $this->handle_post_events("add" ,array("uid"=> $this->uid));
950     }
951   }
953   /* Check formular input */
954   function check()
955   {
956     /* Include global link_info */
957     $ldap= $this->config->get_ldap_link();
959     /* Append groups as memberGroup: to check hook 
960      */
961     $tmp_attributes  = $this->attributes;    
962     $this->attributes[] = "memberGroup";
963     $this->memberGroup = array();
964     foreach($this->groupMembership as $dn => $name){
965       $this->memberGroup[] = $name;
966     }
968     /* Call common method to give check the hook */
969     $message= plugin::check();
970     $this->attributes = $tmp_attributes;
972     /* must: homeDirectory */
973     if ($this->homeDirectory == ""){
974       $message[]= _("The required field 'Home directory' is not set.");
975     }
976     if (!tests::is_path($this->homeDirectory)){
977       $message[]= _("Please enter a valid path in 'Home directory' field.");
978     }
980     /* Check ID's if they are forced by user */
981     if ($this->force_ids == "1"){
983       /* Valid uid/gid? */
984       if (!tests::is_id($this->uidNumber)){
985         $message[]= _("Value specified as 'UID' is not valid.");
986       } else {
987         if ($this->uidNumber < $this->config->current['MINID']){
988           $message[]= _("Value specified as 'UID' is too small.");
989         }
990       }
991       if (!tests::is_id($this->gidNumber)){
992         $message[]= _("Value specified as 'GID' is not valid.");
993       } else {
994         if ($this->gidNumber < $this->config->current['MINID']){
995           $message[]= _("Value specified as 'GID' is too small.");
996         }
997       }
998     }
1000     /* Check shadow settings, well I like spaghetties... */
1001     if ($this->activate_shadowMin){
1002       if (!tests::is_id($this->shadowMin)){
1003         $message[]= _("Value specified as 'shadowMin' is not valid.");
1004       }
1005     }
1006     if ($this->activate_shadowMax){
1007       if (!tests::is_id($this->shadowMax)){
1008         $message[]= _("Value specified as 'shadowMax' is not valid.");
1009       }
1010     }
1011     if ($this->activate_shadowWarning){
1012       if (!tests::is_id($this->shadowWarning)){
1013         $message[]= _("Value specified as 'shadowWarning' is not valid.");
1014       }
1015       if (!$this->activate_shadowMax){
1016         $message[]= _("'shadowWarning' without 'shadowMax' makes no sense.");
1017       }
1018       if ($this->shadowWarning > $this->shadowMax){
1019         $message[]= _("Value specified as 'shadowWarning' should be smaller than 'shadowMax'.");
1020       }
1021       if ($this->activate_shadowMin && $this->shadowWarning < $this->shadowMin){
1022         $message[]= _("Value specified as 'shadowWarning' should be greater than 'shadowMin'.");
1023       }
1024     }
1025     if ($this->activate_shadowInactive){
1026       if (!tests::is_id($this->shadowInactive)){
1027         $message[]= _("Value specified as 'shadowInactive' is not valid.");
1028       }
1029       if (!$this->activate_shadowMax){
1030         $message[]= _("'shadowInactive' without 'shadowMax' makes no sense.");
1031       }
1032     }
1033     if ($this->activate_shadowMin && $this->activate_shadowMax){
1034       if ($this->shadowMin > $this->shadowMax){
1035         $message[]= _("Value specified as 'shadowMin' should be smaller than 'shadowMax'.");
1036       }
1037     }
1039     //  if(empty($this->gosaDefaultPrinter)){
1040     //    $message[]= _("You need to specify a valid default printer.");
1041     //  }
1043     return ($message);
1044   }
1047   function multiple_check()
1048   {
1049     $message = plugin::multiple_check();
1050     if ($this->homeDirectory == "" && in_array("homeDirectory",$this->multi_boxes)){
1051       $message[]= _("The required field 'Home directory' is not set.");
1052     }
1053     if (!tests::is_path($this->homeDirectory) && in_array("homeDirectory",$this->multi_boxes)){
1054       $message[]= _("Please enter a valid path in 'Home directory' field.");
1055     }
1057     /* Check shadow settings, well I like spaghetties... */
1058     if ($this->activate_shadowMin && in_array("activate_shadowMin",$this->multi_boxes)){
1059       if (!tests::is_id($this->shadowMin)){
1060         $message[]= _("Value specified as 'shadowMin' is not valid.");
1061       }
1062     }
1063     if ($this->activate_shadowMax && in_array("activate_shadowMax",$this->multi_boxes)){
1064       if (!tests::is_id($this->shadowMax)){
1065         $message[]= _("Value specified as 'shadowMax' is not valid.");
1066       }
1067     }
1068     if ($this->activate_shadowWarning && in_array("activate_shadowWarning",$this->multi_boxes)){
1069       if (!tests::is_id($this->shadowWarning)){
1070         $message[]= _("Value specified as 'shadowWarning' is not valid.");
1071       }
1072       if (!$this->activate_shadowMax && in_array("activate_shadowMax",$this->multi_boxes)){
1073         $message[]= _("'shadowWarning' without 'shadowMax' makes no sense.");
1074       }
1075       if ($this->shadowWarning > $this->shadowMax && in_array("activate_shadowWarning",$this->multi_boxes)){
1076         $message[]= _("Value specified as 'shadowWarning' should be smaller than 'shadowMax'.");
1077       }
1078       if ($this->activate_shadowMin && $this->shadowWarning < $this->shadowMin && in_array("activate_shadowMin",$this->multi_boxes)){
1079         $message[]= _("Value specified as 'shadowWarning' should be greater than 'shadowMin'.");
1080       }
1081     }
1082     if ($this->activate_shadowInactive && in_array("activate_shadowInactive",$this->multi_boxes)){
1083       if (!tests::is_id($this->shadowInactive)){
1084         $message[]= _("Value specified as 'shadowInactive' is not valid.");
1085       }
1086       if (!$this->activate_shadowMax && in_array("activate_shadowMax",$this->multi_boxes)){
1087         $message[]= _("'shadowInactive' without 'shadowMax' makes no sense.");
1088       }
1089     }
1090     if ($this->activate_shadowMin && $this->activate_shadowMax && in_array("activate_shadowMin",$this->multi_boxes)){
1091       if ($this->shadowMin > $this->shadowMax){
1092         $message[]= _("Value specified as 'shadowMin' should be smaller than 'shadowMax'.");
1093       }
1094     }
1096     return($message);
1097   }
1100   function addGroup ($groups)
1101   {
1102     /* include global link_info */
1103     $ldap= $this->config->get_ldap_link();
1105     /* Walk through groups and add the descriptive entry if not exists */
1106     foreach ($groups as $value){
1108       if (!array_key_exists($value, $this->groupMembership)){
1109         $ldap->cat($value, array('cn', 'description', 'dn'));
1110         $attrs= $ldap->fetch();
1111         error_reporting (0);
1112         if (!isset($attrs['description'][0])){
1113           $entry= $attrs["cn"][0];
1114         } else {
1115           $dsc= preg_replace ('/^Group of user/', _("Group of user"), $attrs["description"][0]);
1116           $entry= $attrs["cn"][0]." [$dsc]";
1117         }
1118         error_reporting (E_ALL | E_STRICT);
1120         if(obj_is_writable($attrs['dn'],"groups/group","memberUid")){
1121           $this->groupMembership[$attrs['dn']]= $entry;
1122           if($this->multiple_support_active && isset($this->groupMembership_some[$attrs['dn']])){
1123             unset($this->groupMembership_some[$attrs['dn']]);
1124           }
1125         }
1126       }
1127     }
1129     /* Sort groups */
1130     asort ($this->groupMembership);
1131     reset ($this->groupMembership);
1132   }
1135   /* Del posix user from some groups */
1136   function delGroup ($groups)
1137   {
1138     $dest= array();
1139     foreach($groups as $dn_to_del){
1140       if(isset($this->groupMembership[$dn_to_del]) && obj_is_writable($dn_to_del,"groups/group","memberUid")){
1141         unset($this->groupMembership[$dn_to_del]);
1142       }
1143       if($this->multiple_support_active){
1144         if(isset($this->groupMembership_some[$dn_to_del]) && obj_is_writable($dn_to_del,"groups/group","memberUid")){
1145           unset($this->groupMembership_some[$dn_to_del]);
1146         }
1147       }
1148     }
1149   }
1152   /* Adapt from template, using 'dn' */
1153   function adapt_from_template($dn)
1154   {
1155     /* Include global link_info */
1156     $ldap= $this->config->get_ldap_link();
1158     plugin::adapt_from_template($dn);
1159     $template= $this->attrs['uid'][0];
1161     /* Adapt group membership */
1162     $ldap->cd($this->config->current['BASE']);
1163     $ldap->search("(&(objectClass=posixGroup)(memberUid=".$this->attrs["uid"][0]."))", array("description", "cn"));
1165     while ($this->attrs= $ldap->fetch()){
1166       if (!isset($this->attrs["description"][0])){
1167         $entry= $this->attrs["cn"][0];
1168       } else {
1169         $entry= $this->attrs["cn"][0]." [".$this->attrs["description"][0]."]";
1170       }
1171       $this->groupMembership[$ldap->getDN()]= $entry;
1172     }
1174     /* Fix primary group settings */
1175     $ldap->cd($this->config->current['BASE']);
1176     $ldap->search("(&(objectClass=posixGroup)(cn=$template)(gidNumber=".$this->gidNumber."))", array("cn"));
1177     if ($ldap->count() != 1){
1178       $this->primaryGroup= $this->gidNumber;
1179     }
1181     $ldap->cd($this->config->current['BASE']);
1182     $ldap->search("(&(objectClass=gosaUserTemplate)(uid=".$template.")(accessTo=*))", array("cn","accessTo"));
1183     while($attr = $ldap->fetch()){
1184       $tmp = $attr['accessTo'];
1185       unset ($tmp['count']);
1186       $this->accessTo = $tmp;   
1187     }
1189     /* Adjust shadow checkboxes */
1190     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive") as $val){
1191       if ($this->$val != 0){
1192         $oval= "activate_".$val;
1193         $this->$oval= "1";
1194       }
1195     }
1197     /* FIXME: NEED review of this section */
1198     /* Need to check shadowExpire separately */
1200     /* 
1201      * If shadowExpire is not enabled in the template, it's a UNIX timestamp - so don't convert it to seconds.
1202      * The check is a hack - if difference between timestamp generated above and here is max 1 day.
1203      */
1204     if(abs($this->shadowExpire - time())>86400) {
1205       $this->shadowExpire= $this->convertToSeconds($this->shadowExpire);
1206     }
1207     
1208     /* Only enable checkbox, if shadowExpire is in the future */
1209     if($this->shadowExpire > time()) {
1210       $this->activate_shadowExpire= "1";
1211     }
1212   }
1214   function convertToSeconds($val)
1215   {
1216     if ($val != 0){
1217       $val*= 60 * 60 * 24;
1218     } else {
1219       $date= getdate();
1220       $val= floor($date[0] / (60*60*24)) * 60 * 60 * 24;
1221     }
1222     return($val);
1223   }
1226   function get_next_id($attrib, $dn)
1227   {
1228     $ids= array();
1229     $ldap= $this->config->get_ldap_link();
1231     $ldap->cd ($this->config->current['BASE']);
1232     if (preg_match('/gidNumber/i', $attrib)){
1233       $oc= "posixGroup";
1234     } else {
1235       $oc= "posixAccount";
1236     }
1237     $ldap->search ("(&(objectClass=$oc)($attrib=*))", array("$attrib"));
1239     /* Get list of ids */
1240     while ($attrs= $ldap->fetch()){
1241       $ids[]= (int)$attrs["$attrib"][0];
1242     }
1244     /* Add the nobody id */
1245     $ids[]= 65534;
1247     /* get the ranges */
1248     $tmp = array('0'=> 1000); 
1249     if (preg_match('/posixAccount/', $oc) && isset($this->config->current['UIDBASE'])) {
1250       $tmp= split('-',$this->config->current['UIDBASE']);
1251     } elseif(isset($this->config->current['GIDBASE'])){
1252       $tmp= split('-',$this->config->current['GIDBASE']);
1253     }
1255     /* Set hwm to max if not set - for backward compatibility */
1256     $lwm= $tmp[0];
1257     if (isset($tmp[1])){
1258       $hwm= $tmp[1];
1259     } else {
1260       $hwm= pow(2,32);
1261     }
1263     /* Find out next free id near to UID_BASE */
1264     if (!isset($this->config->current['BASE_HOOK'])){
1265       $base= $lwm;
1266     } else {
1267       /* Call base hook */
1268       $base= get_base_from_hook($dn, $attrib);
1269     }
1270     for ($id= $base; $id++; $id < pow(2,32)){
1271       if (!in_array($id, $ids)){
1272         return ($id);
1273       }
1274     }
1276     /* Should not happen */
1277     if ($id == $hwm){
1278       msg_dialog::display(_("Error"), _("Cannot allocate a free ID: too many users!"), ERROR_DIALOG);
1279       exit;
1280     }
1282   }
1284   function reload()
1285   {
1286     /* Set base for all searches */
1287     $base      = session::get('CurrentMainBase');
1288     $base     = $base;
1289     $ldap     = $this->config->get_ldap_link();    
1290     $attrs    =  array("cn", "description", "gidNumber");
1291     $Flags    = GL_SIZELIMIT;
1293     /* Get groups */
1294     if ($this->GroupUserRegex == '*'){
1295       $filter = "(&(objectClass=posixGroup)(cn=".$this->GroupRegex."))";
1296     } else {
1297       $filter= "(&(objectClass=posixGroup)(cn=".$this->GroupRegex.")(memberUid=".$this->GroupUserRegex."))";
1298     }
1299     if($this->SubSearch){
1300       $Flags |= GL_SUBSEARCH;
1301     }else{
1302       $base = get_groups_ou().$base;
1303     }
1305     $res= get_list($filter, "groups", $base,$attrs, $Flags);
1306   
1307     /* check sizelimit */
1308     if (preg_match("/size limit/i", $ldap->error)){
1309       session::set('limit_exceeded',TRUE);
1310     }
1312     /* Create a list of users */
1313     $this->grouplist = array();
1314     foreach ($res as $value){
1315       $this->grouplist[$value['gidNumber'][0]]= $value;
1316     }
1318     $tmp=array();
1319     foreach($this->grouplist as $tkey => $val ){
1320       $tmp[strtolower($val['cn'][0]).$val['cn'][0]]=$val;
1321     }
1323     /* Sort index */
1324     ksort($tmp);
1326     /* Recreate index array[dn]=cn[description]*/
1327     $this->grouplist=array();
1328     foreach($tmp as $val){
1329       if(isset($val['description'])){
1330         $this->grouplist[$val['dn']]=$val['cn'][0]."&nbsp;[".$val['description'][0]."]";
1331       }else{
1332         $this->grouplist[$val['dn']]=$val['cn'][0];
1333       }
1334     }
1336     reset ($this->grouplist);
1337   }
1340   /* Get posts from copy & paste dialog */ 
1341   function saveCopyDialog()
1342   {
1343     if(isset($_POST['homeDirectory'])){
1344       $this->homeDirectory = $_POST['homeDirectory'];
1345       if (isset ($_POST['force_ids'])){
1346         $data= 1;
1347         $this->gidNumber = $_POST['gidNumber'];
1348         $this->uidNumber = $_POST['uidNumber'];
1349       } else {
1350         $data= 0;
1351       }
1352       if ($this->force_ids != $data){
1353         $this->is_modified= TRUE;
1354       }
1355       $this->force_ids= $data;
1356     }
1357   }
1358  
1360   /* Create the posix dialog part for copy & paste */
1361   function getCopyDialog()
1362   {
1363     /* Skip dialog creation if this is not a valid account*/
1364     if(!$this->is_account) return("");
1365     if ($this->force_ids == 1){
1366       $force_ids = "checked";
1367       if (session::get('js')){
1368         $forceMode = "";
1369       }
1370     } else {
1371       if (session::get('js')){
1372         if($this->acl != "#none#")
1373           $forceMode ="disabled";
1374       }
1375       $force_ids = "";
1376     }
1378     $sta = "";
1380     /* Open group add dialog */
1381     if(isset($_POST['edit_groupmembership'])){
1382       $this->group_dialog = TRUE;
1383       $sta = "SubDialog";
1384     }
1386     /* If the group-add dialog is closed, call execute 
1387        to ensure that the membership is updatd */
1388     if(isset($_POST['add_groups_finish']) || isset($_POST['add_groups_cancel'])){
1389       $this->execute();
1390       $this->group_dialog =FALSE;
1391     }
1393     if($this->group_dialog){
1394       $str = $this->execute(true);
1395       $ret = array();
1396       $ret['string'] = $str;
1397       $ret['status'] = $sta;
1398       return($ret);
1399     }
1401     /* If a group member should be deleted, simply call execute */
1402     if(isset($_POST['delete_groupmembership'])){
1403       $this->execute();
1404     }
1406     /* Assigned informations to smarty */
1407     $smarty = get_smarty();
1408     $smarty->assign("homeDirectory",$this->homeDirectory);
1409     $smarty->assign("uidNumber",$this->uidNumber);
1410     $smarty->assign("gidNumber",$this->gidNumber);
1411     $smarty->assign("forceMode",$forceMode);
1412     $smarty->assign("force_ids",$force_ids);
1413     if (!count($this->groupMembership)){
1414       $smarty->assign("groupMembership", array("&nbsp;"));
1415     } else {
1416       $smarty->assign("groupMembership", $this->groupMembership);
1417     }
1419     /* Display wars message if there are more than 16 group members */
1420     if (count($this->groupMembership) > 16){
1421       $smarty->assign("groups", "too_many_for_nfs");
1422     } else {
1423       $smarty->assign("groups", "");
1424     }
1425     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE,dirname(__FILE__)));
1427     $ret = array();
1428     $ret['string'] = $str;
1429     $ret['status'] = $sta;
1430     return($ret);
1431   }
1434   function PrepareForCopyPaste($source)
1435   {
1436     plugin::PrepareForCopyPaste($source);
1438     /* Avoid using the same gid/uid number as source user */
1439     $this->savedUidNumber = $this->get_next_id("uidNumber", $this->dn);
1440     $this->savedGidNumber = $this->get_next_id("gidNumber", $this->dn);
1441   }
1444   function multiple_execute()
1445   {
1446     return($this->execute());
1447   }
1450   static function plInfo()
1451   {
1452     return (array(
1453           "plDescription"     => _("POSIX account"),
1454           "plSelfModify"      => TRUE,
1455           "plDepends"         => array("user"),
1456           "plPriority"        => 2,
1457           "plSection"         => array("personal" => _("My account")),
1458           "plCategory"        => array("users"),
1459           "plOptions"         => array(),
1461           "plProvidedAcls"  => array(
1463             "homeDirectory"       =>  _("Home directory"), 
1464             "loginShell"          =>  _("Shell"),
1465             "uidNumber"           =>  _("User ID"),
1466             "gidNumber"           =>  _("Group ID"),
1468             "mustchangepassword"=>  _("Force password change on login"),
1469             "shadowMin"           =>  _("Shadow min"),
1470             "shadowMax"           =>  _("Shadow max"),
1471             "shadowWarning"       =>  _("Shadow warning"),
1472             "shadowInactive"      =>  _("Shadow inactive"),
1473             "shadowExpire"        =>  _("Shadow expire"),
1474             "trustModel"          =>  _("System trust model")))
1475             );
1476   }
1479   /* Return selected values for multiple edit */
1480   function get_multi_edit_values()
1481   {
1482     $ret = plugin::get_multi_edit_values();
1483     $ret['groupMembership']     = $this->groupMembership;
1484     $ret['groupMembership_some']= $this->groupMembership_some;
1486     if(in_array("primaryGroup",$this->multi_boxes)){
1487       $ret['primaryGroup'] = $this->primaryGroup;
1488     }
1489     if(in_array("trustmode",$this->multi_boxes)){
1490       $ret['trustModel'] = $this->trustModel;
1491       $ret['accessTo'] = $this->accessTo;
1492     }
1493     foreach(array("shadowWarning","shadowInactive","shadowMin","shadowMax", "shadowExpire") as $entry){
1494       $active = "activate_".$entry;
1495       if(in_array($active,$this->multi_boxes)){
1496         $ret[$entry] = $this->$entry;
1497         $ret[$active] = $this->$active;
1498       }
1499     }
1500     if(in_array("mustchangepassword",$this->multi_boxes)){
1501       $ret['mustchangepassword'] = $this->mustchangepassword;
1502     }
1503     return($ret);
1504   }
1507   /* Save posts for multiple edit 
1508    */
1509   function multiple_save_object()
1510   {
1511     if(isset($_POST['posix_mulitple_edit'])){
1512  
1513       /* Backup expire value */ 
1514       $expire_tmp = $this->shadowExpire;
1515   
1516       /* Update all values */
1517       plugin::multiple_save_object();
1519       /* Get selected checkboxes */
1520       foreach(array("primaryGroup","trustmode","mustchangepassword","activate_shadowWarning","activate_shadowInactive","activate_shadowMin", "activate_shadowMax","activate_shadowExpire") as $val){
1521         if(isset($_POST["use_".$val])){
1522           $this->multi_boxes[] = $val;
1523         }
1524       }
1526       /* Update special values, checkboxes for posixShadow */
1527       foreach(array("shadowMin","shadowMax","shadowExpire","shadowInactive","shadowWarning") as $var) {
1528         if($this->acl_is_writeable($var)){
1529           $activate_var = "activate_".$var;
1530           if(in_array($activate_var, $this->multi_boxes)){
1531             if(isset($_POST['activate_'.$var])){
1532               $this->$activate_var  = true;
1533               $this->$var      = $_POST[$var];
1534             }else{
1535               $this->$activate_var  = false;
1536               $this->$var      = 0;
1537             }
1538           }
1539         }
1540       }
1542       /* Restore shadow value, if the shadow attribute isn't used */
1543       if(!in_array("activate_shadowExpire",$this->multi_boxes)){
1544         $this->shadowExpire = $expire_tmp;
1545       }
1547       /* Force change password ? */
1548       if(isset($_POST['mustchangepassword'])){
1549         $this->mustchangepassword = TRUE;
1550       }else{
1551         $this->mustchangepassword = FALSE;
1552       }
1554       /* Trust mode - special handling */
1555       if($this->acl_is_writeable("trustModel")){
1556         if (isset($_POST['trustmode'])){
1557           $saved= $this->trustModel;
1558           if ($_POST['trustmode'] == "1"){
1559             $this->trustModel= "fullaccess";
1560           } elseif ($_POST['trustmode'] == "2"){
1561             $this->trustModel= "byhost";
1562           } else {
1563             $this->trustModel= "";
1564           }
1565           if ($this->trustModel != $saved){
1566             $this->is_modified= TRUE;
1567           }
1568         }
1569       }
1571       /* Save primary group settings */
1572       if($this->acl_is_writeable("primaryGroup") && isset($_POST['primaryGroup'])){
1573         $data= $_POST['primaryGroup'];
1574         if ($this->primaryGroup != $data){
1575           $this->is_modified= TRUE;
1576         }
1577         $this->primaryGroup= $_POST['primaryGroup'];
1578       }
1579     }
1580   }
1582   
1583   /* Initialize plugin with given atribute arrays 
1584    */
1585   function init_multiple_support($attrs,$all)
1586   {
1587     plugin::init_multiple_support($attrs,$all);
1589     /* Some dummy values */
1590     $groups_some = array();
1591     $groups_all  = array();
1592     $groups_uid  = array();
1593     $uids        = array();
1594     $first       = TRUE;
1596     /* Get all groups used by currently edited users */
1597     $uid_filter="";  
1598     for($i =0; $i < $this->multi_attrs_all['uid']['count'] ; $i ++){
1599       $uid = $this->multi_attrs_all['uid'][$i];
1600       $uids[] = $uid;
1601       $uid_filter.= "(memberUid=".$uid.")"; 
1602     }
1603     $uid_filter = "(&(objectClass=posixGroup)(|".$uid_filter."))";
1604     $ldap = $this->config->get_ldap_link();
1605     $ldap->cd($this->config->current['BASE']);
1606     $ldap->search($uid_filter,array("dn","cn","memberUid"));
1607     while($group = $ldap->fetch()){
1608       $groups_some[$group['dn']] = $group['cn'][0];
1609       for($i = 0 ; $i < $group['memberUid']['count'] ; $i++){
1610         $groups_uid[$group['dn']][] = $group['memberUid'][$i];
1611       }
1612     }
1614     /* Create an array, containing all used groups */
1615     $groups_all = $groups_some;
1616     foreach($groups_all as $id => $group){
1617       foreach($uids as $uid){
1618         if(!in_array($uid,$groups_uid[$id])){
1619           unset($groups_all[$id]);
1620           break;
1621         }
1622       }
1623     }
1625     /* Assign group array */
1626     $this->groupMembership = $groups_all;
1628     /* Create an array of all grouops used by all users */
1629     foreach( $groups_all as $dn => $cn){
1630       if(isset($groups_some[$dn])){
1631         unset($groups_some[$dn]);
1632       }
1633     }
1634     $this->groupMembership_some = $groups_some;
1635     $this->primaryGroup = $this->gidNumber;
1637     /* Is this account a trustAccount? */
1638     if (isset($this->multi_attrs['trustModel'])){
1639       $this->trustModel= $this->multi_attrs['trustModel'][0];
1640       $this->was_trust_account= TRUE;
1641       $this->multi_boxes[] = "trustmode";
1642     } else {
1643       $this->was_trust_account= FALSE;
1644       $this->trustModel= "";
1645     }
1647     /* Create access informations */
1648     $this->accessTo = array();
1649     if (isset($this->multi_attrs['accessTo'])){
1650       for ($i= 0; $i<$this->multi_attrs['accessTo']['count']; $i++){
1651         $tmp= $this->multi_attrs['accessTo'][$i];
1652         $this->accessTo[$tmp]= $tmp;
1653       }
1654     }
1656     /* Adjust shadow checkboxes */
1657     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
1658           "shadowExpire") as $val){
1659       if ($this->$val != 0){
1660         $oval= "activate_".$val;
1661         $this->$oval= "1";
1662       }
1663     }
1665     /* Convert to seconds */
1666     if(isset($this->multi_attrs['shadowExpire'])){
1667       $this->shadowExpire = $this->convertToSeconds($this->multi_attrs['shadowExpire'][0]);
1668     }else{
1669       $this->activate_shadowExpire = FALSE;
1670     }
1671   }
1674   function set_multi_edit_values($attrs)
1675   {
1676     $groups = array();
1678     /* Update groupMembership, keep optinal group */
1679     foreach($attrs['groupMembership_some'] as $dn => $cn){
1680       if(isset($this->groupMembership[$dn])){
1681         $groups[$dn] = $cn;
1682       }
1683     }
1684     /* Update groupMembership, add forced groups */
1685     foreach($attrs['groupMembership'] as $dn => $cn){
1686       $groups[$dn] = $cn;
1687     }
1688     plugin::set_multi_edit_values($attrs);
1689     $this->groupMembership = $groups;
1690   }
1693 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1694 ?>