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