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 class userManagement extends management
24 {
25 var $plHeadline = "Users";
26 var $plDescription = "Manage users";
27 var $plIcon = "plugins/users/images/user.png";
29 var $sn = "";
30 var $givenName = "";
31 var $uid = "";
32 var $got_uid = "";
33 var $edit_uid = "";
35 // Tab definition
36 protected $tabClass = "usertabs";
37 protected $tabType = "USERTABS";
38 protected $aclCategory = "users";
39 protected $aclPlugin = "user";
40 protected $objectName = "user";
42 function __construct($config,$ui)
43 {
44 $this->config = $config;
45 $this->ui = $ui;
47 // Build filter
48 $filter = new filter(get_template_path("user-filter.xml", true));
49 $filter->setObjectStorage("ou=people,");
50 $this->setFilter($filter);
52 // Build headpage
53 $headpage = new listing(get_template_path("user-list.xml", true));
54 $headpage->registerElementFilter("lockLabel", "userManagement::filterLockLabel");
55 $headpage->registerElementFilter("lockImage", "userManagement::filterLockImage");
56 $headpage->setFilter($filter);
58 // Add copy&paste and snapshot handler.
59 if ($this->config->boolValueIsTrue("main", "copyPaste")){
60 $this->cpHandler = new CopyPasteHandler($this->config);
61 }
62 if($this->config->get_cfg_value("enableSnapshots") == "true"){
63 $this->snapHandler = new SnapshotHandler($this->config);
64 }
66 parent::__construct($config, $ui, "users", $headpage);
68 $this->registerAction("new", "newEntry");
69 $this->registerAction("edit", "editEntry");
70 $this->registerAction("apply", "applyChanges");
71 $this->registerAction("save", "saveChanges");
72 $this->registerAction("cancel", "cancelEdit");
73 $this->registerAction("remove", "removeEntryRequested");
74 $this->registerAction("removeConfirmed", "removeEntryConfirmed");
76 $this->registerAction("copy", "copyPasteHandler");
77 $this->registerAction("cut", "copyPasteHandler");
78 $this->registerAction("paste", "copyPasteHandler");
80 // Register special user actions
81 $this->registerAction("lock", "lockEntry");
82 $this->registerAction("lockUsers", "lockUsers");
83 $this->registerAction("unlockUsers", "lockUsers");
84 $this->registerAction("new_template", "newTemplate");
85 $this->registerAction("newfromtpl", "newUserFromTemplate");
86 $this->registerAction("templateContinue", "templateContinue");
87 $this->registerAction("templatize", "templatizeUsers");
88 $this->registerAction("templatizeContinue", "templatizeContinue");
90 $this->registerAction("sendMessage", "sendMessage");
91 $this->registerAction("saveEventDialog", "saveEventDialog");
92 $this->registerAction("abortEventDialog", "closeDialogs");
93 }
96 // Inject user actions
97 function detectPostActions()
98 {
99 $action = management::detectPostActions();
100 if(isset($_POST['template_continue'])) $action['action'] = "templateContinue";
101 if(isset($_POST['templatize_continue'])) $action['action'] = "templatizeContinue";
102 if(isset($_POST['save_event_dialog'])) $action['action'] = "saveEventDialog";
103 if(isset($_POST['abort_event_dialog'])) $action['action'] = "abortEventDialog";
104 return($action);
105 }
108 /*! \brief Sends a message to a set of users using gosa-si events.
109 */
110 function sendMessage($action="",$target=array(),$all=array())
111 {
112 if(class_available("DaemonEvent")){
113 $uids = array();
114 $ldap = $this->config->get_ldap_link();
115 $ldap->cd($this->config->current['BASE']);
116 foreach($target as $dn){
117 $ldap->cat($dn,array('uid'));
118 $attrs = $ldap->fetch();
119 if(isset($attrs['uid'][0])){
120 $uids[] = $attrs['uid'][0];
121 }
122 }
123 if(count($uids)){
124 $events = DaemonEvent::get_event_types(USER_EVENT);
125 $event = "DaemonEvent_notify";
126 if(isset($events['BY_CLASS'][$event])){
127 $type = $events['BY_CLASS'][$event];
128 $this->dialogObject = new $type['CLASS_NAME']($this->config);
129 $this->dialogObject->add_users($uids);
130 $this->dialogObject->set_type(SCHEDULED_EVENT);
131 }
132 }
133 }
134 }
137 /*! \brief Sends a message to a set of users using gosa-si events.
138 */
139 function saveEventDialog()
140 {
141 $this->dialogObject->save_object();
142 $msgs = $this->dialogObject->check();
143 if(count($msgs)){
144 msg_dialog::displayChecks($msgs);
145 }else{
146 $o_queue = new gosaSupportDaemon();
147 $o_queue->append($this->dialogObject);
148 if($o_queue->is_error()){
149 msg_dialog::display(_("Infrastructure error"), msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
150 }
151 $this->closeDialogs();
152 }
153 }
156 /*! \brief Intiates template creation.
157 */
158 function newTemplate($action,$entry)
159 {
160 $this->newEntry();
161 $this->tabObject->set_template_mode ();
162 }
165 /*! \brief Intiates user creation.
166 * If we've user templates, then the user will be asked to use to use one.
167 * -> See 'templateContinue' for further handling.
168 */
169 function newUserFromTemplate($action="",$target=array(),$all=array())
170 {
171 // Call parent method, it knows whats to do, locking and so on ...
172 management::newEntry($action,$target,$all);
174 // Reset uid selection.
175 $this->got_uid= "";
177 // Use template if there are any of them
178 $templates = array();
179 $templates['none']= _("none");
180 $templates = array_merge($templates,$this->get_templates());
182 // We've templates, so preset the current template and display the input dialog.
183 if (count($templates)){
184 $smarty = get_smarty();
185 foreach(array("sn", "givenName", "uid", "got_uid") as $attr){
186 $smarty->assign("$attr", "");
187 }
188 $smarty->assign("template", array_pop($target));
189 $smarty->assign("templates", $templates);
190 $smarty->assign("edit_uid", "");
191 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
193 // -> See 'templateContinue' for further handling!
194 }
195 }
199 /*! \brief Intiates user creation.
200 * If we've user templates, then the user will be asked
201 * if he wants to use one.
202 * -> See 'templateContinue' for further handling.
203 */
204 function newEntry($action="",$target=array(),$all=array())
205 {
207 // Call parent method, it manages everything, locking, object creation...
208 management::newEntry($action,$target,$all);
210 // If we've at least one template, then ask the user if he wants to use one?
211 $templates = array();
212 $templates['none']= _("none");
213 $templates = array_merge($templates,$this->get_templates());
215 // Display template selection
216 if (count($templates)){
217 $smarty = get_smarty();
219 // Set default variables, normally empty.
220 foreach(array("sn", "givenName", "uid", "got_uid") as $attr){
221 $smarty->assign($attr, "");
222 }
223 $smarty->assign("template", "none");
224 $smarty->assign("templates", $templates);
225 $smarty->assign("edit_uid", "");
226 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
228 // -> See 'templateContinue' for further handling!
229 }
230 }
233 /* !\brief This method is called whenever a template selection was displayed.
234 * Here we act on the use selection.
235 * - Does the user want to create a user from template?
236 * - Create user without template?
237 * - Input correct, every value given and valid?
238 */
239 function templateContinue()
240 {
241 // Get the list of available templates.
242 $templates = array();
243 $templates['none']= _("none");
244 $templates = array_merge($templates,$this->get_templates());
246 // Input validation, if someone wants to create a user from a template
247 // then validate the given values.
248 $message = array();
249 if(!isset($_POST['template']) || (empty($_POST['template']))){
250 $message[]= msgPool::invalid(_("Template"));
251 }
252 if(!isset($_POST['sn']) || (empty($_POST['sn']))){
253 $message[]= msgPool::required(_("Name"));
254 }
255 if(!isset($_POST['givenName']) || (empty($_POST['givenName']))){
256 $message[]= msgPool::required(_("Given name"));
257 }
259 /********************
260 * 1 We've had input errors - Display errors and show input dialog again.
261 ********************/
263 if (count($message) > 0){
264 msg_dialog::displayChecks($message);
266 // Preset input fields with user input.
267 $smarty = get_smarty();
268 foreach(array("sn", "givenName", "uid", "template") as $attr){
269 if(isset($_POST[$attr])){
270 $smarty->assign("$attr", get_post($attr));
271 }else{
272 $smarty->assign("$attr", "");
273 }
274 }
276 $smarty->assign("templates",$templates);
277 $smarty->assign("got_uid", $this->got_uid);
278 $smarty->assign("edit_uid",false);
279 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
280 }
283 /********************
284 * 2 There was a template selected, now ask for the uid.
285 ********************/
287 if ($_POST['template'] != 'none' && !isset($_POST['uid'])){
289 // Remember user input.
290 $smarty = get_smarty();
291 $this->sn = $_POST['sn'];
292 $this->givenName = $_POST['givenName'];
294 // Avoid duplicate entries, check if such a user already exists.
295 $dn= preg_replace("/^[^,]+,/i", "", $_POST['template']);
296 $ldap= $this->config->get_ldap_link();
297 $ldap->cd ($dn);
298 $ldap->search ("(&(sn=".normalizeLdap($this->sn).")(givenName=".normalizeLdap($this->givenName)."))", array("givenName"));
299 if ($ldap->count () != 0){
300 msg_dialog::displayChecks(array(msgPool::duplicated(_("Name"))));
301 }else{
303 // Preset uid field by using the idGenerator
304 $attributes= array('sn' => $this->sn, 'givenName' => $this->givenName);
305 if ($this->config->get_cfg_value("idGenerator") != ""){
306 $uids= gen_uids ($this->config->get_cfg_value("idGenerator"), $attributes);
307 if (count($uids)){
308 $smarty->assign("edit_uid", "false");
309 $smarty->assign("uids", $uids);
310 $this->uid= current($uids);
311 }
312 } else {
313 $smarty->assign("edit_uid", "");
314 $this->uid= "";
315 }
316 $this->got_uid= true;
317 }
319 // Assign user input
320 foreach(array("sn", "givenName", "uid", "got_uid") as $attr){
321 $smarty->assign("$attr", $this->$attr);
322 }
323 if (isset($_POST['template'])){
324 $smarty->assign("template", $_POST['template']);
325 }
326 $smarty->assign("templates",$templates);
327 return($smarty->fetch(get_template_path('template.tpl', TRUE)));
328 }
331 /********************
332 * 3 No template - Ok. Lets fill the data into the user object and skip templating here.
333 ********************/
334 if ($_POST['template'] == 'none'){
335 foreach(array("sn", "givenName", "uid") as $attr){
336 if (isset($_POST[$attr])){
337 $this->tabObject->by_object['user']->$attr= $_POST[$attr];
338 }
339 }
341 // The user Tab object is already instantiated, so just go back and let the
342 // management class do the rest.
343 return("");
344 }
347 /********************
348 * 4 Template selected and uid given - Ok, then lets adapt tempalte values.
349 ********************/
350 if(isset($_POST['uid'])){
352 // Move user supplied data to sub plugins
353 foreach(array("uid","sn","givenName") as $attr){
354 $this->$attr = $_POST[$attr];
355 $this->tabObject->$attr = $this->$attr;
356 $this->tabObject->by_object['user']->$attr = $this->$attr;
357 }
359 // Adapt template values.
360 $template_dn = $_POST['template'];
361 $this->tabObject->adapt_from_template($template_dn, array("uid","cn","givenName","sn"));
362 $template_base = preg_replace("/^[^,]+,".preg_quote(get_people_ou(), '/')."/", '', $template_dn);
363 $this->tabObject->by_object['user']->base= $template_base;
365 // The user Tab object is already instantiated, so just go back and let the
366 // management class do the rest.
367 return("");
368 }
369 }
372 /* !\brief This method applies a template to a set of users.
373 */
374 function templatizeUsers($action="",$target=array(),$all=array())
375 {
376 $this->dns = array();
377 if(count($target)){
379 // Get the list of available templates.
380 $templates = $this->get_templates();
382 // Check entry locking
383 foreach($target as $dn){
384 if (($user= get_lock($dn)) != ""){
385 return(gen_locked_message ($user, $dn));
386 }
387 $this->dns[] = $dn;
388 }
390 // Display template
391 $smarty = get_smarty();
392 $smarty->assign("templates", $templates);
393 return($smarty->fetch(get_template_path('templatize.tpl', TRUE)));
394 }
395 }
398 /* !\brief This method is called whenever the templatize dialog was used.
399 */
400 function templatizeContinue()
401 {
402 // Template readable?
403 $template= get_post('template');
404 $acl = $this->ui->get_permissions($template, $this->aclCategory."/".$this->aclPlugin);
405 if (preg_match('/r/', $acl)){
406 $tab = $this->tabClass;
407 foreach ($this->dns as $dn){
409 // User writeable
410 $acl = $this->ui->get_permissions($dn, $this->aclCategory."/".$this->aclPlugin);
411 if (preg_match('/w/', $acl)){
412 $this->tabObject= new $tab($this->config, $this->config->data['TABS'][$this->tabType], $dn, $this->aclCategory);
413 $this->tabObject->adapt_from_template($template, array("sn", "givenName", "uid"));
414 $this->tabObject->save();
415 } else {
416 msg_dialog::display(_("Permission error"), msgPool::permModify($dn), ERROR_DIALOG);
417 }
418 }
419 } else {
420 msg_dialog::display(_("Permission error"), msgPool::permView($template), ERROR_DIALOG);
421 }
423 // Cleanup!
424 $this->remove_lock();
425 $this->closeDialogs();
426 }
429 /* !\brief Lock/unlock multiple users.
430 */
431 function lockUsers($action,$target,$all)
432 {
433 if($action == "lockUsers"){
434 $this->lockEntry($action,$target, $all, "lock");
435 }else{
436 $this->lockEntry($action,$target, $all, "unlock");
437 }
438 }
441 /* !\brief Locks/unlocks the given user(s).
442 */
443 function lockEntry($action,$entry, $all, $type = "toggle")
444 {
446 // Filter out entries we are not allowed to modify
447 $disallowed = array();
448 $dns = array();
449 foreach($entry as $dn){
450 if (!preg_match("/w/",$this->ui->get_permissions($dn,"users/password"))){
451 $disallowed[] = $dn;
452 }else{
453 $allowed[] = $dn;
454 }
455 }
456 if(count($disallowed)){
457 msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
458 }
460 // Try to lock/unlock the rest of the entries.
461 $ldap = $this->config->get_ldap_link();
462 foreach($allowed as $dn){
463 $ldap->cat($dn, array('userPassword'));
464 if($ldap->count() == 1){
466 // We can't lock empty passwords.
467 $val = $ldap->fetch();
468 if(!isset($val['userPassword'])){
469 continue;
470 }
472 // Detect the password method and try to lock/unlock.
473 $pwd = $val['userPassword'][0];
474 $method = passwordMethod::get_method($pwd,$val['dn']);
475 $success= true;
476 if($method instanceOf passwordMethod){
477 if($type == "toggle"){
478 if($method->is_locked($this->config,$val['dn'])){
479 $success= $method->unlock_account($this->config,$val['dn']);
480 }else{
481 $success= $method->lock_account($this->config,$val['dn']);
482 }
483 }elseif($type == "lock" && !$method->is_locked($this->config,$val['dn'])){
484 $success= $method->lock_account($this->config,$val['dn']);
485 }elseif($type == "unlock" && $method->is_locked($this->config,$val['dn'])){
486 $success= $method->unlock_account($this->config,$val['dn']);
487 }
489 // Check if everything went fine.
490 if (!$success){
491 $hn= $method->get_hash_name();
492 if (is_array($hn)){
493 $hn= $hn[0];
494 }
495 msg_dialog::display(_("Account locking"),
496 sprintf(_("Password method '%s' does not support locking. Account (%s) has not been locked!"),
497 $hn,$dn),WARNING_DIALOG);
498 }
499 }else{
500 // Can't lock unknown methods.
501 }
502 }
503 }
504 }
507 /* !\brief This method returns a list of all available templates.
508 */
509 function get_templates()
510 {
511 $templates= array();
512 $ldap= $this->config->get_ldap_link();
513 foreach ($this->config->departments as $key => $value){
514 $acl = $this->ui->get_permissions($value,$this->aclCategory."/".$this->aclPlugin);
515 if (preg_match("/c/",$acl)){
517 // Search all templates from the current dn.
518 $ldap->cd (get_people_ou().$value);
519 $ldap->search ("(objectClass=gosaUserTemplate)", array("uid"));
520 if ($ldap->count() != 0){
521 while ($attrs= $ldap->fetch()){
522 $templates[$ldap->getDN()]= $attrs['uid'][0]." - ".LDAP::fix($key);
523 }
524 }
525 }
526 }
527 natcasesort ($templates);
528 reset ($templates);
529 return($templates);
530 }
533 static function filterLockImage($userPassword)
534 {
535 $image= "images/empty.png";
536 if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
537 if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
538 $image= "images/lists/locked.png";
539 }else{
540 $image= "images/lists/unlocked.png";
541 }
542 }
543 return $image;
544 }
547 static function filterLockLabel($userPassword)
548 {
549 $label= "";
550 if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
551 if(preg_match("/^[^\}]*+\}!/",$userPassword[0])){
552 $label= _("Unlock account");
553 }else{
554 $label= _("Lock account");
555 }
556 }
557 return $label;
558 }
559 }
560 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
561 ?>