9e4adc8b53d128a9db020cf053304a2b16110eeb
1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 /*!
24 \brief posixAccount plugin
25 \author Cajus Pollmeier <pollmeier@gonicus.de>
26 \version 2.00
27 \date 24.07.2003
29 This class provides the functionality to read and write all attributes
30 relevant for posixAccounts and shadowAccounts from/to the LDAP. It
31 does syntax checking and displays the formulars required.
32 */
34 class posixAccount extends plugin
35 {
36 /* Definitions */
37 var $plHeadline= "POSIX";
38 var $plDescription= "Edit users POSIX settings";
40 /* Plugin specific values */
41 var $homeDirectory= "";
42 var $loginShell= "/bin/bash";
43 var $uidNumber= "";
44 var $gidNumber= "";
45 var $gecos= "";
46 var $shadowMin= "0";
47 var $shadowMax= "0";
48 var $shadowWarning= "0";
49 var $shadowLastChange= "0";
50 var $shadowInactive= "0";
51 var $shadowExpire= "";
52 var $accessTo= array();
54 var $glist=array();
55 var $status= "";
56 var $loginShellList= array();
57 var $groupMembership= array();
58 var $savedGroupMembership= array();
59 var $savedUidNumber= "";
60 var $savedGidNumber= "";
61 var $activate_shadowMin= "0";
62 var $activate_shadowMax= "0";
63 var $activate_shadowWarning= "0";
64 var $activate_shadowInactive= "0";
65 var $activate_shadowExpire= "0";
66 var $mustchangepassword= "0";
67 var $force_ids= 0;
68 var $gotoLastSystemLogin= "";
69 var $groupSelect= FALSE;
70 var $secondaryGroups= array();
71 var $primaryGroup= 0;
72 var $memberGroup= array();
73 var $grouplist= array();
74 var $ui= array();
75 var $ssh= null;
76 var $sshAcl= "";
78 var $view_logged= false;
80 /* attribute list for save action */
81 var $CopyPasteVars =
82 array("grouplist","groupMembership","activate_shadowMin",
83 "activate_shadowMax","activate_shadowWarning","activate_shadowInactive","activate_shadowExpire",
84 "must_change_password","printerList","grouplist","savedGidNumber","savedUidNumber");
86 var $attributes = array("homeDirectory", "loginShell", "uidNumber", "gidNumber", "gecos",
87 "shadowMin", "shadowMax", "shadowWarning", "shadowInactive", "shadowLastChange",
88 "shadowExpire", "uid", "gotoLastSystemLogin");
90 var $objectclasses= array("posixAccount", "shadowAccount");
92 var $uid= "";
93 var $multiple_support = TRUE;
94 var $groupMembership_some = array();
96 /* constructor, if 'dn' is set, the node loads the given
97 'dn' from LDAP */
98 function posixAccount (&$config, $dn= NULL, $parent =NULL)
99 {
100 global $class_mapping;
102 /* Configuration is fine, allways */
103 $this->config= $config;
105 /* Load bases attributes */
106 plugin::plugin($config, $dn, $parent);
108 $this->trustModeDialog = new trustModeDialog($this->config, $this->dn, $parent);
109 $this->trustModeDialog->setAcl('users/posixAccount');
111 /* If gotoLastSystemLogin is available read it from ldap and create a readable
112 date time string, fallback to sambaLogonTime if available.
113 */
114 if(isset($this->attrs['gotoLastSystemLogin'][0]) && preg_match("/^[0-9]*$/",$this->attrs['gotoLastSystemLogin'][0])){
115 $this->gotoLastSystemLogin = date("d.m.Y H:i:s", strtotime($this->attrs['gotoLastSystemLogin'][0]));
116 } else if(isset($this->attrs['sambaLogonTime'][0]) && preg_match("/^[0-9]*$/",$this->attrs['sambaLogonTime'][0])){
117 $this->gotoLastSystemLogin = date("d.m.Y H:i:s", $this->attrs['sambaLogonTime'][0]);
118 }
120 /* Setting uid to default */
121 if(isset($this->attrs['uid'][0])){
122 $this->uid = $this->attrs['uid'][0];
123 }
125 $ldap= $this->config->get_ldap_link();
127 if ($dn !== NULL){
129 /* Correct is_account. shadowAccount is not required. */
130 if (isset($this->attrs['objectClass']) &&
131 in_array ('posixAccount', $this->attrs['objectClass'])){
133 $this->is_account= TRUE;
134 }
135 $this->initially_was_account= $this->is_account;
137 /* Fill group */
138 $this->primaryGroup= $this->gidNumber;
140 /* Generate status text */
141 $current= date("U");
143 $current= floor($current / 60 /60 / 24);
145 if (($current >= $this->shadowExpire) && $this->shadowExpire){
146 $this->status= _("expired");
147 if (($current - $this->shadowExpire) < $this->shadowInactive){
148 $this->status.= ", "._("grace time active");
149 }
150 } elseif (($this->shadowLastChange + $this->shadowMin) >= $current){
151 $this->status= _("active").", "._("password not changeable");
152 } elseif (($this->shadowLastChange + $this->shadowMax) >= $current){
153 $this->status= _("active").", "._("password expired");
154 } else {
155 $this->status= _("active");
156 }
158 /* Get group membership */
159 $ldap->cd($this->config->current['BASE']);
160 $ldap->search("(&(objectClass=posixGroup)(memberUid=".$this->uid."))", array("cn", "description"));
162 while ($attrs= $ldap->fetch()){
163 if (!isset($attrs["description"][0])){
164 $entry= $attrs["cn"][0];
165 } else {
166 $entry= $attrs["cn"][0]." [".$attrs["description"][0]."]";
167 }
168 $this->groupMembership[$ldap->getDN()]= $entry;
169 }
170 asort($this->groupMembership);
171 reset($this->groupMembership);
172 $this->savedGroupMembership= $this->groupMembership;
173 $this->savedUidNumber= $this->uidNumber;
174 $this->savedGidNumber= $this->gidNumber;
176 // Instanciate SSH object if available
177 if (isset($class_mapping["sshPublicKey"])){
178 if (empty($this->acl_base)){
179 $this->acl_base= $config->current['BASE'];
180 }
182 $this->sshAcl= $this->getacl("sshPublicKey");
183 $this->ssh= new sshPublicKey($this->config, $this->dn, $this->sshAcl);
184 }
185 }
187 /* Adjust shadow checkboxes */
188 foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
189 "shadowExpire") as $val){
191 if ($this->$val != 0){
192 $oval= "activate_".$val;
193 $this->$oval= "1";
194 }
195 }
197 /* Convert shadowExpire for usage */
198 if ($this->shadowExpire == 0){
199 $this->shadowExpire= "";
200 } else {
201 $this->shadowExpire= date('d.m.Y', $this->shadowExpire * 60 * 60 * 24);
202 }
205 /* Generate shell list from CONFIG_DIR./shells */
206 if (file_exists(CONFIG_DIR.'/shells')){
207 $shells = file (CONFIG_DIR.'/shells');
208 foreach ($shells as $line){
209 if (!preg_match ("/^#/", $line)){
210 $this->loginShellList[]= trim($line);
211 }
212 }
213 } else {
214 if ($this->loginShell == ""){
215 $this->loginShellList[]= _("unconfigured");
216 }
217 }
219 /* Insert possibly missing loginShell */
220 if ($this->loginShell != "" && !in_array($this->loginShell, $this->loginShellList)){
221 $this->loginShellList[]= $this->loginShell;
222 }
224 /* Generate group list */
225 $this->ui = get_userinfo();
226 $this->secondaryGroups[]= "- "._("automatic")." -";
227 $ldap->cd($this->config->current['BASE']);
228 $ldap->search("(objectClass=posixGroup)", array("cn", "gidNumber"));
229 while($attrs = $ldap->fetch()){
230 $this->secondaryGroups[$attrs['gidNumber'][0]]= $attrs['cn'][0];
231 }
232 asort ($this->secondaryGroups);
234 $this->ui = get_userinfo();
235 }
238 /* execute generates the html output for this node */
239 function execute($isCopyPaste = false)
240 {
241 /* Call parent execute */
242 plugin::execute();
243 $display= "";
245 /* Log view */
246 if($this->is_account && !$this->view_logged){
247 $this->view_logged = TRUE;
248 new log("view","users/".get_class($this),$this->dn);
249 }
250 $this->dialog = FALSE;
252 if($this->multiple_support_active){
253 $this->is_account = TRUE;
254 }
256 if(!$isCopyPaste && ! $this->multiple_support_active){
258 /* Do we need to flip is_account state? */
259 if(isset($_POST['modify_state'])){
260 if($this->is_account && $this->acl_is_removeable()){
261 $this->is_account= FALSE;
262 }elseif(!$this->is_account && $this->acl_is_createable()){
263 $this->is_account= TRUE;
264 }
265 }
267 /* Do we represent a valid posixAccount? */
268 if (!$this->is_account && $this->parent === NULL ){
269 $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\"> <b>".
270 msgPool::noValidExtension(_("POSIX"))."</b>";
271 $display.= back_to_main();
272 return ($display);
273 }
276 /* Show tab dialog headers */
277 if ($this->parent !== NULL){
278 if ($this->is_account){
279 if (isset($this->parent->by_object['sambaAccount'])){
280 $obj= $this->parent->by_object['sambaAccount'];
281 }
282 if (isset($obj) && $obj->is_account == TRUE &&
283 ((isset($this->parent->by_object['sambaAccount']))&&($this->parent->by_object['sambaAccount']->is_account))
284 ||(isset($this->parent->by_object['environment'] ))&&($this->parent->by_object['environment'] ->is_account)){
286 /* Samba3 dependency on posix accounts are enabled
287 in the moment, because I need to rely on unique
288 uidNumbers. There'll be a better solution later
289 on. */
290 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("POSIX")), msgPool::featuresEnabled(_("POSIX"), array(_("Samba"), _("Environment"))), TRUE);
291 } else {
292 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("POSIX")), msgPool::featuresEnabled(_("POSIX")));
293 }
294 } else {
295 $display= $this->show_enable_header(msgPool::addFeaturesButton(_("POSIX")), msgPool::featuresDisabled(_("POSIX")));
296 return($display);
297 }
298 }
299 }
301 // Display dialog to allow selection of groups
302 if (isset($_POST['edit_groupmembership'])){
303 $this->groupSelect = new groupSelect($this->config,get_userinfo());
304 }
306 // Cancel group dialog
307 if (isset($_POST['add_groups_cancel'])){
308 $this->groupSelect= NULL;
309 }
311 // Add groups selected in groupSelect dialog to ours.
312 if (isset($_POST['add_groups_finish']) && $this->groupSelect){
313 $groups = $this->groupSelect->detectPostActions();
314 if(isset($groups['targets'])){
315 $this->addGroup ($groups['targets']);
316 $this->is_modified= TRUE;
317 }
318 $this->groupSelect= NULL;
319 }
321 // Remove groups from currently selected groups.
322 if (isset($_POST['delete_groupmembership']) &&
323 isset($_POST['group_list']) && count($_POST['group_list'])){
325 $this->delGroup (get_post('group_list'));
326 }
328 /* Templates now! */
329 $smarty= get_smarty();
333 // Handle trust mode dialog
334 $trustModeDialog = $this->trustModeDialog->execute();
335 if($this->trustModeDialog->trustSelect){
336 $this->dialog = TRUE;
337 return($trustModeDialog);
339 }
340 $smarty->assign("trustModeDialog" , $trustModeDialog);
343 /* Manage group add dialog */
344 if ($this->groupSelect){
345 $this->dialog = TRUE;
347 // Build up blocklist
348 session::set('filterBlacklist', array('dn' => array_keys($this->groupMembership)));
349 return($this->groupSelect->execute());
350 }
352 // Handle ssh dialog?
353 if ($this->ssh instanceOf sshPublicKey && preg_match('/[rw]/', $this->getacl("sshPublicKey"))) {
355 if ($result= $this->ssh->execute()) {
356 $this->dialog= true;
357 pathNavigator::registerPlugin("SSH keys");
358 return $result;
359 }
360 }
363 /* Show main page */
364 $smarty= get_smarty();
367 $smarty->assign("sshPublicKeyACL", $this->getacl("sshPublicKey"));
369 /* Depending on pwmode, currently hardcoded because there are no other methods */
370 if ( 1 == 1 ){
371 $smarty->assign("pwmode", dirname(__FILE__)."/posix_shadow");
373 $shadowMinACL = $this->getacl("shadowMin");
374 $smarty->assign("shadowmins", sprintf(_("Password can't be changed up to %s days after last change"),
375 "<input type='text' name=\"shadowMin\" size=3 maxlength=4 value=\"".$this->shadowMin."\">"));
377 $shadowMaxACL = $this->getacl("shadowMax");
378 $smarty->assign("shadowmaxs", sprintf(_("Password must be changed after %s days"),
379 "<input type='text' name=\"shadowMax\" size=3 maxlength=4 value=\"".$this->shadowMax."\">"));
381 $shadowInactiveACL= $this->getacl("shadowInactive");
382 $smarty->assign("shadowinactives", sprintf(_("Disable account after %s days of inactivity after password expiry"),
383 "<input type='text' name=\"shadowInactive\" size=3 maxlength=4 value=\"".$this->shadowInactive."\">"));
385 $shadowWarningACL = $this->getacl("shadowWarning");
386 $smarty->assign("shadowwarnings", sprintf(_("Warn user %s days before password expiry"),
387 "<input type='text' name=\"shadowWarning\" size=3 maxlength=4 value=\"".$this->shadowWarning."\">"));
389 foreach( array("activate_shadowMin", "activate_shadowMax",
390 "activate_shadowExpire", "activate_shadowInactive","activate_shadowWarning") as $val){
391 if ($this->$val == 1){
392 $smarty->assign("$val", "checked");
393 } else {
394 $smarty->assign("$val", "");
395 }
396 $smarty->assign("$val"."ACL", $this->getacl(preg_replace("/^.*_/","",$val)));
397 }
399 $smarty->assign("mustchangepasswordACL", $this->getacl("mustchangepassword"));
400 }
402 // Set last system login
403 $smarty->assign("gotoLastSystemLogin", set_post($this->gotoLastSystemLogin));
405 /* Fill arrays */
406 $smarty->assign("shells", set_post($this->loginShellList));
407 $smarty->assign("secondaryGroups", $this->secondaryGroups);
408 $smarty->assign("primaryGroup", set_post($this->primaryGroup));
409 if(!$this->multiple_support_active){
410 if (!count($this->groupMembership)){
411 $smarty->assign("groupMembership", array(" "));
412 } else {
413 $smarty->assign("groupMembership", set_post($this->groupMembership));
414 }
415 }else{
416 $smarty->assign("groupMembership", set_post($this->groupMembership));
417 $smarty->assign("groupMembership_some", set_post($this->groupMembership_some));
418 }
420 if (count($this->groupMembership) > 16){
421 $smarty->assign("groups", "too_many_for_nfs");
422 } else {
423 $smarty->assign("groups", "");
424 }
426 /* Avoid "Undefined index: forceMode" */
427 $smarty->assign("forceMode", "");
429 /* Checkboxes */
430 if ($this->force_ids == 1){
431 $smarty->assign("force_ids", "checked");
432 if (session::get('js')){
433 $smarty->assign("forceMode", "");
434 }
435 } else {
436 if (session::get('js')){
437 $smarty->assign("forceMode", "disabled");
438 }
439 $smarty->assign("force_ids", "");
440 }
442 /* Create onClick="" action string for the "Force UID/GID" option
443 */
444 $onClickIDS ="";
445 if(preg_match("/w/",$this->getacl("uidNumber"))){
446 $onClickIDS .= "changeState('uidNumber');";
447 }
448 if(preg_match("/w/",$this->getacl("gidNumber"))){
449 $onClickIDS .= "changeState('gidNumber');";
450 }
451 $smarty->assign("onClickIDS", $onClickIDS);
452 $smarty->assign("force_idsACL", $this->getacl("uidNumber").$this->getacl("gidNumber"));
454 foreach(array("primaryGroup","activate_shadowWarning","activate_shadowInactive","activate_shadowMin","activate_shadowMax","activate_shadowExpire","mustchangepassword") as $val){
455 if(in_array($val,$this->multi_boxes)){
456 $smarty->assign("use_".$val,TRUE);
457 }else{
458 $smarty->assign("use_".$val,FALSE);
459 }
460 }
463 /* Load attributes and acl's */
464 foreach($this->attributes as $val){
465 if(in_array($val,$this->multi_boxes)){
466 $smarty->assign("use_".$val,TRUE);
467 }else{
468 $smarty->assign("use_".$val,FALSE);
469 }
470 $smarty->assign("$val", set_post($this->$val));
471 }
473 $tmp = $this->plInfo();
474 foreach($tmp['plProvidedAcls'] as $val => $desc){
475 $smarty->assign("$val"."ACL", $this->getacl($val));
476 }
478 if($this->read_only){
479 $smarty->assign("groupMembershipACL","r");
480 }else{
481 $smarty->assign("groupMembershipACL","rw");
482 }
483 $smarty->assign("status", $this->status);
485 if($this->mustchangepassword){
486 $smarty->assign("mustchangepassword", " checked ");
487 } else {
488 $smarty->assign("mustchangepassword", "");
489 }
491 // Add SSH button if available
492 $smarty->assign("sshPublicKey", $this->ssh?1:0);
494 $smarty->assign("multiple_support" , $this->multiple_support_active);
495 $display.= $smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
496 return($display);
497 }
500 /* remove object from parent */
501 function remove_from_parent()
502 {
503 /* Cancel if there's nothing to do here */
504 if ((!$this->initially_was_account) || (!$this->acl_is_removeable())){
505 return;
506 }
509 /* Remove and write to LDAP */
510 plugin::remove_from_parent();
512 /* Zero out array */
513 $this->attrs['gosaHostACL']= array();
515 /* Keep uid, because we need it for authentification! */
516 unset($this->attrs['uid']);
518 @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,
519 /* include global link_info */
520 $this->attributes, "Save");
521 $ldap= $this->config->get_ldap_link();
522 $ldap->cd($this->dn);
523 $this->cleanup();
524 $ldap->modify ($this->attrs);
526 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
528 if (!$ldap->success()){
529 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
530 }
532 /* Delete group only if cn is uid and there are no other
533 members inside */
534 $ldap->cd ($this->config->current['BASE']);
535 $ldap->search ("(&(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))", array("cn", "memberUid"));
536 if ($ldap->count() != 0){
537 $attrs= $ldap->fetch();
538 if ($attrs['cn'][0] == $this->uid &&
539 !isset($this->attrs['memberUid'])){
541 $ldap->rmDir($ldap->getDN());
542 }
543 }
545 /* Optionally execute a command after we're done */
546 $this->handle_post_events("remove",array("uid" => $this->uid));
547 }
550 function save_object()
551 {
552 if (isset($_POST['posixTab'])){
553 /* Save values to object */
554 plugin::save_object();
555 $this->trustModeDialog->save_object();
557 /* Save force GID checkbox */
558 if($this->acl_is_writeable("gidNumber") || $this->acl_is_writeable("uidNumber")){
559 if (isset ($_POST['force_ids'])){
560 $data= 1;
561 } else {
562 $data= 0;
563 }
564 if ($this->force_ids != $data){
565 $this->is_modified= TRUE;
566 }
567 $this->force_ids= $data;
568 }
570 /*Save primary group settings */
571 if($this->acl_is_writeable("primaryGroup") && isset($_POST['primaryGroup'])){
572 $data= get_post('primaryGroup');
573 if ($this->primaryGroup != $data){
574 $this->is_modified= TRUE;
575 }
576 $this->primaryGroup= get_post('primaryGroup');
577 }
579 /* Get seelcted shadow checkboxes */
580 foreach(array("shadowMin","shadowMax","shadowExpire","shadowInactive","shadowWarning") as $var) {
581 if($this->acl_is_writeable($var)){
582 $activate_var = "activate_".$var;
583 if(isset($_POST['activate_'.$var])){
584 $this->$activate_var = true;
585 $this->$var = get_post($var);
586 }else{
587 $this->$activate_var = false;
588 if ($var != "shadowExpire") {
589 $this->$var = 0;
590 }
591 }
592 }
593 }
595 /* Force change password ? */
596 if(isset($_POST['mustchangepassword'])){
597 $this->mustchangepassword = TRUE;
598 }else{
599 $this->mustchangepassword = FALSE;
600 }
601 }
602 }
605 /* Save data to LDAP, depending on is_account we save or delete */
606 function save()
607 {
609 /* Adapt shadow values */
610 if (!$this->activate_shadowExpire){
611 $this->shadowExpire= "0";
612 } else {
613 /* Transform date to days since the beginning */
614 list($day, $month, $year)= explode('.', $this->shadowExpire, 3);
615 $this->shadowExpire= (int)(mktime(0, 0, 0, $month, $day, $year)/ (60 * 60 * 24)) ;
616 }
617 if (!$this->activate_shadowMax){
618 $this->shadowMax= "0";
619 }
620 if ($this->mustchangepassword){
621 $this->shadowLastChange= (int)(date("U") / 86400) - $this->shadowMax - 1;
622 } else {
623 # $this->shadowLastChange= (int)(date("U") / 86400);
624 }
625 if (!$this->activate_shadowWarning){
626 $this->shadowWarning= "0";
627 }
629 /* Check what to do with ID's
630 Nothing forced, so we may have to generate our own IDs, if not done already.
631 */
632 if ($this->force_ids == 0){
634 /* Handle uidNumber.
635 * - use existing number if possible
636 * - if not, try to create a new uniqe one.
637 * */
638 if ($this->savedUidNumber != ""){
639 $this->uidNumber= $this->savedUidNumber;
640 } else {
642 /* Calculate new id's. We need to place a lock before calling get_next_id
643 to get real unique values.
644 */
645 $wait= 10;
646 while (get_lock("uidnumber") != ""){
647 sleep (1);
649 /* Oups - timed out */
650 if ($wait-- == 0){
651 msg_dialog::display(_("Warning"), _("Timeout while waiting for lock. Ignoring lock!"), WARNING_DIALOG);
652 break;
653 }
654 }
655 add_lock ("uidnumber", "gosa");
656 $this->uidNumber= get_next_id("uidNumber", $this->dn);
657 }
658 }
661 /* Handle gidNumber
662 * - If we do not have a primary group selected (automatic), we will check if there
663 * is already a group with the same name and use this as primary.
664 * - .. if we couldn't find a group with the same name, we will create a new one,
665 * using the users uid as cn and a generated uniqe gidNumber.
666 * */
667 if ($this->primaryGroup == 0 || $this->force_ids){
669 /* Search for existing group */
670 $ldap = $this->config->get_ldap_link();
671 $ldap->cd($this->config->current['BASE']);
673 /* Are we forced to use a special gidNumber? */
674 if($this->force_ids){
675 $ldap->search("(&(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))", array("cn","gidNumber"));
676 }else{
677 $ldap->search("(&(objectClass=posixGroup)(gidNumber=*)(cn=".$this->uid."))", array("cn","gidNumber"));
678 }
680 /* No primary group found, create a new one */
681 if ($ldap->count() == 0){
683 $groupcn = $this->uid;
684 $pri_attr = $this->config->get_cfg_value("core","accountPrimaryAttribute");
685 $groupdn= preg_replace ('/^'.preg_quote($pri_attr,'/').'=[^,]+,'.preg_quote(get_people_ou(),'/').'/i',
686 'cn='.$groupcn.','.get_groups_ou(), $this->dn);
688 /* Request a new and uniqe gidNumber, if required */
689 if(!$this->force_ids){
690 $this->gidNumber= get_next_id("gidNumber", $this->dn);
691 }
693 /* If forced gidNumber could not be found, then check if the given group name already exists
694 we do not want to modify the gidNumber of an existing group.
695 */
696 $cnt= 0;
697 while($ldap->dn_exists($groupdn) && ($cnt < 100)){
698 $cnt ++;
699 $groupcn = $this->uid."_".$cnt;
700 $groupdn= preg_replace ('/^'.preg_quote($pri_attr,'/').'=[^,]+,'.preg_quote(get_people_ou(),'/').'/i',
701 'cn='.$groupcn.','.get_groups_ou(), $this->dn);
702 }
704 /* Create new primary group and enforce the new gidNumber */
705 $g= new group($this->config, $groupdn);
706 $g->cn= $groupcn;
707 $g->force_gid= 1;
708 $g->gidNumber= $this->gidNumber;
709 $g->description= _("Group of user")." ".$this->givenName." ".$this->sn;
710 $g->save ();
712 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
713 sprintf("Primary group '%s' created, using gidNumber '%s'.",$groupcn,$this->gidNumber),"");
714 }else{
715 $attrs = $ldap->fetch();
716 $this->gidNumber = $attrs['gidNumber'][0];
717 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
718 "Found and used: <i>".$attrs['dn']."</i>",
719 sprintf("Primary group '%s' exists, gidNumber is '%s'.",$this->uid,$this->gidNumber));
720 }
721 }else{
723 /* Primary group was selected by user
724 */
725 $this->gidNumber = $this->primaryGroup;
726 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
727 sprintf("Primary group '%s' for user '%s' manually selected.",$this->gidNumber,$this->uid),"");
728 }
730 if ($this->activate_shadowMin != "1" ) {
731 $this->shadowMin = "";
732 }
734 if (($this->activate_shadowMax != "1") && ($this->mustchangepassword != "1")) {
735 $this->shadowMax = "";
736 }
738 if ($this->activate_shadowWarning != "1" ) {
739 $this->shadowWarning = "";
740 }
742 if ($this->activate_shadowInactive != "1" ) {
743 $this->shadowInactive = "";
744 }
746 if ($this->activate_shadowExpire != "1" ) {
747 $this->shadowExpire = "";
748 }
750 /* Fill gecos */
751 if (isset($this->parent) && $this->parent !== NULL){
752 $this->gecos= rewrite($this->parent->by_object['user']->cn);
753 if (!preg_match('/^[a-z0-9 -]+$/i', $this->gecos)){
754 $this->gecos= "";
755 }
756 }
758 foreach(array("shadowMin","shadowMax","shadowWarning","shadowInactive","shadowExpire") as $attr){
759 $this->$attr = (int) $this->$attr;
760 }
761 /* Call parents save to prepare $this->attrs */
762 plugin::save();
764 /* include global link_info */
765 $this->cleanup();
767 /* This is just a test, we have had duplicated ids
768 in the past when copy & paste was used.
769 Normaly this should not happen.
770 */
771 if(isset($this->attrs['uidNumber']) && !$this->force_ids){
772 $used = $this->get_used_uid_numbers();
773 if(isset($used[$this->attrs['uidNumber']]) && $used[$this->attrs['uidNumber']] != $this->dn){
774 msg_dialog::display(_("Warning"),_("A duplicated UID number was written for this user. If this was not intended please verify all used uidNumbers!"), WARNING_DIALOG);
775 }
776 }
778 $ldap= $this->config->get_ldap_link();
779 $ldap->cd($this->dn);
780 unset($this->attrs['uid']);
781 $ldap->modify ($this->attrs);
783 /* Log last action */
784 if($this->initially_was_account){
785 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
786 }else{
787 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
788 }
790 if (!$ldap->success()){
791 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
792 }
794 /* Remove lock needed for unique id generation */
795 del_lock ("uidnumber");
797 // Save ssh stuff if needed
798 if ($this->ssh) {
799 $this->ssh->setDN($this->dn);
800 $this->ssh->save();
801 }
803 $this->trustModeDialog->dn = $this->dn;
804 $this->trustModeDialog->save();
806 /* Take care about groupMembership values: add to groups */
807 foreach ($this->groupMembership as $key => $value){
808 if (!isset($this->savedGroupMembership[$key])){
809 $g= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $key,"groups");
810 $g->set_acl_base($key);
811 $g->by_object['group']->addUser($this->uid);
812 $g->save();
813 }
814 }
816 /* Remove groups not listed in groupMembership */
817 foreach ($this->savedGroupMembership as $key => $value){
818 if (!isset($this->groupMembership[$key])){
819 $g= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $key,"groups");
820 $g->set_acl_base($key);
821 $g->by_object['group']->removeUser ($this->uid);
822 $g->save();
823 }
824 }
826 /* Optionally execute a command after we're done */
827 if ($this->initially_was_account == $this->is_account){
828 if ($this->is_modified){
829 $this->handle_post_events("modify",array("uid" => $this->uid));
830 }
831 } else {
832 $this->handle_post_events("add" ,array("uid"=> $this->uid));
833 }
834 }
837 /* Check formular input */
838 function check()
839 {
840 /* Include global link_info */
841 $ldap= $this->config->get_ldap_link();
843 /* Append groups as memberGroup: to check hook
844 */
845 $tmp_attributes = $this->attributes;
846 $this->attributes[] = "memberGroup";
847 $this->memberGroup = array();
848 foreach($this->groupMembership as $dn => $name){
849 $this->memberGroup[] = $name;
850 }
852 /* Call common method to give check the hook */
853 $message= plugin::check();
854 $this->attributes = $tmp_attributes;
856 /* must: homeDirectory */
857 if ($this->homeDirectory == ""){
858 $message[]= msgPool::required(_("Home directory"));
859 }
860 if (!tests::is_path($this->homeDirectory)){
861 $message[]= msgPool::invalid(_("Home directory"), "", "", "/home/yourname" );
862 }
864 /* Check ID's if they are forced by user */
865 if ($this->force_ids == "1"){
867 /* Valid uid/gid? */
868 if (!tests::is_id($this->uidNumber)){
869 $message[]= msgPool::invalid(_("UID"), $this->uidNumber, "/[0-9]/");
870 } else {
871 if ($this->uidNumber < $this->config->get_cfg_value("core","minId")){
872 $message[]= msgPool::toosmall(_("UID"), $this->config->get_cfg_value("core","minId"));
873 }
874 }
875 if (!tests::is_id($this->gidNumber)){
876 $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
877 } else {
878 if ($this->gidNumber < $this->config->get_cfg_value("core","minId")){
879 $message[]= msgPool::toosmall(_("GID"), $this->config->get_cfg_value("core","minId"));
880 }
881 }
882 }
884 /* Check dates */
885 if ($this->activate_shadowExpire && ($this->shadowExpire == "" || !tests::is_date($this->shadowExpire))){
886 $message[]= msgPool::invalid("shadowExpire", $this->shadowExpire);
887 }
889 /* Check shadow settings, well I like spaghetties... */
890 if ($this->activate_shadowMin){
891 if (!tests::is_id($this->shadowMin)){
892 $message[]= msgPool::invalid(_("shadowMin"), $this->shadowMin, "/[0-9]/");
893 }
894 }
895 if ($this->activate_shadowMax){
896 if (!tests::is_id($this->shadowMax)){
897 $message[]= msgPool::invalid(_("shadowMax"), $this->shadowMax, "/[0-9]/");
898 }
899 }
900 if ($this->activate_shadowWarning){
901 if (!tests::is_id($this->shadowWarning)){
902 $message[]= msgPool::invalid(_("shadowWarning"), $this->shadowWarning, "/[0-9]/");
903 }
904 if (!$this->activate_shadowMax){
905 $message[]= msgPool::depends("shadowWarning", "shadowMax");
906 }
907 if ($this->shadowWarning > $this->shadowMax){
908 $message[]= msgPool::toobig("shadowWarning", "shadowMax");
909 }
910 if ($this->activate_shadowMin && $this->shadowWarning < $this->shadowMin){
911 $message[]= msgPool::toosmall("shadowWarning", "shadowMin");
912 }
913 }
914 if ($this->activate_shadowInactive){
915 if (!tests::is_id($this->shadowInactive)){
916 $message[]= msgPool::invalid(_("shadowInactive"), $this->shadowInactive, "/[0-9]/");
917 }
918 if (!$this->activate_shadowMax){
919 $message[]= msgPool::depends("shadowInactive", "shadowMax");
920 }
921 }
922 if ($this->activate_shadowMin && $this->activate_shadowMax){
923 if ($this->shadowMin > $this->shadowMax){
924 $message[]= msgPool::toobig("shadowMin", "shadowMax");
925 }
926 }
928 return ($message);
929 }
932 function multiple_check()
933 {
934 $message = plugin::multiple_check();
935 if ($this->homeDirectory == "" && in_array("homeDirectory",$this->multi_boxes)){
936 $message[]= msgPool::required(_("Home directory"));
937 }
938 if (!tests::is_path($this->homeDirectory) && in_array("homeDirectory",$this->multi_boxes)){
939 $message[]= msgPool::invalid(_("Home directory"), "", "", "/home/yourname" );
940 }
942 /* Check shadow settings, well I like spaghetties... */
943 if ($this->activate_shadowMin && in_array("activate_shadowMin",$this->multi_boxes)){
944 if (!tests::is_id($this->shadowMin)){
945 $message[]= msgPool::invalid(_("shadowMin"), $this->shadowMin, "/[0-9]/");
946 }
947 }
948 if ($this->activate_shadowMax && in_array("activate_shadowMax",$this->multi_boxes)){
949 if (!tests::is_id($this->shadowMax)){
950 $message[]= msgPool::invalid(_("shadowMax"), $this->shadowMax, "/[0-9]/");
951 }
952 }
953 if ($this->activate_shadowWarning && in_array("activate_shadowWarning",$this->multi_boxes)){
954 if (!tests::is_id($this->shadowWarning)){
955 $message[]= msgPool::invalid(_("shadowWarning"), $this->shadowWarning, "/[0-9]/");
956 }
957 if (!$this->activate_shadowMax && in_array("activate_shadowMax",$this->multi_boxes)){
958 $message[]= msgPool::depends("shadowWarning", "shadowMax");
959 }
960 if ($this->shadowWarning > $this->shadowMax && in_array("activate_shadowWarning",$this->multi_boxes)){
961 $message[]= msgPool::toobig("shadowWarning", "shadowMax");
962 }
963 if ($this->activate_shadowMin && $this->shadowWarning < $this->shadowMin && in_array("activate_shadowMin",$this->multi_boxes)){
964 $message[]= msgPool::tosmall("shadowWarning", "shadowMin");
965 }
966 }
967 if ($this->activate_shadowInactive && in_array("activate_shadowInactive",$this->multi_boxes)){
968 if (!tests::is_id($this->shadowInactive)){
969 $message[]= msgPool::invalid(_("shadowInactive"), $this->shadowInactive, "/[0-9]/");
970 }
971 if (!$this->activate_shadowMax && in_array("activate_shadowMax",$this->multi_boxes)){
972 $message[]= msgPool::depends("shadowInactive", "shadowMax");
973 }
974 }
975 if ($this->activate_shadowMin && $this->activate_shadowMax && in_array("activate_shadowMin",$this->multi_boxes)){
976 if ($this->shadowMin > $this->shadowMax){
977 $message[]= msgPool::toobig("shadowMin", "shadowMax");
978 }
979 }
981 return($message);
982 }
985 function addGroup ($groups)
986 {
987 /* include global link_info */
988 $ldap= $this->config->get_ldap_link();
990 /* Walk through groups and add the descriptive entry if not exists */
991 foreach ($groups as $value){
993 if (!array_key_exists($value, $this->groupMembership)){
994 $ldap->cat($value, array('cn', 'description', 'dn'));
995 $attrs= $ldap->fetch();
996 error_reporting (0);
997 if (!isset($attrs['description'][0])){
998 $entry= $attrs["cn"][0];
999 } else {
1000 $dsc= preg_replace ('/^Group of user/', _("Group of user"), $attrs["description"][0]);
1001 $entry= $attrs["cn"][0]." [$dsc]";
1002 }
1003 error_reporting (E_ALL | E_STRICT);
1005 if(obj_is_writable($attrs['dn'],"groups/group","memberUid")){
1006 $this->groupMembership[$attrs['dn']]= $entry;
1007 if($this->multiple_support_active && isset($this->groupMembership_some[$attrs['dn']])){
1008 unset($this->groupMembership_some[$attrs['dn']]);
1009 }
1010 }
1011 }
1012 }
1014 /* Sort groups */
1015 asort ($this->groupMembership);
1016 reset ($this->groupMembership);
1017 }
1020 /* Del posix user from some groups */
1021 function delGroup ($groups)
1022 {
1023 $dest= array();
1024 foreach($groups as $dn_to_del){
1025 if(isset($this->groupMembership[$dn_to_del]) && obj_is_writable($dn_to_del,"groups/group","memberUid")){
1026 unset($this->groupMembership[$dn_to_del]);
1027 }
1028 if($this->multiple_support_active){
1029 if(isset($this->groupMembership_some[$dn_to_del]) && obj_is_writable($dn_to_del,"groups/group","memberUid")){
1030 unset($this->groupMembership_some[$dn_to_del]);
1031 }
1032 }
1033 }
1034 }
1037 /* Adapt from template, using 'dn' */
1038 function adapt_from_template($dn, $skip= array())
1039 {
1040 /* Include global link_info */
1041 $ldap= $this->config->get_ldap_link();
1043 plugin::adapt_from_template($dn, $skip);
1044 $template= $this->attrs['uid'][0];
1046 /* Adapt group membership */
1047 $ldap->cd($this->config->current['BASE']);
1048 $ldap->search("(&(objectClass=posixGroup)(memberUid=".$this->attrs["uid"][0]."))", array("description", "cn"));
1050 while ($this->attrs= $ldap->fetch()){
1051 if (!isset($this->attrs["description"][0])){
1052 $entry= $this->attrs["cn"][0];
1053 } else {
1054 $entry= $this->attrs["cn"][0]." [".$this->attrs["description"][0]."]";
1055 }
1056 $this->groupMembership[$ldap->getDN()]= $entry;
1057 }
1059 /* Fix primary group settings */
1060 $ldap->cd($this->config->current['BASE']);
1061 $ldap->search("(&(objectClass=posixGroup)(cn=$template)(gidNumber=".$this->gidNumber."))", array("cn"));
1062 if ($ldap->count() != 1){
1063 $this->primaryGroup= $this->gidNumber;
1064 }
1066 $ldap->cd($this->config->current['BASE']);
1067 $ldap->search("(&(objectClass=gosaUserTemplate)(uid=".$template.")(accessTo=*))", array("cn","accessTo"));
1068 while($attr = $ldap->fetch()){
1069 $tmp = $attr['accessTo'];
1070 unset ($tmp['count']);
1071 $this->accessTo = $tmp;
1072 }
1074 /* Adjust shadow checkboxes */
1075 foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive") as $val){
1076 if ($this->$val != 0){
1077 $oval= "activate_".$val;
1078 $this->$oval= "1";
1079 }
1080 }
1082 /* Only enable checkbox, if shadowExpire is in the future */
1083 if($this->shadowExpire > time()) {
1084 $this->activate_shadowExpire= "1";
1085 }
1087 /* Convert shadowExpire for usage */
1088 if ($this->shadowExpire == 0){
1089 $this->shadowExpire= "";
1090 } else {
1091 $this->shadowExpire= date('d.m.Y', $this->shadowExpire * 60 * 60 * 24);
1092 }
1093 }
1095 function convertToSeconds($val)
1096 {
1097 if ($val != 0){
1098 $val*= 60 * 60 * 24;
1099 } else {
1100 $date= getdate();
1101 $val= floor($date[0] / (60*60*24)) * 60 * 60 * 24;
1102 }
1103 return($val);
1104 }
1107 function get_used_uid_numbers()
1108 {
1109 $ids= array();
1110 $ldap= $this->config->get_ldap_link();
1112 $ldap->cd ($this->config->current['BASE']);
1113 $ldap->search ("(&(objectClass=posixAccount)(uidNumber=*))", array("uidNumber"));
1115 /* Get list of ids */
1116 while ($attrs= $ldap->fetch()){
1117 $ids[$attrs['uidNumber'][0]] = $attrs['dn'];
1118 }
1119 return($ids);
1120 }
1123 /* Get posts from copy & paste dialog */
1124 function saveCopyDialog()
1125 {
1126 if(isset($_POST['homeDirectory'])){
1127 $this->homeDirectory = get_post('homeDirectory');
1128 if (isset ($_POST['force_ids'])){
1129 $data= 1;
1130 $this->gidNumber = get_post('gidNumber');
1131 $this->uidNumber = get_post('uidNumber');
1132 } else {
1133 $data= 0;
1134 }
1135 if ($this->force_ids != $data){
1136 $this->is_modified= TRUE;
1137 }
1138 $this->force_ids= $data;
1139 $data= get_post('primaryGroup');
1140 if ($this->primaryGroup != $data){
1141 $this->is_modified= TRUE;
1142 }
1143 $this->primaryGroup= get_post('primaryGroup');
1144 }
1145 }
1148 /* Create the posix dialog part for copy & paste */
1149 function getCopyDialog()
1150 {
1151 /* Skip dialog creation if this is not a valid account*/
1152 if(!$this->is_account) return("");
1153 if ($this->force_ids == 1){
1154 $force_ids = "checked";
1155 if (session::get('js')){
1156 $forceMode = "";
1157 }
1158 } else {
1159 if (session::get('js')){
1160 if($this->acl != "#none#")
1161 $forceMode ="disabled";
1162 }
1163 $force_ids = "";
1164 }
1166 $sta = "";
1168 /* Open group add dialog */
1169 if(isset($_POST['edit_groupmembership'])){
1170 $this->groupSelect = new groupSelect($this->config,get_userinfo());
1171 $sta = "SubDialog";
1172 }
1174 /* If the group-add dialog is closed, call execute
1175 to ensure that the membership is updatd */
1176 if(isset($_POST['add_groups_finish']) || isset($_POST['add_groups_cancel'])){
1177 $this->execute();
1178 $this->groupSelect =NULL;
1179 }
1181 if($this->groupSelect){
1182 $str = $this->execute(true);
1183 $ret = array();
1184 $ret['string'] = $str;
1185 $ret['status'] = $sta;
1186 return($ret);
1187 }
1189 /* If a group member should be deleted, simply call execute */
1190 if(isset($_POST['delete_groupmembership'])){
1191 $this->execute();
1192 }
1194 /* Assigned informations to smarty */
1195 $smarty = get_smarty();
1196 $smarty->assign("homeDirectory",set_post($this->homeDirectory));
1197 $smarty->assign("secondaryGroups",$this->secondaryGroups);
1198 $smarty->assign("primaryGroup",set_post($this->primaryGroup));
1200 $smarty->assign("uidNumber",set_post($this->uidNumber));
1201 $smarty->assign("gidNumber",set_post($this->gidNumber));
1202 $smarty->assign("forceMode",set_post($forceMode));
1203 $smarty->assign("force_ids",set_post($force_ids));
1204 if (!count($this->groupMembership)){
1205 $smarty->assign("groupMembership", array(" "));
1206 } else {
1207 $smarty->assign("groupMembership", set_post($this->groupMembership));
1208 }
1210 /* Display wars message if there are more than 16 group members */
1211 if (count($this->groupMembership) > 16){
1212 $smarty->assign("groups", "too_many_for_nfs");
1213 } else {
1214 $smarty->assign("groups", "");
1215 }
1216 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE,dirname(__FILE__)));
1218 $ret = array();
1219 $ret['string'] = $str;
1220 $ret['status'] = $sta;
1221 return($ret);
1222 }
1225 function PrepareForCopyPaste($source)
1226 {
1227 plugin::PrepareForCopyPaste($source);
1229 $this->trustModeDialog->PrepareForCopyPaste($source);
1231 /* Avoid using the same gid/uid number as source user
1232 empty numbers to enforce new ones. */
1233 $this->savedUidNumber = "";
1234 $this->savedGidNumber = "";
1236 /* Get group membership */
1237 $ldap = $this->config->get_ldap_link();
1238 $ldap->cd($this->config->current['BASE']);
1239 $ldap->search("(&(objectClass=posixGroup)(memberUid=".$source['uid'][0]."))", array("cn", "description"));
1241 while ($attrs= $ldap->fetch()){
1242 if (!isset($attrs["description"][0])){
1243 $entry= $attrs["cn"][0];
1244 } else {
1245 $entry= $attrs["cn"][0]." [".$attrs["description"][0]."]";
1246 }
1247 $this->groupMembership[$ldap->getDN()]= $entry;
1248 }
1249 asort($this->groupMembership);
1250 reset($this->groupMembership);
1252 /* Fill group */
1253 if(isset($source['gidNumber'][0])){
1254 $this->primaryGroup= $source['gidNumber'][0];
1255 }
1258 /* Adjust shadow checkboxes */
1259 foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
1260 "shadowExpire") as $val){
1262 if ($this->$val != 0){
1263 $oval= "activate_".$val;
1264 $this->$oval= "1";
1265 }
1266 }
1268 /* Convert shadowExpire for usage */
1269 if ($this->shadowExpire == 0){
1270 $this->shadowExpire= "";
1271 } else {
1272 $this->shadowExpire= date('d.m.Y', $this->shadowExpire * 60 * 60 * 24);
1273 }
1275 $tmp = new trustModeDialog($this->config, $source['dn']);
1276 $this->trustModeDialog = new trustModeDialog($this->config, $this->dn);
1277 $this->trustModeDialog->trustModel = $tmp->trustModel;
1278 $this->trustModeDialog->accessTo = $tmp->accessTo;
1279 $this->trustModeDialog->setAcl('users/posixAccount');
1281 }
1284 function multiple_execute()
1285 {
1286 return($this->execute());
1287 }
1290 static function plInfo()
1291 {
1292 return (array(
1293 "plDescription" => _("POSIX account"),
1294 "plSelfModify" => TRUE,
1295 "plDepends" => array("user"),
1296 "plPriority" => 2,
1297 "plSection" => array("personal" => _("My account")),
1298 "plCategory" => array("users"),
1299 "plOptions" => array(),
1300 "plRequirements"=> array(
1301 'ldapSchema' => array('posixAccount' => ''),
1302 'onFailureDisablePlugin' => array(get_class(), 'sambaAccount','netatalk','environment')
1303 ),
1305 "plProvidedAcls" => array(
1307 "homeDirectory" => _("Home directory"),
1308 "primaryGroup" => _("Primary group"),
1309 "loginShell" => _("Shell"),
1310 "uidNumber" => _("User ID"),
1311 "gidNumber" => _("Group ID"),
1313 "shadowLastChange" => _("Shadow last changed"),
1314 "gotoLastSystemLogin" => _("Last login"),
1316 "mustchangepassword"=> _("Force password change on login"),
1317 "shadowMin" => _("Shadow min"),
1318 "shadowMax" => _("Shadow max"),
1319 "shadowWarning" => _("Shadow warning"),
1320 "shadowInactive" => _("Shadow inactive"),
1321 "shadowExpire" => _("Shadow expire"),
1322 "sshPublicKey" => _("Public SSH key"),
1323 "accessTo" => _("System trust model")))
1324 );
1325 }
1328 /* Return selected values for multiple edit */
1329 function get_multi_edit_values()
1330 {
1331 $ret = plugin::get_multi_edit_values();
1332 $ret = array_merge($ret,$this->trustModeDialog->get_multi_edit_values());
1333 $ret['groupMembership'] = $this->groupMembership;
1334 $ret['groupMembership_some']= $this->groupMembership_some;
1336 if(in_array("primaryGroup",$this->multi_boxes)){
1337 $ret['primaryGroup'] = $this->primaryGroup;
1338 }
1339 foreach(array("shadowWarning","shadowInactive","shadowMin","shadowMax", "shadowExpire") as $entry){
1340 $active = "activate_".$entry;
1341 if(in_array($active,$this->multi_boxes)){
1342 $ret[$entry] = $this->$entry;
1343 $ret[$active] = $this->$active;
1344 }
1345 }
1346 if(in_array("mustchangepassword",$this->multi_boxes)){
1347 $ret['mustchangepassword'] = $this->mustchangepassword;
1348 }
1349 return($ret);
1350 }
1353 /* Save posts for multiple edit
1354 */
1355 function multiple_save_object()
1356 {
1357 if(isset($_POST['posix_mulitple_edit'])){
1359 /* Backup expire value */
1360 $expire_tmp = $this->shadowExpire;
1362 /* Update all values */
1363 plugin::multiple_save_object();
1365 $this->trustModeDialog->multiple_save_object();
1367 /* Get selected checkboxes */
1368 foreach(array("primaryGroup","mustchangepassword","activate_shadowWarning","activate_shadowInactive","activate_shadowMin", "activate_shadowMax","activate_shadowExpire") as $val){
1369 if(isset($_POST["use_".$val])){
1370 $this->multi_boxes[] = $val;
1371 }
1372 }
1374 /* Update special values, checkboxes for posixShadow */
1375 foreach(array("shadowMin","shadowMax","shadowExpire","shadowInactive","shadowWarning") as $var) {
1376 if($this->acl_is_writeable($var)){
1377 $activate_var = "activate_".$var;
1378 if(in_array($activate_var, $this->multi_boxes)){
1379 if(isset($_POST['activate_'.$var])){
1380 $this->$activate_var = true;
1381 $this->$var = get_post($var);
1382 }else{
1383 $this->$activate_var = false;
1384 $this->$var = 0;
1385 }
1386 }
1387 }
1388 }
1390 /* Restore shadow value, if the shadow attribute isn't used */
1391 if(!in_array("activate_shadowExpire",$this->multi_boxes)){
1392 $this->shadowExpire = $expire_tmp;
1393 }
1395 /* Force change password ? */
1396 if(isset($_POST['mustchangepassword'])){
1397 $this->mustchangepassword = TRUE;
1398 }else{
1399 $this->mustchangepassword = FALSE;
1400 }
1402 /* Save primary group settings */
1403 if($this->acl_is_writeable("primaryGroup") && isset($_POST['primaryGroup'])){
1404 $data= get_post('primaryGroup');
1405 if ($this->primaryGroup != $data){
1406 $this->is_modified= TRUE;
1407 }
1408 $this->primaryGroup= get_post('primaryGroup');
1409 }
1410 }
1411 }
1414 /* Initialize plugin with given atribute arrays
1415 */
1416 function init_multiple_support($attrs,$all)
1417 {
1418 plugin::init_multiple_support($attrs,$all);
1419 $this->trustModeDialog->init_multiple_support($attrs,$all);
1421 /* Some dummy values */
1422 $groups_some = array();
1423 $groups_all = array();
1424 $groups_uid = array();
1425 $uids = array();
1426 $first = TRUE;
1428 /* Get all groups used by currently edited users */
1429 $uid_filter="";
1430 for($i =0; $i < $this->multi_attrs_all['uid']['count'] ; $i ++){
1431 $uid = $this->multi_attrs_all['uid'][$i];
1432 $uids[] = $uid;
1433 $uid_filter.= "(memberUid=".$uid.")";
1434 }
1435 $uid_filter = "(&(objectClass=posixGroup)(|".$uid_filter."))";
1436 $ldap = $this->config->get_ldap_link();
1437 $ldap->cd($this->config->current['BASE']);
1438 $ldap->search($uid_filter,array("dn","cn","memberUid"));
1439 while($group = $ldap->fetch()){
1440 $groups_some[$group['dn']] = $group['cn'][0];
1441 for($i = 0 ; $i < $group['memberUid']['count'] ; $i++){
1442 $groups_uid[$group['dn']][] = $group['memberUid'][$i];
1443 }
1444 }
1446 /* Create an array, containing all used groups */
1447 $groups_all = $groups_some;
1448 foreach($groups_all as $id => $group){
1449 foreach($uids as $uid){
1450 if(!in_array($uid,$groups_uid[$id])){
1451 unset($groups_all[$id]);
1452 break;
1453 }
1454 }
1455 }
1457 /* Assign group array */
1458 $this->groupMembership = $groups_all;
1460 /* Create an array of all grouops used by all users */
1461 foreach( $groups_all as $dn => $cn){
1462 if(isset($groups_some[$dn])){
1463 unset($groups_some[$dn]);
1464 }
1465 }
1466 $this->groupMembership_some = $groups_some;
1467 $this->primaryGroup = $this->gidNumber;
1469 /* Adjust shadow checkboxes */
1470 foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
1471 "shadowExpire") as $val){
1472 if ($this->$val != 0){
1473 $oval= "activate_".$val;
1474 $this->$oval= "1";
1475 }
1476 }
1478 /* Convert to seconds */
1479 if(isset($this->multi_attrs['shadowExpire'])){
1480 $this->shadowExpire = $this->convertToSeconds($this->multi_attrs['shadowExpire'][0]);
1481 }else{
1482 $this->activate_shadowExpire = FALSE;
1483 }
1484 }
1487 function set_multi_edit_values($attrs)
1488 {
1489 $groups = array();
1491 /* Update groupMembership, keep optinal group */
1492 foreach($attrs['groupMembership_some'] as $dn => $cn){
1493 if(isset($this->groupMembership[$dn])){
1494 $groups[$dn] = $cn;
1495 }
1496 }
1497 /* Update groupMembership, add forced groups */
1498 foreach($attrs['groupMembership'] as $dn => $cn){
1499 $groups[$dn] = $cn;
1500 }
1501 plugin::set_multi_edit_values($attrs);
1502 $this->trustModeDialog->set_multi_edit_values($attrs);
1503 $this->groupMembership = $groups;
1504 }
1506 function set_acl_base($base)
1507 {
1508 @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,"<b>".$base."</b>","<b>ACL-Base:</b> ");
1509 $this->acl_base= $base;
1510 $this->trustModeDialog->set_acl_base($base);
1511 }
1513 /*! \brief Enables multiple support for this plugin
1514 */
1515 function enable_multiple_support()
1516 {
1517 plugin::enable_multiple_support();
1518 $this->trustModeDialog->enable_multiple_support();
1519 }
1521 }
1523 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1524 ?>