Code

6edbf93e3bcfe894cc280c43709f8e9be7538e53
[gosa.git] / gosa-core / plugins / personal / generic / class_user.inc
1 <?php
2 /*!
3   \brief   user 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 person, organizationalPerson, inetOrgPerson and gosaAccount
10   from/to the LDAP. It does syntax checking and displays the formulars required.
11  */
13 class user extends plugin
14 {
15   /* Definitions */
16   var $plHeadline= "Generic";
17   var $plDescription= "Edit organizational user settings";
19   /* Plugin specific values */
20   var $base= "";
21   var $orig_base= "";
22   var $cn= "";
23   var $new_dn= "";
24   var $personalTitle= "";
25   var $academicTitle= "";
26   var $homePostalAddress= "";
27   var $homePhone= "";
28   var $labeledURI= "";
29   var $o= "";
30   var $ou= "";
31   var $departmentNumber= "";
32   var $employeeNumber= "";
33   var $employeeType= "";
34   var $roomNumber= "";
35   var $telephoneNumber= "";
36   var $facsimileTelephoneNumber= "";
37   var $mobile= "";
38   var $pager= "";
39   var $l= "";
40   var $st= "";
41   var $postalAddress= "";
42   var $dateOfBirth;
43   var $use_dob= "0";
44   var $gender="0";
45   var $preferredLanguage="0";
47   var $jpegPhoto= "*removed*";
48   var $photoData= "";
49   var $old_jpegPhoto= "";
50   var $old_photoData= "";
51   var $cert_dialog= FALSE;
52   var $picture_dialog= FALSE;
53   var $pwObject= NULL;
55   var $userPKCS12= "";
56   var $userSMIMECertificate= "";
57   var $userCertificate= "";
58   var $certificateSerialNumber= "";
59   var $old_certificateSerialNumber= "";
60   var $old_userPKCS12= "";
61   var $old_userSMIMECertificate= "";
62   var $old_userCertificate= "";
64   var $gouvernmentOrganizationalUnit= "";
65   var $houseIdentifier= "";
66   var $street= "";
67   var $postalCode= "";
68   var $vocation= "";
69   var $ivbbLastDeliveryCollective= "";
70   var $gouvernmentOrganizationalPersonLocality= "";
71   var $gouvernmentOrganizationalUnitDescription= "";
72   var $gouvernmentOrganizationalUnitSubjectArea= "";
73   var $functionalTitle= "";
74   var $role= "";
75   var $publicVisible= "";
77   var $orig_dn;
78   var $dialog;
80   /* variables to trigger password changes */
81   var $pw_storage= "crypt";
82   var $last_pw_storage= "unset";
83   var $had_userCertificate= FALSE;
85   var $view_logged = FALSE;
87   /* attribute list for save action */
88   var $attributes= array("sn", "givenName", "uid", "personalTitle", "academicTitle",
89       "homePostalAddress", "homePhone", "labeledURI", "ou", "o", "dateOfBirth", "gender","preferredLanguage",
90       "departmentNumber", "employeeNumber", "employeeType", "l", "st","jpegPhoto",
91       "roomNumber", "telephoneNumber", "mobile", "pager", "cn", "userPKCS12",
92       "postalAddress", "facsimileTelephoneNumber", "userSMIMECertificate");
94   var $objectclasses= array("top", "person", "organizationalPerson", "inetOrgPerson",
95       "gosaAccount");
97   /* attributes that are part of the government mode */
98   var $govattrs= array("gouvernmentOrganizationalUnit", "houseIdentifier", "vocation",
99       "ivbbLastDeliveryCollective", "gouvernmentOrganizationalPersonLocality",
100       "gouvernmentOrganizationalUnitDescription","gouvernmentOrganizationalUnitSubjectArea",
101       "functionalTitle", "certificateSerialNumber", "publicVisible", "street", "role",
102       "postalCode");
104   var $multiple_support = TRUE;
106   /* constructor, if 'dn' is set, the node loads the given
107      'dn' from LDAP */
108   function user (&$config, $dn= NULL)
109   {
110     $this->config= $config;
111     /* Configuration is fine, allways */
112     if ($this->config->current['GOVERNMENTMODE']){
113       $this->attributes=array_merge($this->attributes,$this->govattrs);
114     }
116     /* Load base attributes */
117     plugin::plugin ($config, $dn);
119     $this->orig_dn  = $this->dn;
120     $this->new_dn   = $dn;
122     if ($this->config->current['GOVERNMENTMODE']){
123       /* Fix public visible attribute if unset */
124       if (!isset($this->attrs['publicVisible'])){
125         $this->publicVisible == "nein";
126       }
127     }
129     /* Load government mode attributes */
130     if ($this->config->current['GOVERNMENTMODE']){
131       /* Copy all attributs */
132       foreach ($this->govattrs as $val){
133         if (isset($this->attrs["$val"][0])){
134           $this->$val= $this->attrs["$val"][0];
135         }
136       }
137     }
139     /* Create me for new accounts */
140     if ($dn == "new"){
141       $this->is_account= TRUE;
142     }
144     /* Make hash default to md5 if not set in config */
145     if (!isset($this->config->current['HASH'])){
146       $hash= "md5";
147     } else {
148       $hash= $this->config->current['HASH'];
149     }
151     /* Load data from LDAP? */
152     if ($dn !== NULL){
154       /* Do base conversation */
155       if ($this->dn == "new"){
156         $ui= get_userinfo();
157         $this->base= dn2base($ui->dn);
158       } else {
159         $this->base= dn2base($dn);
160       }
162       /* get password storage type */
163       if (isset ($this->attrs['userPassword'][0])){
164         /* Initialize local array */
165         $matches= array();
166         if (preg_match ("/^{([^}]+)}(.+)/", $this->attrs['userPassword'][0], $matches)){
167           $this->pw_storage= strtolower($matches[1]);
168         } else {
169           if ($this->attrs['userPassword'][0] != ""){
170             $this->pw_storage= "clear";
171           } else {
172             $this->pw_storage= $hash;
173           }
174         }
175       } else {
176         /* Preset with vaule from configuration */
177         $this->pw_storage= $hash;
178       }
180       /* Load extra attributes: certificate and picture */
181       $this->load_cert();
182       $this->load_picture();
183       if ($this->userCertificate != ""){
184         $this->had_userCertificate= TRUE;
185       }
186     }
188     /* Reset password storage indicator, used by password_change_needed() */
189     if ($dn == "new"){
190       $this->last_pw_storage= "unset";
191     } else {
192       $this->last_pw_storage= $this->pw_storage;
193     }
195     /* Generate dateOfBirth entry */
196     if (isset ($this->attrs['dateOfBirth'])){
197       /* This entry is ISO 8601 conform */
198       list($year, $month, $day)= split("-", $this->attrs['dateOfBirth'][0], 3);
199     
200       $this->dateOfBirth=array( 'mon'=> $month,"mday"=> $day,"year"=> $year);
201       $this->use_dob= "1";
202     } else {
203       $this->use_dob= "0";
204     }
206     /* Put gender attribute to upper case */
207     if (isset ($this->attrs['gender'])){
208       $this->gender= strtoupper($this->attrs['gender'][0]);
209     }
210  
211     $this->orig_base = $this->base;
212   }
217   /* execute generates the html output for this node */
218   function execute()
219   {
220     /* Call parent execute */
221     plugin::execute();
223     /* Log view */
224     if($this->is_account && !$this->view_logged){
225       $this->view_logged = TRUE;
226       new log("view","users/".get_class($this),$this->dn);
227     }
229     $smarty= get_smarty();
231     /* Fill calendar */
232     if ($this->dateOfBirth == "0"){
233       $date= getdate();
234     } else {
235       if(is_array($this->dateOfBirth)){
236         $date = $this->dateOfBirth;
237   
238         // Trigger on dates like 1985-04-01, getdate only understands timestamps
239       } else if (!empty($this->dateOfBirth) && !is_numeric($this->dateOfBirth)){
240         $date= getdate(strtotime($this->dateOfBirth));
242       } else {
243         $date = getdate($this->dateOfBirth);
244       }
245     }
247     $days= array();
248     for($d= 1; $d<32; $d++){
249       $days[$d]= $d;
250     }
251     $years= array();
253     if(($date['year']-100)<1901){
254       $start = 1901;
255     }else{
256       $start = $date['year']-100;
257     }
259     $end = $start +100;
260     
261     for($y= $start; $y<=$end; $y++){
262       $years[]= $y;
263     }
264     $years['-']= "-&nbsp;";
265     $months= array(_("January"), _("February"), _("March"), _("April"),
266         _("May"), _("June"), _("July"), _("August"), _("September"),
267         _("October"), _("November"), _("December"), '-' => '-&nbsp;');
268     $smarty->assign("day", $date["mday"]);
269     $smarty->assign("days", $days);
270     $smarty->assign("months", $months);
271     $smarty->assign("month", $date["mon"]-1);
272     $smarty->assign("years", $years);
273     $smarty->assign("year", $date["year"]);
275     /* Assign sex */
276     $sex= array(0 => "&nbsp;", "F" => _("female"), "M" => _("male"));
277     $smarty->assign("gender_list", $sex);
278     $language= array_merge(array(0 => "&nbsp;") ,get_languages(TRUE));
279     $smarty->assign("preferredLanguage_list", $language);
281     /* Get random number for pictures */
282     srand((double)microtime()*1000000); 
283     $smarty->assign("rand", rand(0, 10000));
286     /* Do we represent a valid gosaAccount? */
287     if (!$this->is_account){
288       $str = "<img alt=\"\" src=\"images/stop.png\" align=\"middle\">&nbsp;<b>".
289         _("This account has no valid GOsa extensions.")."</b>";
290       return($str);
291     }
293     /* Base select dialog */
294     $once = true;
295     foreach($_POST as $name => $value){
296       if(preg_match("/^chooseBase/",$name) && $once){
297         $once = false;
298         $this->dialog = new baseSelectDialog($this->config,$this,$this->allowedBasesToMoveTo());
299         $this->dialog->setCurrentBase($this->base);
300       }
301     }
303     /* Password configure dialog handling */
304     if(is_object($this->pwObject) && $this->pwObject->display){
305       $output= $this->pwObject->configure();
306       if ($output != ""){
307         $this->dialog= TRUE;
308         return $output;
309       }
310       $this->dialog= false;
311     }
313     /* Dialog handling */
314     if(is_object($this->dialog)){
315       /* Must be called before save_object */
316       $this->dialog->save_object();
317    
318       if($this->dialog->isClosed()){
319         $this->dialog = false;
320       }elseif($this->dialog->isSelected()){
322         /* check if selected base is allowed to move to / create a new object */
323         $tmp = $this->get_allowed_bases();
324         if(isset($tmp[$this->dialog->isSelected()])){
325           $this->base = $this->dialog->isSelected();
326         }
327         $this->dialog= false;
328       }else{
329         return($this->dialog->execute());
330       }
331     }
333     /* Want password method editing? */
334     if ($this->acl_is_writeable("userPassword")){
335       if (isset($_POST['edit_pw_method'])){
336         if (!is_object($this->pwObject) || $this->pw_storage != $this->pwObject->get_hash_name()){
337           $temp= passwordMethod::get_available_methods();
338           $this->pwObject= new $temp[$this->pw_storage]($this->config,$this->dn);
339         }
340         $this->pwObject->display = TRUE;
341         $this->dialog= TRUE;
342         return ($this->pwObject->configure());
343       }
344     }
346     /* Want picture edit dialog? */
347     if($this->acl_is_writeable("userPicture")) {
348       if (isset($_POST['edit_picture'])){
349         /* Save values for later recovery, in case some presses
350            the cancel button. */
351         $this->old_jpegPhoto= $this->jpegPhoto;
352         $this->old_photoData= $this->photoData;
353         $this->picture_dialog= TRUE;
354         $this->dialog= TRUE;
355       }
356     }
358     /* Remove picture? */
359     if($this->acl_is_writeable("userPicture",(!is_object($this->parent) && !session::is_set('edit'))) ){
360       if (isset($_POST['picture_remove'])){
361         $this->set_picture ();
362         $this->jpegPhoto= "*removed*";
363         $this->is_modified= TRUE;
364         return($smarty->fetch (get_template_path('generic_picture.tpl', TRUE, dirname(__FILE__))));
365       }
366     }
368     /* Save picture */
369     if (isset($_POST['picture_edit_finish'])){
371       /* Check for clean upload */
372       if ($_FILES['picture_file']['name'] != ""){
373         if (!is_uploaded_file($_FILES['picture_file']['tmp_name'])) {
374           msg_dialog::display(_("Error"), _("Cannot upload file!"), ERROR_DIALOG);
375         }else{
376           /* Activate new picture */
377           $this->set_picture($_FILES['picture_file']['tmp_name']);
378         }
379       }
380       $this->picture_dialog= FALSE;
381       $this->dialog= FALSE;
382       $this->is_modified= TRUE;
383     }
386     /* Cancel picture */
387     if (isset($_POST['picture_edit_cancel'])){
389       /* Restore values */
390       $this->jpegPhoto= $this->old_jpegPhoto;
391       $this->photoData= $this->old_photoData;
393       /* Update picture */
394       session::set('binary',$this->photoData);
395       session::set('binarytype',"image/jpeg");
396       $this->picture_dialog= FALSE;
397       $this->dialog= FALSE;
398     }
400     /* Toggle dateOfBirth information */
401     if (isset($_POST['set_dob'])){
402       $this->use_dob= ($this->use_dob == "0")?"1":"0";
403     }
406     /* Want certificate= */
407     if ((isset($_POST['edit_cert'])) && $this->acl_is_readable("Certificate")){
409       /* Save original values for later reconstruction */
410       foreach (array("certificateSerialNumber", "userCertificate",
411             "userSMIMECertificate", "userPKCS12") as $val){
413         $oval= "old_$val";
414         $this->$oval= $this->$val;
415       }
417       $this->cert_dialog= TRUE;
418       $this->dialog= TRUE;
419     }
422     /* Cancel certificate dialog */
423     if (isset($_POST['cert_edit_cancel'])){
425       /* Restore original values in case of 'cancel' */
426       foreach (array("certificateSerialNumber", "userCertificate",
427             "userSMIMECertificate", "userPKCS12") as $val){
429         $oval= "old_$val";
430         $this->$val= $this->$oval;
431       }
432       $this->cert_dialog= FALSE;
433       $this->dialog= FALSE;
434     }
437     /* Remove certificate? */
438     if($this->acl_is_writeable("Certificate",(!is_object($this->parent) && !session::is_set('edit')))){ 
439       foreach (array ("userCertificate", "userSMIMECertificate", "userPKCS12") as $val){
440         if (isset($_POST["remove_$val"])){
442           /* Reset specified cert*/
443           $this->$val= "";
444           $this->is_modified= TRUE;
445         }
446       }
447     }
449     /* Upload new cert and close dialog? */     
450     if($this->acl_is_writeable("Certificate",(!is_object($this->parent) && !session::is_set('edit')))){ 
451       if (isset($_POST['cert_edit_finish'])){
453         /* for all certificates do */
454         foreach (array ("userCertificate", "userSMIMECertificate", "userPKCS12")
455             as $val){
457           /* Check for clean upload */
458           if (array_key_exists($val."_file", $_FILES) &&
459               array_key_exists('name', $_FILES[$val."_file"]) &&
460               $_FILES[$val."_file"]['name'] != "" &&
461               is_uploaded_file($_FILES[$val."_file"]['tmp_name'])) {
462             $this->set_cert("$val", $_FILES[$val."_file"]['tmp_name']);
463           }
464         }
466         /* Save serial number */
467         if (isset($_POST["certificateSerialNumber"]) &&
468             $_POST["certificateSerialNumber"] != ""){
470           if (!tests::is_id($_POST["certificateSerialNumber"])){
471             msg_dialog::display(_("Error"), _("Please enter a valid serial number!"), ERROR_DIALOG);
473             foreach(array("userCertificate", "userSMIMECertificate", "userPKCS12") as $cert){
474               if ($this->$cert != ""){
475                 $smarty->assign("$cert"."_state", "true");
476               } else {
477                 $smarty->assign("$cert"."_state", "");
478               }
479             }
480             return ($smarty->fetch (get_template_path('generic_certs.tpl', TRUE, dirname(__FILE__))));
481           }
483           $this->certificateSerialNumber= $_POST["certificateSerialNumber"];
484           $this->is_modified= TRUE;
485         }
487         $this->cert_dialog= FALSE;
488         $this->dialog= FALSE;
489       }
490     }
491     /* Display picture dialog */
492     if ($this->picture_dialog){
493       return($smarty->fetch (get_template_path('generic_picture.tpl', TRUE, dirname(__FILE__))));
494     }
496     /* Display cert dialog */
497     if ($this->cert_dialog){
498       $smarty->assign("CertificateACL",$this->getacl("Certificate",(!is_object($this->parent) && !session::is_set('edit'))));
499       $smarty->assign("Certificate_readable",$this->acl_is_readable("Certificate"));
501       foreach(array("userCertificate", "userSMIMECertificate", "userPKCS12") as $cert){
502         if ($this->$cert != ""){
503           /* import certificate */
504           $certificate = new certificate;
505           $certificate->import($this->$cert);
506       
507           /* Read out data*/
508           $timeto   = $certificate->getvalidto_date();
509           $timefrom = $certificate->getvalidfrom_date();
510          
511           
512           /* Additional info if start end time is '0' */
513           $add_str_info = "";
514           if($timeto == 0 && $timefrom == 0){
515             $add_str_info = "<br><i>"._("(Some types of certificates are currently not supported and may be displayed as 'invalid'.)")."</i>";
516           }
518           $str = "<table summary=\"\" border=0>
519                     <tr>
520                       <td style='vertical-align:top'>CN</td>
521                       <td>".preg_replace("/ /", "&nbsp;", $certificate->getname())."</td>
522                     </tr>
523                   </table><br>".
525                   sprintf(_("Certificate is valid from %s to %s and is currently %s."),
526                         "<b>".date('d M Y',$timefrom)."</b>",
527                         "<b>".date('d M Y',$timeto)."</b>",
528                         $certificate->isvalid()?"<b><font style='color:green'>"._("valid")."</font></b>":
529                                                 "<b><font style='color:red'>"._("invalid")."</font></b>").$add_str_info;
531           $smarty->assign($cert."info",$str);
532           $smarty->assign($cert."_state","true");
533         } else {
534           $smarty->assign($cert."info", "<i>"._("No certificate installed")."</i>");
535           $smarty->assign($cert."_state","");
536         }
537       }
538       $smarty->assign("governmentmode", "false");
539       return($smarty->fetch (get_template_path('generic_certs.tpl', TRUE, dirname(__FILE__))));
540     }
542     /* Prepare password hashes */
543     if ($this->pw_storage == ""){
544       $this->pw_storage= $this->config->current['HASH'];
545     }
547     $temp= passwordMethod::get_available_methods();
548     $is_configurable= FALSE;
549     $hashes = $temp['name'];
550     if(isset($temp[$this->pw_storage])){
551       $test= new $temp[$this->pw_storage]($this->config);
552       $is_configurable= $test->is_configurable();
553     }else{
554       new msg_dialog(_("Password method"),_("The selected password method is no longer available."),WARNING_DIALOG);
555     }
556     
557     /* Load attributes and acl's */
558     $ui =get_userinfo();
559     foreach($this->attributes as $val){
560       $smarty->assign("$val", $this->$val);
561       if(in_array($val,$this->multi_boxes)){
562         $smarty->assign("use_".$val,TRUE);
563       }else{
564         $smarty->assign("use_".$val,FALSE);
565       }
566     }
567     foreach(array("base","pw_storage","edit_picture") as $val){
568       if(in_array($val,$this->multi_boxes)){
569         $smarty->assign("use_".$val,TRUE);
570       }else{
571         $smarty->assign("use_".$val,FALSE);
572       }
573     }
575     /* Set acls */
576     $tmp = $this->plinfo();
577     foreach($tmp['plProvidedAcls'] as $val => $translation){
578       $smarty->assign("$val"."ACL", $this->getacl($val,(!is_object($this->parent) && !session::is_set('edit'))));
579     }
581     $smarty->assign("pwmode", $hashes);
582     $smarty->assign("pwmode_select", $this->pw_storage);
583     $smarty->assign("pw_configurable", $is_configurable);
584     $smarty->assign("passwordStorageACL", $this->getacl("userPassword",(!is_object($this->parent) && !session::is_set('edit'))));
585     $smarty->assign("base_select",      $this->base);
586     $smarty->assign("CertificatesACL",  $this->getacl("Certificate",(!is_object($this->parent) && !session::is_set('edit'))));
587     $smarty->assign("userPictureACL",   $this->getacl("userPicture",(!is_object($this->parent) && !session::is_set('edit'))));
588     $smarty->assign("userPicture_is_readable",   $this->acl_is_readable("userPicture",(!is_object($this->parent) && !session::is_set('edit'))));
590     /* Create base acls */
591     $tmp = @$this->allowedBasesToMoveTo();
592     $smarty->assign("bases", $tmp);
594     /* Save government mode attributes */
595     if (isset($this->config->current['GOVERNMENTMODE']) &&
596         preg_match('/true/i', $this->config->current['GOVERNMENTMODE'])){
597       $smarty->assign("governmentmode", "true");
598       $ivbbmodes= array("nein", "ivbv", "testa", "ivbv,testa", "internet",
599           "internet,ivbv", "internet,testa", "internet,ivbv,testa");
600       $smarty->assign("ivbbmodes", $ivbbmodes);
601       foreach ($this->govattrs as $val){
602         $smarty->assign("$val", $this->$val);
603         $smarty->assign("$val"."ACL", $this->getacl($val,(!is_object($this->parent) && !session::is_set('edit'))));
604       }
605     } else {
606       $smarty->assign("governmentmode", "false");
607     }
609     /* Special mode for uid */
610     $uidACL= $this->getacl("uid",(!is_object($this->parent) && !session::is_set('edit')));
611     if (isset ($this->dn)){
612       if ($this->dn != "new"){
613         $uidACL= preg_replace("/w/","",$uidACL);
614       }
615     }  else {
616       $uidACL= preg_replace("/w/","",$uidACL);
617     }
618     
619     $smarty->assign("uidACL", $uidACL);
620     $smarty->assign("is_template", $this->is_template);
621     $smarty->assign("use_dob", $this->use_dob);
623     if (isset($this->parent)){
624       if (isset($this->parent->by_object['phoneAccount']) &&
625           $this->parent->by_object['phoneAccount']->is_account){
626         $smarty->assign("has_phoneaccount", "true");
627       } else {
628         $smarty->assign("has_phoneaccount", "false");
629       }
630     } else {
631       $smarty->assign("has_phoneaccount", "false");
632     }
633     $smarty->assign("multiple_support" , $this->multiple_support_active);
634     return($smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__))));
635   }
638   /* remove object from parent */
639   function remove_from_parent()
640   {
641     /* Remove password extension */
642     $temp= passwordMethod::get_available_methods();
643     $this->pwObject= new $temp[$this->pw_storage]($this->config,$this->dn);
644     $this->pwObject->remove_from_parent();
646     /* Remove user */
647     $ldap= $this->config->get_ldap_link();
648     $ldap->rmdir ($this->dn);
649     show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/generic account with dn '%s' failed."),$this->dn));
650   
651     new log("remove","users/".get_class($this),$this->dn,$this->attributes,$ldap->get_error());
652   
653     /* Delete references to groups */
654     $ldap->cd ($this->config->current['BASE']);
655     $ldap->search ("(&(objectClass=posixGroup)(memberUid=".$this->uid."))", array("uid"));
656     while ($ldap->fetch()){
657       $g= new group($this->config, $ldap->getDN());
658       $g->removeUser($this->uid);
659       $g->save ();
660     }
662     /* Delete references to object groups */
663     $ldap->cd ($this->config->current['BASE']);
664     $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
665     while ($ldap->fetch()){
666       $og= new ogroup($this->config, $ldap->getDN());
667       unset($og->member[$this->dn]);
668       $og->save ();
669     }
671     /* If needed, let the password method do some cleanup */
672     $tmp = new passwordMethod($this->config);
673     $available = $tmp->get_available_methods();
674     if (in_array_ics($this->pw_storage, $available['name'])){
675       $test= new $available[$this->pw_storage]($this->config);
676       $test->attrs= $this->attrs;
677       $test->dn= $this->dn;
678       $test->remove_from_parent();
679     }
681     /* Remove ACL dependencies too */
682     $tmp = new acl($this->config,$this->parent,$this->dn);
683     $tmp->remove_acl();
685     /* Optionally execute a command after we're done */
686     $this->handle_post_events("remove",array("uid" => $this->uid));
687   }
690   /* Save data to object */
691   function save_object()
692   {
693     if(isset($_POST['generic']) || isset($_POST['multiple_user_posted'])){
695       /* Make a backup of the current selected base */
696       $base_tmp = $this->base;
698       /* Parents save function */
699       plugin::save_object ();
701       /* Save government mode attributes */
702       if ($this->config->current['GOVERNMENTMODE']){
703         foreach ($this->govattrs as $val){
704           if ($this->acl_is_writeable($val,(!is_object($this->parent) && !session::is_set('edit'))) && isset($_POST["$val"])){
705             $data= stripcslashes($_POST["$val"]);
706             if ($data != $this->$val){
707               $this->is_modified= TRUE;
708             }
709             $this->$val= $data;
710           }
711         }
712       }
714       /* In template mode, the uid is autogenerated... */
715       if ($this->is_template){
716         $this->uid= strtolower($this->sn);
717         $this->givenName= $this->sn;
718       }
720       /* Save base and pw_storage, since these are no LDAP attributes */
721       if (isset($_POST['base'])){
723         $tmp = $this->get_allowed_bases();
724         if(isset($tmp[$_POST['base']])){
725           $base= validate($_POST['base']);
726           if ($base != $this->base){
727             $this->is_modified= TRUE;
728           }
729           $this->base= $base;
730         }else{
731           $this->base = $base_tmp;
732           msg_dialog::display(_("Error"), sprintf(_("You have no permission to move this object to '%s'!"), LDAP::fix($_POST['base'])), ERROR_DIALOG);
733           $this->set_acl_base('dummy,'.$this->base);
734         }
735       }
737       /* Get pw_storage mode */
738       if (isset($_POST['pw_storage'])){
739         foreach(array("pw_storage") as $val){
740           if(isset($_POST[$val])){
741             $data= validate($_POST[$val]);
742             if ($data != $this->$val){
743               $this->is_modified= TRUE;
744             }
745             $this->$val= $data;
746           }
747         }
748       }
750       $this->set_acl_base('dummy,'.$this->base);
751     }
752   }
754   function rebind($ldap, $referral)
755   {
756     $credentials= LDAP::get_credentials($referral, $this->config->current['REFERRAL']);
757     if (ldap_bind($ldap, $credentials['ADMIN'], $credentials['PASSWORD'])) {
758       $this->error = "Success";
759       $this->hascon=true;
760       $this->reconnect= true;
761       return (0);
762     } else {
763       $this->error = "Could not bind to " . $credentials['ADMIN'];
764       return NULL;
765     }
766   }
768   
769   /* Save data to LDAP, depending on is_account we save or delete */
770   function save()
771   {
772     /* Only force save of changes .... 
773        If this attributes aren't changed, avoid saving.
774      */
775     if($this->gender=="0") $this->gender ="";
776     if($this->preferredLanguage=="0") $this->preferredLanguage ="";
778     /* First use parents methods to do some basic fillup in $this->attrs */
779     plugin::save ();
781     if ($this->use_dob == "1"){
782       /* If it is an array, the generic page has never been loaded - so there's no difference. Using an array would cause an error btw. */
783       if(!is_array($this->attrs['dateOfBirth'])) {
784         $this->attrs['dateOfBirth'] = date("Y-m-d", $this->dateOfBirth);
785       }
786     }
788     /* Remove additional objectClasses */
789     $tmp= array();
790     foreach ($this->attrs['objectClass'] as $key => $set){
791       $found= false;
792       foreach (array("ivbbentry", "gosaUserTemplate") as $val){
793         if (preg_match ("/^$set$/i", $val)){
794           $found= true;
795           break;
796         }
797       }
798       if (!$found){
799         $tmp[]= $set;
800       }
801     }
803     /* Replace the objectClass array. This is done because of the
804        separation into government and normal mode. */
805     $this->attrs['objectClass']= $tmp;
807     /* Add objectClasss for template mode? */
808     if ($this->is_template){
809       $this->attrs['objectClass'][]= "gosaUserTemplate";
810     }
812     /* Hard coded government mode? */
813     if ($this->config->current['GOVERNMENTMODE'] != 'false'){
814       $this->attrs['objectClass'][]= "ivbbentry";
816       /* Copy standard attributes */
817       foreach ($this->govattrs as $val){
818         if ($this->$val != ""){
819           $this->attrs["$val"]= $this->$val;
820         } elseif (!$this->is_new) {
821           $this->attrs["$val"]= array();
822         }
823       }
825       /* Remove attribute if set to "nein" */
826       if ($this->publicVisible == "nein"){
827         $this->attrs['publicVisible']= array();
828         if($this->is_new){
829           unset($this->attrs['publicVisible']);
830         }else{
831           $this->attrs['publicVisible']=array();
832         }
834       }
836     }
838     /* Special handling for attribute userCertificate needed */
839     if ($this->userCertificate != ""){
840       $this->attrs["userCertificate;binary"]= $this->userCertificate;
841       $remove_userCertificate= false;
842     } else {
843       $remove_userCertificate= true;
844     }
846     /* Special handling for dateOfBirth value */
847     if ($this->use_dob != "1"){
848       if ($this->is_new) {
849         unset($this->attrs["dateOfBirth"]);
850       } else {
851         $this->attrs["dateOfBirth"]= array();
852       }
853     }
854     if (!$this->gender){
855       if ($this->is_new) {
856         unset($this->attrs["gender"]);
857       } else {
858         $this->attrs["gender"]= array();
859       }
860     }
861     if (!$this->preferredLanguage){
862       if ($this->is_new) {
863         unset($this->attrs["preferredLanguage"]);
864       } else {
865         $this->attrs["preferredLanguage"]= array();
866       }
867     }
869     /* Special handling for attribute jpegPhote needed, scale image via
870        image magick to 147x200 pixels and inject resulting data. */
871     if ($this->jpegPhoto == "*removed*"){
872     
873       /* Reset attribute to avoid writing *removed* as value */    
874       $this->attrs["jpegPhoto"] = array();
876     } else {
878       /* Fallback if there's no image magick inside PHP */
879       if (!function_exists("imagick_blob2image")){
880         /* Get temporary file name for conversation */
881         $fname = tempnam ("/tmp", "GOsa");
882   
883         /* Open file and write out photoData */
884         $fp = fopen ($fname, "w");
885         fwrite ($fp, $this->photoData);
886         fclose ($fp);
888         /* Build conversation query. Filename is generated automatically, so
889            we do not need any special security checks. Exec command and save
890            output. For PHP safe mode, you'll need a configuration which respects
891            image magick as executable... */
892         $query= "convert -size 147x200 $fname -resize 147x200 +profile \"*\" -";
893         @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
894             $query, "Execute");
895   
896         /* Read data written by convert */
897         $output= "";
898         $sh= popen($query, 'r');
899         while (!feof($sh)){
900           $output.= fread($sh, 4096);
901         }
902         pclose($sh);
904         unlink($fname);
906         /* Save attribute */
907         $this->attrs["jpegPhoto"] = $output;
909       } else {
911         /* Load the new uploaded Photo */
912         if(!$handle  =  imagick_blob2image($this->photoData))  {
913           new log("debug","users/".get_class($this),$this->dn,array(),"Could not access uploaded image");
914         }
916         /* Resizing image to 147x200 and blur */
917         if(!imagick_resize($handle,147,200,IMAGICK_FILTER_GAUSSIAN,0)){
918           new log("debug","users/".get_class($this),$this->dn,array(),"Could not resize uploaded image");
919         }
921         /* Converting image to JPEG */
922         if(!imagick_convert($handle,"JPEG")) {
923           new log("debug","users/".get_class($this),$this->dn,array(),"Could not convert uploaded image to jepg");
924         }
926         /* Creating binary Code for the Image */
927         if(!$dump = imagick_image2blob($handle)){
928           new log("debug","users/".get_class($this),$this->dn,array(),"Could not create new user image");
929         }
931         /* Sending Image */
932         $output=  $dump;
934         /* Save attribute */
935         $this->attrs["jpegPhoto"] = $output;
936       }
938     }
940     /* This only gets called when user is renaming himself */
941     $ldap= $this->config->get_ldap_link();
942     if ($this->dn != $this->new_dn){
944       /* Write entry on new 'dn' */
945       $this->update_acls($this->dn,$this->new_dn);
946       $this->move($this->dn, $this->new_dn);
948       /* Happen to use the new one */
949       change_ui_dn($this->dn, $this->new_dn);
950       $this->dn= $this->new_dn;
951     }
954     /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
955        new entries. So do a check first... */
956     $ldap->cat ($this->dn, array('dn'));
957     if ($ldap->fetch()){
958       $mode= "modify";
959     } else {
960       $mode= "add";
961       $ldap->cd($this->config->current['BASE']);
962       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
963     }
965     /* Set password to some junk stuff in case of templates */
966     if ($this->is_template){
967       $this->attrs['userPassword']= '{crypt}N0T$3T4N0W';
968     }
970     @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,
971         $this->attributes, "Save via $mode");
973     /* Finally write data with selected 'mode' */
974     $this->cleanup();
976     if(isset($this->attrs['preferredLanguage'])){
977       $ui = session::get('ui');
978       $ui->language = $this->preferredLanguage;
979       session::set('ui',$ui);
980       session::set('Last_init_lang',"update");
981     }
983     $ldap->cd ($this->dn);
984     $ldap->$mode ($this->attrs);
985     if (show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/generic account with dn '%s' failed."),$this->dn))){
986       return (1);
987     }
989     /* Remove ACL dependencies too */
990     if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
991       $tmp = new acl($this->config,$this->parent,$this->dn);
992       $tmp->update_acl_membership($this->orig_dn,$this->dn);
993     }
995     if($mode == "modify"){
996       new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
997     }else{
998       new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
999     }
1001     /* Remove cert? 
1002        For some reason, the 'ldap' class doesn't want to remove binary entries, so I need
1003        to work around myself. */
1004     if ($remove_userCertificate == true && !$this->is_new && $this->had_userCertificate){
1006       /* Reset array, assemble new, this should be reworked */
1007       $this->attrs= array();
1008       $this->attrs['userCertificate;binary']= array();
1010       /* Prepare connection */
1011       if (!($ds = ldap_connect($this->config->current['SERVER']))) {
1012         die ("Could not connect to LDAP server");
1013       }
1014       ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
1015       if (function_exists("ldap_set_rebind_proc") && isset($this->config->current['RECURSIVE']) && $this->config->current['RECURSIVE'] == "true") {
1016         ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1);
1017         ldap_set_rebind_proc($ds, array(&$this, "rebind"));
1018       }
1019       if(isset($config->current['TLS']) && $config->current['TLS'] == "true"){
1020         ldap_start_tls($ds);
1021       }
1022       if (!($res = @ldap_bind($ds, $this->config->current['ADMIN'],
1023               $this->config->current['PASSWORD']))) {
1024         die ("Could not bind to LDAP");
1025       }
1027       /* Modify using attrs */
1028       ldap_mod_del($ds,$this->dn,$this->attrs);
1029       ldap_close($ds);
1030     }
1032     /* If needed, let the password method do some cleanup */
1033     if ($this->pw_storage != $this->last_pw_storage){
1034       $tmp = new passwordMethod($this->config);
1035       $available = $tmp->get_available_methods();
1036       if (in_array_ics($this->last_pw_storage, $available['name'])){
1037         $test= new $available[$this->last_pw_storage]($this->config,$this->dn);
1038         $test->attrs= $this->attrs;
1039         $test->remove_from_parent();
1040       }
1041     }
1043     /* Maybe the current password method want's to do some changes... */
1044     if (is_object($this->pwObject)){
1045       $this->pwObject->save($this->dn);
1046     }
1048     /* Optionally execute a command after we're done */
1049     if ($mode == "add"){
1050       $this->handle_post_events("add", array("uid" => $this->uid));
1051     } elseif ($this->is_modified){
1052       $this->handle_post_events("modify", array("uid" => $this->uid));
1053     }
1055     return (0);
1056   }
1058   
1059   function update_new_dn()
1060   {
1061     $pt= "";
1062     if(isset($this->config->current['INCLUDE_PERSONAL_TITLE']) && preg_match("/true/i",$this->config->current['INCLUDE_PERSONAL_TITLE'])){
1063       if(!empty($this->personalTitle)){
1064         $pt = $this->personalTitle." ";
1065       }
1066     }
1067     $this->cn= $pt.$this->givenName." ".$this->sn;
1069     /* Permissions for that base? */
1070     if (isset($this->config->current['DNMODE']) && $this->config->current['DNMODE'] == "uid"){
1071       $this->new_dn= 'uid='.$this->uid.','.get_people_ou().$this->base;
1072     } else {
1073       /* Don't touch dn, if cn hasn't changed */
1074       if (isset($this->saved_attributes['cn']) && $this->saved_attributes['cn'] == $this->cn &&
1075           $this->orig_base == $this->base ){
1076         $this->new_dn= $this->dn;
1077       } else {
1078         $this->new_dn= $this->create_unique_dn('cn', get_people_ou().$this->base);
1079       }
1080     }
1081   }
1082   
1084   /* Check formular input */
1085   function check()
1086   {
1087     /* Call common method to give check the hook */
1088     $message= plugin::check();
1090     $this->update_new_dn();
1092     /* Set the new acl base */
1093     if($this->dn == "new") {
1094       $this->set_acl_base($this->base);
1095     }
1097     /* UID already used? */
1098     $ldap= $this->config->get_ldap_link();
1099     $ldap->cd($this->config->current['BASE']);
1100     $ldap->search("(uid=$this->uid)", array("uid"));
1101     $ldap->fetch();
1102     if ($ldap->count() != 0 && $this->dn == 'new'){
1103       $message[]= _("There's already a person with this 'Login' in the database.");
1104     }
1106     /* In template mode, the uid and givenName are autogenerated... */
1107     if (!$this->is_template){
1108       if ($this->sn == ""){
1109         $message[]= msgPool::required(_("Name"));
1110       }
1111       if ($this->givenName == ""){
1112         $message[]= msgPool::required(_("Given name"));
1113       }
1114       if ($this->uid == ""){
1115         $message[]= msgPool::required(_("Login"));
1116       }
1117       if (!(isset($this->config->current['DNMODE']) && $this->config->current['DNMODE'] == "uid")){
1118         $ldap->cat($this->new_dn);
1119         if ($ldap->count() != 0 && $this->dn != $this->new_dn && $this->dn == 'new'){
1120           $message[]= msgPool::duplicated("cn=".$this->cn);
1121         }
1122       }
1123     }
1125     /* Check for valid input */
1126     if ($this->is_modified && !tests::is_uid($this->uid)){
1128       if (strict_uid_mode()){
1129         $message[]= msgPool::invalid(_("Login"), $this->uid, "/[a-z0-9_-]/");
1130       } else {
1131         $message[]= msgPool::invalid(_("Login"), $this->uid, "/[a-z0-9_-]/i");
1132       }
1133     }
1134     if (!tests::is_url($this->labeledURI)){
1135       $message[]= msgPool::invalid(_("Homepage"), "", "", "http://www.example.com/yourname");
1136     }
1138     /* Check phone numbers */
1139     if (!tests::is_phone_nr($this->telephoneNumber)){
1140       $message[]= msgPool::invalid(_("Phone"), $this->telephoneNumber, "/[\/0-9 ()+*-]/");
1141     }
1142     if (!tests::is_phone_nr($this->facsimileTelephoneNumber)){
1143       $message[]= msgPool::invalid(_("Fax"), $this->facsimileTelephoneNumber, "/[\/0-9 ()+*-]/");
1144     }
1145     if (!tests::is_phone_nr($this->mobile)){
1146       $message[]= msgPool::invalid(_("Mobile"), $this->mobile, "/[\/0-9 ()+*-]/");
1147     }
1148     if (!tests::is_phone_nr($this->pager)){
1149       $message[]= msgPool::invalid(_("Pager"), $this->pager, "/[\/0-9 ()+*-]/");
1150     }
1152     /* Check for reserved characers */
1153     if (preg_match ('/[,+"?\'()=<>;\\\\]/', $this->givenName)){
1154       $message[]= msgPool::invalid(_("Given name"), $this->givenName, '/[^,+"?\'()=<>;\\\\]/');
1155     }
1156     if (preg_match ('/[,+"?\'()=<>;\\\\]/', $this->sn)){
1157       $message[]= msgPool::invalid(_("Name"), $this->sn, '/[^,+"?\'()=<>;\\\\]/');
1158     }
1160     return $message;
1161   }
1164   /* Indicate whether a password change is needed or not */
1165   function password_change_needed()
1166   {
1167     if(in_array("pw_storage",$this->multi_boxes)){
1168       return(TRUE);
1169     }
1170     return($this->pw_storage != $this->last_pw_storage);
1171   }
1174   /* Load a jpegPhoto from LDAP, this is going to be simplified later on */
1175   function load_picture()
1176   {
1177     $ldap = $this->config->get_ldap_link();
1178     $ldap->cd ($this->dn);
1179     $data = $ldap->get_attribute($this->dn,"jpegPhoto");
1181     if((!$data) || ($data == "*removed*")){ 
1183       /* In case we don't get an entry, load a default picture */
1184       $this->set_picture ();//"./images/default.jpg");
1185       $this->jpegPhoto= "*removed*";
1186     }else{
1188       /* Set picture */
1189       $this->photoData= $data;
1190       session::set('binary',$this->photoData);
1191       session::set('binarytype',"image/jpeg");
1192       $this->jpegPhoto= "";
1193     }
1194   }
1197   /* Load a certificate from LDAP, this is going to be simplified later on */
1198   function load_cert()
1199   {
1200     $ds= ldap_connect($this->config->current['SERVER']);
1201     ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
1202     if (function_exists("ldap_set_rebind_proc") && isset($this->config->current['RECURSIVE']) && $this->config->current['RECURSIVE'] == "true") {
1203       ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1);
1204       ldap_set_rebind_proc($ds, array(&$this, "rebind"));
1205     }
1206     if(isset($this->config->current['TLS']) &&
1207         $this->config->current['TLS'] == "true"){
1209       ldap_start_tls($ds);
1210     }
1212     $r= ldap_bind($ds);
1213     $sr= @ldap_read($ds, $this->dn, "userCertificate=*", array("userCertificate"));
1215     if ($sr) {
1216       $ei= @ldap_first_entry($ds, $sr);
1217       
1218       if ($ei) {
1219         if (!$info = @ldap_get_values_len($ds, $ei, "userCertificate;binary")){
1220           $this->userCertificate= "";
1221         } else {
1222           $this->userCertificate= $info[0];
1223         }
1224       }
1225     } else {
1226       $this->userCertificate= "";
1227     }
1229     ldap_unbind($ds);
1230   }
1233   /* Load picture from file to object */
1234   function set_picture($filename ="")
1235   {
1236     if (!is_file($filename) || $filename =="" ){
1237       $filename= "./images/default.jpg";
1238       $this->jpegPhoto= "*removed*";
1239     }
1241     $fd = fopen ($filename, "rb");
1242     $this->photoData= fread ($fd, filesize ($filename));
1243     session::set('binary',$this->photoData);
1244     session::set('binarytype',"image/jpeg");
1245     $this->jpegPhoto= "";
1247     fclose ($fd);
1248   }
1251   /* Load certificate from file to object */
1252   function set_cert($cert, $filename)
1253   {
1254     if(!$thsi->acl_is_writeable("Certificate",(!is_object($this->parent) && !session::is_set('edit')))) return;
1255     $fd = fopen ($filename, "rb");
1256     if (filesize($filename)>0) {
1257       $this->$cert= fread ($fd, filesize ($filename));
1258       fclose ($fd);
1259       $this->is_modified= TRUE;
1260     } else {
1261       msg_dialog::display(_("Error"), _("Cannot open certificate!"), ERROR_DIALOG);
1262     }
1263   }
1265   /* Adapt from given 'dn' */
1266   function adapt_from_template($dn)
1267   {
1268     plugin::adapt_from_template($dn);
1270     /* Get base */
1271     $this->base= preg_replace('/^[^,]+,'.get_people_ou().'/i', '', $dn);
1273     if ($this->config->current['GOVERNMENTMODE']){
1275       /* Walk through govattrs */
1276       foreach ($this->govattrs as $val){
1278         if (isset($this->attrs["$val"][0])){
1280           /* If attribute is set, replace dynamic parts: 
1281              %sn, %givenName and %uid. Fill these in our local variables. */
1282           $value= $this->attrs["$val"][0];
1284           foreach (array("sn", "givenName", "uid") as $repl){
1285             if (preg_match("/%$repl/i", $value)){
1286               $value= preg_replace ("/%$repl/i",
1287                   $this->parent->$repl, $value);
1288             }
1289           }
1290           $this->$val= $value;
1291         }
1292       }
1293     }
1295     /* Get back uid/sn/givenName */
1296     if ($this->parent !== NULL){
1297       $this->uid= $this->parent->uid;
1298       $this->sn= $this->parent->sn;
1299       $this->givenName= $this->parent->givenName;
1300     }
1301   }
1303  
1304   /* This avoids that users move themselves out of their rights. 
1305    */
1306   function allowedBasesToMoveTo()
1307   {
1308     /* Get bases */
1309     $bases  = $this->get_allowed_bases();
1310     return($bases);
1311   } 
1314   function getCopyDialog()
1315   {
1316     $str = "";
1318     session::set('binary',$this->photoData); 
1319     session::set('binarytype',"image/jpeg");
1321     /* Get random number for pictures */
1322     srand((double)microtime()*1000000); 
1323     $rand = rand(0, 10000);
1325     $smarty = get_smarty();
1327     $smarty->assign("passwordTodo","clear");
1329     if(isset($_POST['passwordTodo'])){
1330       $smarty->assign("passwordTodo",$_POST['passwordTodo']);
1331     }
1333     $smarty->assign("sn",       $this->sn);
1334     $smarty->assign("givenName",$this->givenName);
1335     $smarty->assign("uid",      $this->uid);
1336     $smarty->assign("rand",     $rand);
1337     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE,dirname(__FILE__)));
1340     $ret = array();
1341     $ret['string'] = $str;
1342     $ret['status'] = "";  
1343     return($ret);
1344   }
1346   function saveCopyDialog()
1347   {
1348     /* Set_acl_base */
1349     $this->set_acl_base("cn=dummy,".get_people_ou().$this->base);
1351     if((isset($_FILES['picture_file']['tmp_name'])) && ($_FILES['picture_file']['size'] > 0)){
1352       $this->set_picture($_FILES['picture_file']['tmp_name']);
1353     }
1355     /* Remove picture? */
1356     if (isset($_POST['picture_remove'])){
1357       $this->jpegPhoto= "*removed*";
1358       $this->set_picture ("./images/default.jpg");
1359       $this->is_modified= TRUE;
1360     }
1362     $attrs = array("uid","givenName","sn");
1363     foreach($attrs as $attr){
1364       if(isset($_POST[$attr])){
1365         $this->$attr = $_POST[$attr];
1366       }
1367     } 
1368   }
1371   function PrepareForCopyPaste($source)
1372   {
1373     plugin::PrepareForCopyPaste($source);
1375     /* Reset certificate information addepted from source user
1376        to avoid setting the same user certificate for the destination user. */
1377     $this->userPKCS12= "";
1378     $this->userSMIMECertificate= "";
1379     $this->userCertificate= "";
1380     $this->certificateSerialNumber= "";
1381     $this->old_certificateSerialNumber= "";
1382     $this->old_userPKCS12= "";
1383     $this->old_userSMIMECertificate= "";
1384     $this->old_userCertificate= "";
1385   }
1388   static function plInfo()
1389   {
1390   
1391     $govattrs= array(
1392         "gouvernmentOrganizationalUnit"             =>  _("Unit"), 
1393         "houseIdentifier"                           =>  _("House identifier"), 
1394         "vocation"                                  =>  _("Vocation"),
1395         "ivbbLastDeliveryCollective"                =>  _("Last delivery"), 
1396         "gouvernmentOrganizationalPersonLocality"   =>  _("Person locality"),
1397         "gouvernmentOrganizationalUnitDescription"  =>  _("Unit description"),
1398         "gouvernmentOrganizationalUnitSubjectArea"  =>  _("Subject area"),
1399         "functionalTitle"                           =>  _("Functional title"),
1400         "certificateSerialNumber"                   =>  _("Certificate serial number"),
1401         "publicVisible"                             =>  _("Public visible"),
1402         "street"                                    =>  _("Street"),
1403         "role"                                      =>  _("Role"),
1404         "postalCode"                                =>  _("Postal code"));
1406     $ret = array(
1407         "plShortName" => _("Generic"),
1408         "plDescription" => _("Generic user settings"),
1409         "plSelfModify"  => TRUE,
1410         "plDepends"     => array(),
1411         "plPriority"    => 1,
1412         "plSection"     => array("personal" => _("My account")),
1413         "plCategory"    => array("users" => array("description" => _("Users"),
1414                                                   "objectClass" => "gosaAccount")),
1416         "plProvidedAcls" => array(
1417           "base"              => _("Base"), 
1418           "userPassword"      => _("User password"), 
1419           "sn"                => _("Surename"),
1420           "givenName"         => _("Given name"),
1421           "uid"               => _("User identification"),
1422           "personalTitle"     => _("Personal title"),
1423           "academicTitle"     => _("Academic title"),
1424           "homePostalAddress" => _("Home postal address"),
1425           "homePhone"         => _("Home phone number"),
1426           "labeledURI"        => _("Homepage"),
1427           "o"                 => _("Organization"),
1428           "ou"                => _("Department"),
1429           "dateOfBirth"       => _("Date of birth"),
1430           "gender"            => _("Gender"),
1431           "preferredLanguage" => _("Preferred language"),
1432           "departmentNumber"  => _("Department number"),
1433           "employeeNumber"    => _("Employee number"),
1434           "employeeType"      => _("Employee type"),
1435           "l"                 => _("Location"),
1436           "st"                => _("State"),
1437           "userPicture"       => _("User picture"),
1438           "roomNumber"        => _("Room number"),
1439           "telephoneNumber"   => _("Telefon number"),
1440           "mobile"            => _("Mobile number"),
1441           "pager"             => _("Pager number"),
1442           "Certificate"        => _("User certificates"),
1444           "postalAddress"                => _("Postal address"),
1445           "facsimileTelephoneNumber"     => _("Fax number"))
1446         );
1448     /* Append government attributes if required */
1449       global $config;
1450     if (isset($config->current['GOVERNMENTMODE']) &&  preg_match('/true/i', $config->current['GOVERNMENTMODE'])){
1451       foreach($govattrs as $attr => $desc){
1452         $ret["plProvidedAcls"][$attr] = $desc;
1453       }
1454     }
1455     return($ret);
1456   }
1458   function get_multi_edit_values()
1459   {
1460     $ret = plugin::get_multi_edit_values();
1461     if(in_array("pw_storage",$this->multi_boxes)){
1462       $ret['pw_storage'] = $this->pw_storage;
1463     }
1464     if(in_array("edit_picture",$this->multi_boxes)){
1465       $ret['jpegPhoto'] = $this->jpegPhoto;
1466       $ret['photoData'] = $this->photoData;
1467       $ret['old_jpegPhoto'] = $this->old_jpegPhoto;
1468       $ret['old_photoData'] = $this->old_photoData;
1469     }
1470     if(isset($ret['dateOfBirth'])){
1471       unset($ret['dateOfBirth']);
1472     }
1473     if(isset($ret['cn'])){
1474       unset($ret['cn']);
1475     }
1476     $ret['is_modified'] = $this->is_modified;
1477     if(in_array("base",$this->multi_boxes)){
1478       $ret['orig_base']="Changed_by_Multi_Plug";
1479       $ret['base']=$this->base;
1480     }
1481     return($ret); 
1482   }
1485   function multiple_save_object()
1486   {
1487     plugin::multiple_save_object();
1489     /* Get pw_storage mode */
1490     if (isset($_POST['pw_storage'])){
1491       foreach(array("pw_storage") as $val){
1492         if(isset($_POST[$val])){
1493           $data= validate(get_post($val));
1494           if ($data != $this->$val){
1495             $this->is_modified= TRUE;
1496           }
1497           $this->$val= $data;
1498         }
1499       }
1500     }
1501     if(isset($_POST['base'])){
1502       $this->base = get_post('base');
1503     }
1505     if(isset($_POST['user_mulitple_edit'])){
1506       foreach(array("base","pw_storage","edit_picture") as $val){
1507         if(isset($_POST["use_".$val])){
1508           $this->multi_boxes[] = $val;
1509         }
1510       }
1511     }
1512   }
1514   
1515   function multiple_check()
1516   {
1517     /* Call check() to set new_dn correctly ... */
1518     $message = plugin::multiple_check();
1520     /* Set the new acl base */
1521     if($this->dn == "new") {
1522       $this->set_acl_base($this->base);
1523     }
1524     if (!tests::is_url($this->labeledURI) && in_array("labeledURI",$this->multi_boxes)){
1525       $message[]= msgPool::invalid(_("Homepage"));
1526     }
1527     if (!tests::is_phone_nr($this->telephoneNumber) && in_array("telephoneNumber",$this->multi_boxes)){
1528       $message[]= msgPool::invalid(_("Phone"), $this->telephoneNumber, "/[\/0-9 ()+*-]/");
1529     }
1530     if (!tests::is_phone_nr($this->facsimileTelephoneNumber) &&  in_array("facsimileTelephoneNumber",$this->multi_boxes)){
1531       $message[]= msgPool::invalid(_("Fax"), $this->facsimileTelephoneNumber, "/[\/0-9 ()+*-]/");
1532     }
1533     if (!tests::is_phone_nr($this->mobile) && in_array("mobile",$this->multi_boxes)){
1534       $message[]= msgPool::invalid(_("Mobile"), $this->mobile, "/[\/0-9 ()+*-]/");
1535     }
1536     if (!tests::is_phone_nr($this->pager) && in_array("pager",$this->multi_boxes)){
1537       $message[]= msgPool::invalid(_("Pager"), $this->pager, "/[\/0-9 ()+*-]/");
1538     }
1539     if (preg_match ('/[,+"?\'()=<>;\\\\]/', $this->givenName) && in_array("givenName",$this->multi_boxes)){
1540       $message[]= msgPool::invalid(_("Given name"), $this->giveName, '/[^,+"?\'()=<>;\\\\]/');
1541     }
1542     if (preg_match ('/[,+"?\'()=<>;\\\\]/', $this->sn) && in_array("sn",$this->multi_boxes)){
1543       $message[]= msgPool::invalid(_("Name"), $this->sn, '/[^,+"?\'()=<>;\\\\]/');
1544     }
1545     return($message);
1546   }
1550   function multiple_execute()
1551   {
1552     return($this->execute());
1553   }
1558 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1559 ?>