# # Copyright (c) 2001 SuSE GmbH Nuernberg, Germany. All rights reserved. # # # $Id: import_user.pm,v 1.38 2004/05/03 20:06:29 varkoly Exp $ # package import_user; use strict; use CGI qw(-no_xhtml); use CGI::Carp qw(fatalsToBrowser); use Storable qw(freeze thaw); use Net::LDAP; use Digest::MD5; use MIME::Base64; use LDAPUtils; use Utils; use Display; use Encode; use Data::Dumper; use vars qw(@ISA); use subs qw(exit); # Select the correct exit function *exit = $ENV{MOD_PERL} ? \&Apache::exit : sub { CORE::exit }; @ISA = qw(Display); my $JavaScript=<{'attr_int'} = ['uid', 'sn', 'givenname', 'birthday', 'userpassword', 'mail', 'alias', 'o', 'l', 'c', 'preferredlanguage', 'title', 'initials', 'description', 'homephone', 'mobile', 'facsimiletelephonenumber', 'pager', 'telephonenumber', 'labeleduri', 'street', 'postalcode', 'st', 'gidnumber', 'classe', 'writeglobaladdress','rasAccess']; return bless $self, $this; } sub display { my $this = shift; my $cgi = $this->{"cgi"}; my $doit = $cgi->param('doit'); my $doit_teacher = $cgi->param('doit_teacher'); if(defined $doit && $doit ne "") { $this->add_user(); } elsif(defined $doit_teacher && $doit_teacher ne "") { $this->add_teacher(); } else { $this->startup(); } } sub startup { my $this = shift; my $q = $this->{"cgi"}; my $session = $this->{"session"}; my $confParam = $session->{"confParam"}; my $message = ($session->getLanguage($confParam->{LANG},'CREATE_USER','IMPORT_USER'))->data(); my $sessionID = $confParam->{"sessionID"}; my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $IMPORT_FORMAT= $::CONF_GLOBAL{'GENERAL'}{'ImportFileFormat'}; my $ldapbase = $confParam->{baseDN}; my $ldaphost = $confParam->{LDAPserver}; my $ldapport = $confParam->{LDAPport}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $tab = $q->param('tab'); my $stab = $q->param('stab'); my $lang = $q->param('lang'); my $cgi_params = (); my $read_from_session = $q->param('read_from_session'); if( defined $read_from_session && $read_from_session == 1){ $cgi_params = $this->session_to_form; #print STDERR "Read data from sesssion:\n"; foreach my $key ( keys %$cgi_params){ #print STDERR " $key: ".$cgi_params->{$key}."\n"; } }else{ $cgi_params = $q->Vars(); } my $html = ""; $html .= $q->start_table({-class=>'AdminBorder', -cellspacing=>2, -cellpadding=>0, -width=>"100%"}); $html .= "\n"; $html .= $q->start_Tr(); $html .= $q->start_td(); $html .= $q->start_multipart_form( -action => $confParam->{'cgi_path'}."/import_user.pl", -name => "form" ); $html .= $q->start_table({-border=>0, -cellspacing => 0, -cellpadding=>3, -width=>"100%"}); $html .= "\n"; $html .= $q->start_Tr(); $html .= $this->help_th(2, $message->{import_user}.'
'. $message->{import_file_format}.$IMPORT_FORMAT, "IMPORT_USER"); $html .= $q->end_Tr(); $html .= "\n"; $html .= $q->start_Tr(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "right", -width=>"50%"}); $html .= $message->{"file"}; $html .= $q->end_td(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "left"}); $html .= $q->filefield(-name=>'userlist',-size=>50); $html .= $q->end_td(); $html .= $q->end_Tr(); $html .= "\n"; $html .= $q->start_Tr(); $html .= $q->start_td(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "left"}); $html .= $q->checkbox(-name=>"detail_list", -checked=>1, -label=>$message->{detail_list}); $html .= $q->end_td(); $html .= $q->end_Tr(); $html .= "\n"; $html .= $q->start_Tr(); $html .= $q->start_td(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "left"}); $html .= $q->submit(-name=>"doit", -value=>$message->{'add'}); $html .= $q->end_td(); $html .= $q->end_Tr(); $html .= $q->end_table(); $html .= "


\n"; $html .= $q->start_table({-border=>0, -cellspacing => 0, -cellpadding=>3, -width=>"100%"}); $html .= $q->start_Tr(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "right", -width=>"50%"}); $html .= $message->{"file_teacher"}; $html .= $q->end_td(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "left"}); $html .= $q->filefield(-name=>'teacherlist',-size=>50); $html .= $q->end_td(); $html .= $q->end_Tr(); $html .= "\n"; $html .= $q->start_Tr(); $html .= $q->start_td(); $html .= $q->start_td({-bgcolor=>$Display::__gray1, -align => "left"}); $html .= $q->submit(-name=>"doit_teacher", -value=>$message->{'add_teacher'}); $html .= $q->end_td(); $html .= $q->end_Tr(); $html .= "\n"; $html .= $q->hidden(-name=>"sessionID", -value=>$sessionID); $html .= $q->hidden(-name=>"tab", -value=>$tab); $html .= $q->hidden(-name=>"stab", -value=>$stab); $html .= "\n"; $html .= $q->end_table(); $html .= $q->end_form(); $html .= $q->end_td(); $html .= $q->end_Tr(); $html .= $q->end_table(); $this->back_url("$confParam->{cgi_path}/menu.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); $this->SUPER::display($html); } sub add_teacher { my $this = shift; my $q = $this->{"cgi"}; my $session = $this->{"session"}; my $confParam = $session->{"confParam"}; my $sessionID = $confParam->{"sessionID"}; my $message = ($session->getLanguage($confParam->{LANG},'CREATE_USER','IMPORT_USER'))->data(); my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $ldapbase = $confParam->{baseDN}; my $ldaphost = $confParam->{LDAPserver}; my $ldapport = $confParam->{LDAPport}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $tab = $q->param('tab'); my $stab = $q->param('stab'); my $lang = $q->param('lang'); my $teacherlist = $q->upload('teacherlist'); my @NEWLIST = (); my @ALLUID = (); my %ALLUSER = (); my @AKTUID = (); my $DOMAIN = ""; my $domain = ""; my @lines = (); my $errs; # C SCHULSERVER # my @def_folder = ("INBOX.sent-mail", "INBOX.trash", "INBOX.drafts", "INBOX.spam"); my @def_folder = split(/ /,$message->{def_folder}); # E SCHULSERVER # Variablen fuer die Erkundung der Fileheader my $read_attrs = $this->{'attr_int'}; my @attr_ext = (); my %attr_ext_name = (); my $sep = ""; my %header = (); my $SCHEME = read_rcconfig("SCHOOL_LOGIN_SCHEME"); my $LOGIN_PREFIX = read_rcconfig("SCHOOL_LOGIN_PREFIX"); my $IMPORT_FORMAT= $::CONF_GLOBAL{'GENERAL'}{'ImportFileFormat'}; my $n1 = substr($SCHEME,1,1); my $n2 = substr($SCHEME,3,1); my $fq_val = read_rcconfig("SCHOOL_FILE_TEACHER_QUOTA"); my $q_val = read_rcconfig("SCHOOL_MAIL_TEACHER_QUOTA")*1024; $q->param('mquota',$q_val); if($this->form_to_session() ne "OK"){ $this->display_error($message->{'write2session_failed'}, "$confParam->{cgi_path}/import_user.pl?sessionID=$sessionID". "\&tab=$tab\&lang=$lang\&stab=$stab"); exit; }; # now we make a connection to the ldap server my $bind_dn = "uid=".$ADMINuid.",".$ldapbase; my $ldap = Net::LDAP->new("$ldaphost",port=>$ldapport,version => 3); if(!defined $ldap) { $this->display_error("can't contact LDAP Server", "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } my $mesg = $ldap->bind ( # bind to a directory with dn and password dn => "$bind_dn", password => "$ADMINpasswd" ); if($mesg->code != 0) { $errs = "bind $message->{failed}\n\n"; $errs .= &LDAPerror($mesg); $this->display_error($errs, "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } # now we make a connection to the imap server my $imap = new Net::IMAP($imaphost, Debug => 0); if(!defined $imap){ $this->display_error("can't contact IMAP Server", "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } $mesg = $imap->login($ADMINuid, $ADMINpasswd); if($$mesg{Status} ne "ok") { $errs .= "IMAP login failed: Serverresponse: $$mesg{Status} => $$mesg{Text}\n"; $this->display_error($errs, "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } # Wir suchen mal ein paar Standardwerte aus $mesg = $ldap->search ( # perform a search base => "$bind_dn", scope => "base", attrs => ['c', 'o', 'maildomain'], filter => "objectclass=*" ); if($mesg->code == 0) { my $entry = $mesg->entry(0); $q->param('c',$entry->get_value('c')); $q->param('o',$entry->get_value('o')); $q->param('preferredlanguage', $entry->get_value('c')) ; $DOMAIN = $entry->get_value('maildomain'); } else { $errs = "search $message->{failed}\n\n"; $errs .= &LDAPerror($mesg); $this->display_error($errs, "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } # Jetzt erstellen wir eine Liste saemtlicher Lehrer $mesg = $ldap->search ( # perform a search base => "$ldapbase", scope => "one", filter => '(&(!(uid=mailadmin))(gidnumber=102)(uid=*))', attrs => ['uid','sn', 'givenname', 'birthday'] ); foreach my $entry ($mesg->all_entries) { my $i = $entry->get_value('uid'); push @ALLUID , $i; my $sn = $entry->get_value('sn'); my $givenname = $entry->get_value('givenname'); my $birthday = $entry->get_value('birthday'); $ALLUSER{"$sn-$givenname-$birthday"} = $i; } # -- building file header attributes foreach my $attr (@{$read_attrs}){ push @attr_ext, $message->{$attr}; $attr_ext_name{$message->{$attr}} = $attr; } my $muster = ""; foreach my $i (@attr_ext) { if( $i ne ""){ $muster.="$i|"; } } chomp $muster; #-- reading the file in a variable while ( <$teacherlist> ) { chomp; s/\r//; push @lines, $_; } #-- empty file if(scalar(@lines) < 2) { $this->display_error('Nothing to do', "$confParam->{cgi_path}/import_user.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); exit; } #-- convert if necessary if($IMPORT_FORMAT ne 'CSV' ) { if(!ConvertImportFile(\@lines,$IMPORT_FORMAT)) { $this->display_error('convert_broken', "$confParam->{cgi_path}/import_user.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); exit; } } #-- reading and evauliring of the header my $HEADER = uc($lines[0]); #-- removing white spaces $HEADER =~ s/\s+//; #-- determine the field separator $HEADER =~ /($muster)(.+?)($muster)/; $sep = $2; #-- insert for output needed fields if( $HEADER !~ /$message->{'uid'}/) { $HEADER = $HEADER.$sep.$message->{'uid'}; } if( $HEADER !~ /$message->{'userpassword'}/) { $HEADER = $HEADER.$sep.$message->{'userpassword'}; } my $counter = 0; foreach my $i (split /$sep/,$HEADER){ $header{$counter} = $attr_ext_name{$i}; $counter++; } push @NEWLIST, $HEADER; # Nun fangen wir an mit dem Aufbau des Ergebnisses $this->display_head(); print $q->start_table().$q->start_Tr().$q->start_td(); print "

$message->{working}

"; print $q->end_td().$q->end_Tr().$q->end_table()."\n"; my $pwch = time; $pwch= int($pwch/86400); for (my $i=1; $i<$#lines+1; $i++ ) { # Zuers loeschen wir alles was zaehlt $q->delete('uid'); $q->delete('sn'); $q->delete('givenname'); $q->delete('birthday'); $q->delete('classe'); $q->delete('userpassword'); my $uid = ''; my $ERROR = 0; my $ERRORS = ''; # jetzt lesen wir eine Zeile ein my $ackt_line = $lines[$i]; Encode::from_to( $ackt_line , 'iso-8859-2' , 'utf-8'); my @line = split /$sep/, $ackt_line; foreach my $h (keys %header) { if( $header{$h} eq "classe" ) { foreach my $c (split /\s+/,$line[$h]) { $q->append('classe',uc($c)); } } else { if( $header{$h} eq "uid" || $header{$h} eq "userpassword" ) { $line[$h] =~ s/\s//g; } $q->param("$header{$h}","$line[$h]"); } } $q->param('gidnumber','102'); $q->param('pwmech','CRYPT'); my $givenname = $q->param('givenname'); my $birthday = $q->param('birthday'); my $sn = $q->param('sn'); my @classes = $q->param('classe'); # Wenn kein maildomain gegeben ist wird default verwendet if( defined $q->param('domain') && $q->param('domain') ne "") { $domain = $q->param('domain'); } else { $domain = $DOMAIN; } $q->param('mail',"$domain"); # Oh Gott wieviele möglichkeiten gibt es ?? DD-MM-YYYY DD:MM:YYYY DD MM YYYY DDMMYYYY ... $birthday =~ tr/.: /---/; if( $birthday =~ /(\d{2})(\d{2})(\d{4})/) { $birthday = "$3-$2-$1"; $q->param('birthday',$birthday); } elsif ( $birthday =~ /(\d+)-(\d+)-(\d{4})/) { $birthday = sprintf("$3-%02d-%02d",$2,$1); $q->param('birthday',$birthday); } elsif ( $birthday =~ /(\d{4})-(\d{2})-(\d{2})/) { $q->param('birthday',$birthday); } else { $ERRORS .= " $givenname $sn: $message->{birthday_format_false}\n"; $ERROR = 1; } # Schaumamal ob es diesen Lehrer scho gibt: if( exists($ALLUSER{"$sn-$givenname-$birthday"}) ){ $uid=$ALLUSER{"$sn-$givenname-$birthday"}; if( $q->param('uid') eq '' ) { $q->param('uid',$uid); } else { if( $ALLUSER{"$sn-$givenname-$birthday"} ne $q->param('uid') ) { $ERRORS .= " $givenname $sn $birthday: $message->{same_person} $uid \n"; } } } # Und jetzt geht's los. if( $uid ne '') { $mesg = $ldap->search( base => $ldapbase, scope => 'one', filter => "(&(objectClass=SuSESchoolClass)(memberuid=$uid))", attrs => ['cn']); $ERRORS .= "$message->{teacher}: $givenname $sn: $message->{old_classes}:"; foreach my $entry ($mesg->all_entries) { my $cn = $entry->get_value('cn'); $mesg = $ldap->modify ( "cn=$cn,$ldapbase", delete => { memberUid => "$uid" } ); $mesg = $imap->deleteacl($cn,$uid); $ERRORS .= " $cn"; } $ERRORS .= " $message->{new_classes}:"; my $Classen = ""; foreach my $i (@classes) { $mesg = $ldap->modify ( "cn=$i,$ldapbase", add => { memberUid => "$uid" } ); $mesg = $imap->setacl($i,$uid,"lrswipcd"); $Classen .= "$i "; } $ERRORS .= " $Classen"; $mesg = $ldap->modify("uid=$uid:system,o=AddressBook,$ldapbase", replace => { 'ou' =>"$Classen" }); $mesg = $ldap->modify("uid=$uid,$ldapbase", replace => { 'ou' =>"$Classen" }); $ERRORS .= "
\n"; } else { # Zuerst bekommt jeder ein passwort $q->param('pwmech','CRYPT'); if( $q->param('userpassword') eq "" || !defined $q->param('userpassword') ) { # $q->param('userpassword','system'); my $passwd = ""; for( my $i=0; $i < 8; $i++){ $passwd .= pack( "C", int(rand(25)+97) ); } $q->param('userpassword',$passwd); } elsif ( $q->param('userpassword') eq "*" ){ my $passwd = ""; for( my $i=0; $i < 8; $i++){ $passwd .= pack( "C", int(rand(25)+97) ); } $q->param('userpassword',$passwd); } elsif( $q->param("userpassword") !~ /^[:\/\w\d§\$\%&!]+$/ ) { $ERRORS .= $message->{incorrect_passwd}.$q->param("userpassword"); $ERROR = 1; } if((! defined $q->param('uid')) || $q->param('uid') eq '' ) { my $gn = to_ascii(lc($givenname)); $uid = to_ascii(lc($sn)); if ( substr($SCHEME,0,1) eq "N" ) { $uid = substr($uid,0,$n1).substr($gn,0,$n2); } else { $uid = substr($gn,0,$n1).substr($uid,0,$n2); } $uid = $LOGIN_PREFIX.$uid; $uid =~ s/ |-//g; # Mal schauen ob es diese uid schon gibt. my $NOOK = 1; my $myuid = $uid; while ( $NOOK > 0 ) { $mesg = $ldap->search( base => $ldapbase, scope => "sub", filter => "uid=$myuid", attrs => ["uidNumber"]); if( $mesg->count > 0 ) { $myuid = $uid.$NOOK; $NOOK++; } else { $NOOK = 0; } } $uid = $myuid; $q->param('uid',"$uid"); } else { $uid = $q->param('uid'); } my $params = $q->Vars(); if($params->{"uid"} eq "" || $params->{"sn"} eq "" || $params->{"userpassword"} eq "" || $params->{"mail"} eq "" || $params->{"o"} eq "" || $params->{"c"} eq "") { $ERRORS .= " $givenname $sn: $message->{miss_some_values}\n"; $ERROR = 1; } else { if($params->{"uid"} =~ /[^a-zA-Z0-9-_]+/ ) { # Match a non-word character $ERRORS .= " $givenname $sn: $message->{uid_invalid}\n"; $ERROR = 1; } $params->{"uid"} = lc($params->{"uid"}); # uid always lowercase # Don't allow anybody or anyone as uid (these keywords are needed by cyrus for ACLs) if( ($params->{"uid"} eq "anyone") || ($params->{"uid"} eq "anybody")){ $ERRORS .= " $givenname $sn: $message->{value_anyone_not_allowed}\n"; $ERROR = 1; } $params->{"mail"} = $params->{"uid"}."@".$params->{"mail"}; if(length $params->{"userpassword"} < 5 || ( $params->{"pwmech"} eq "SMD5" ? 0 : length($params->{"userpassword"}) > 8 ) ) { $ERRORS .= " $givenname $sn: $message->{incorrect_passwd_length}\n"; $ERROR = 1; } } if( !$ERROR ) { # Ist kein fehler aufgetreten wird der neue Benutzer angelegt. my $exit_value = 0; my $text = ""; ($exit_value, $errs) = $this->to_ldap($ldap); $ERRORS .= $errs; ($exit_value, $errs) = $this->to_cyrus(@def_folder); $ERRORS .= $errs; # Setting file system quota $session->suad_setfquota('/home',$uid,$fq_val); $ERRORS = "$message->{teacher}: $givenname $sn $message->{created} $message->{uid}:\"$uid\"
\n".$ERRORS; } } print $q->start_table().$q->start_Tr().$q->start_td(); print $ERRORS; print $q->end_td().$q->end_Tr().$q->end_table()."\n"; if( $ERROR eq 0 ) { # Vorarbeit für die neue Liste: my $line = ""; foreach my $h (sort (keys %header)) { $line .= $q->param("$header{$h}").$sep; } $line =~ s/$sep\$//; Encode::from_to( $line ,'utf-8','iso-8859-2'); push @NEWLIST, $line; push @NEWLIST, " "; } } # Und jetz wird die neue Liste gespeichert: my $directory = `date +%Y-%m-%d.%H-%M`; chop $directory; $session->suad_mkdir("/root/userimport.$directory"); $session->suad_save( \@NEWLIST, "/root/userimport.$directory/teacher_list.txt" ); # Jetzt führen wir die archivierung per Hand durch # system("sudo /usr/sbin/archiv_user"); $session->suad_service_exec("nscd", "restart"); $imap->logout(); $this->display_footer("$confParam->{cgi_path}/menu.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); return (0, $errs); } sub add_user { my $this = shift; my $q = $this->{"cgi"}; my $session = $this->{"session"}; my $confParam = $session->{"confParam"}; my $sessionID = $confParam->{"sessionID"}; my $message = ($session->getLanguage($confParam->{LANG},'CREATE_USER','IMPORT_USER'))->data(); my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $ldapbase = $confParam->{baseDN}; my $ldaphost = $confParam->{LDAPserver}; my $ldapport = $confParam->{LDAPport}; my $imaphost = $confParam->{IMAPserver}; my $tab = $q->param('tab'); my $stab = $q->param('stab'); my $lang = $q->param('lang'); my $userlist = $q->upload('userlist'); my $NEWLIST = {}; my @CLASSES = (); my @ALLUID = (); my %ALLUSER = (); my @AKTUID = (); my $DOMAIN = ""; my $domain = ""; my @lines = (); my $errs; # C SCHULSERVER # my @def_folder = ("INBOX.sent-mail", "INBOX.trash", "INBOX.drafts", "INBOX.spam"); my @def_folder = split(/ /,$message->{def_folder}); # E SCHULSERVER # Variablen fuer die Erkundung der Fileheader my $read_attrs = $this->{'attr_int'}; my @attr_ext = (); my %attr_ext_name = (); my $sep = ""; my %header = (); my $groupware = read_rcconfig("SCHOOL_GROUPWARE") || 'all'; my $SCHEME = read_rcconfig("SCHOOL_LOGIN_SCHEME"); my $LOGIN_PREFIX = read_rcconfig("SCHOOL_LOGIN_PREFIX"); my $IMPORT_FORMAT= $::CONF_GLOBAL{'GENERAL'}{'ImportFileFormat'}; my $n1 = substr($SCHEME,1,1); my $n2 = substr($SCHEME,3,1); my $SORTED_HOME = read_rcconfig("SCHOOL_SORTED_HOME"); my $OBSERV_HOME = read_rcconfig("SCHOOL_TEACHER_OBSERV_HOME") || 'yes'; my $fq_val = read_rcconfig("SCHOOL_FILE_QUOTA"); my $q_val = read_rcconfig("SCHOOL_MAIL_QUOTA")*1024; $q->param('mquota',$q_val); my $uc_cnames = read_rcconfig("SCHOOL_UPPER_CASE_CLASS_NAME"); if($this->form_to_session() ne "OK"){ $this->display_error($message->{'write2session_failed'}, "$confParam->{cgi_path}/import_user.pl?sessionID=$sessionID". "\&tab=$tab\&lang=$lang\&stab=$stab"); exit; }; my $bind_dn = "uid=".$ADMINuid.",".$ldapbase; my $ldap = Net::LDAP->new("$ldaphost",port=>$ldapport,version => 3); if(!defined $ldap) { $this->display_error("can't contact LDAP Server", "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } my $mesg = $ldap->bind ( # bind to a directory with dn and password dn => "$bind_dn", password => "$ADMINpasswd" ); if($mesg->code != 0) { $errs = "bind $message->{failed}\n\n"; $errs .= &LDAPerror($mesg); $this->display_error($errs, "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } # Wir suchen mal ein paar Standardwerte aus $mesg = $ldap->search ( # perform a search base => "$bind_dn", scope => "base", attrs => ['c', 'o', 'maildomain'], filter => "objectclass=*" ); if($mesg->code == 0) { my $entry = $mesg->entry(0); $q->param('c',$entry->get_value('c')); $q->param('o',$entry->get_value('o')); $q->param('preferredlanguage', $entry->get_value('c')) ; $DOMAIN = $entry->get_value('maildomain'); } else { $errs = "search $message->{failed}\n\n"; $errs .= &LDAPerror($mesg); $this->display_error($errs, "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } # Jetzt suchen wir alle Klassen der Schule $mesg = $ldap->search ( # perform a search base => "$ldapbase", scope => "one", attrs => ['cn','gidNumber'], filter => "objectclass=SuSESchoolClass" ); if($mesg->code == 0) { foreach my $entry ($mesg->all_entries) { my $key = $entry->get_value("gidNumber"); my $val = $entry->get_value("cn"); push @CLASSES, $val; } } # Jetzt erstellen wir eine Liste saemtlicher Schueler $mesg = $ldap->search ( # perform a search base => "$ldapbase", scope => "one", filter => '(&(!(uid=mailadmin))(gidnumber=100)(uid=*))', attrs => ['uid','sn', 'givenname', 'birthday'] ); foreach my $entry ($mesg->all_entries) { my $i = $entry->get_value('uid'); push @ALLUID , $i; my $sn = $entry->get_value('sn'); my $givenname = $entry->get_value('givenname'); my $birthday = $entry->get_value('birthday'); $ALLUSER{"$sn-$givenname-$birthday"} = $i; # -- print STDERR "$sn-$givenname-$birthday => $i\n"; } # -- building file header attributes foreach my $attr (@{$read_attrs}){ push @attr_ext, $message->{$attr}; $attr_ext_name{$message->{$attr}} = $attr; } my $muster = ""; foreach my $i (@attr_ext) { if( $i ne ""){ $muster.="$i|"; } } chomp $muster; #-- reading the file in a variable while ( <$userlist> ) { chomp; s/\r//; push @lines, $_; } #-- empty file if(scalar(@lines) < 2) { $this->display_error('Nothing to do', "$confParam->{cgi_path}/import_user.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); exit; } #-- convert if necessary if($IMPORT_FORMAT ne 'CSV' ) { if(!ConvertImportFile(\@lines,$IMPORT_FORMAT)) { $this->display_error('convert_broken', "$confParam->{cgi_path}/import_user.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); exit; } } #-- reading and evauliring of the header my $HEADER = uc($lines[0]); #-- removing white spaces $HEADER =~ s/\s+//; #-- determine the field separator $HEADER =~ /($muster)(.+?)($muster)/; $sep = $2; #-- insert for output needed fields if( $HEADER !~ /$message->{'uid'}/) { $HEADER = $HEADER.$sep.$message->{'uid'}; } if( $HEADER !~ /$message->{'userpassword'}/) { $HEADER = $HEADER.$sep.$message->{'userpassword'}; } my $counter = 0; foreach my $i (split /$sep/,$HEADER){ $header{$counter} = $attr_ext_name{$i}; # print STDERR "$i $attr_ext_name{$i} $header{$counter} -> $sep\n"; $counter++; } foreach my $cl (@CLASSES) { $NEWLIST->{$cl}->{'header'} = $HEADER; } # Nun fangen wir an mit dem Aufbau des Ergebnisses $this->display_head(); print $q->start_table().$q->start_Tr().$q->start_td(); print "

$message->{working}

"; print $q->end_td().$q->end_Tr().$q->end_table()."\n"; my $pwch = time; $pwch= int($pwch/86400); for (my $i=1; $i<$#lines+1; $i++ ) { # Zuers loeschen wir alles was zaehlt $q->delete('uid'); $q->delete('sn'); $q->delete('givenname'); $q->delete('birthday'); $q->delete('classe'); $q->delete('userpassword'); my $uid = ''; my $ERROR = 0; my $ERRORS = ''; # jetzt lesen wir eine Zeile ein my $ackt_line = $lines[$i]; Encode::from_to( $ackt_line , 'iso-8859-2' , 'utf-8'); my @line = split /$sep/, $ackt_line; foreach my $h (keys %header) { if( $header{$h} eq "classe" ) { foreach my $c (split /\s+/,$line[$h]) { $q->append('classe',uc($c)); } } else { if( $header{$h} eq "uid" || $header{$h} eq "userpassword" ) { $line[$h] =~ s/\s//g; } $q->param("$header{$h}","$line[$h]"); } } $q->param('gidnumber','100'); $q->param('pwmech','CRYPT'); my $givenname = $q->param('givenname'); my $birthday = $q->param('birthday'); my $sn = $q->param('sn'); my @classes = $q->param('classe'); #Mal sehen ob alle klassen vorhanden sind foreach(@classes){ my $cn = uc($_); my $desc = $message->{classe}; if( !defined $NEWLIST->{$cn}->{'header'} ) { my $command = $confParam->{bin_path}."/add_group_ldap -"; my $cmd_args = "H=$ldaphost\nP=$ldapport\nal=$ADMINuid\n"; $cmd_args .= "bDN=$ldapbase\nap=$ADMINpasswd\ncn=$cn\n"; $cmd_args .= "groupware=$groupware\n"; $cmd_args .= "class=true\n"; $cmd_args .= "desc=$desc\n"; my $errs = cmd_pipe($command, $cmd_args); my $mesg = $ldap->search( base => "cn=$cn,$ldapbase", scope => "base", filter => "cn=$cn", attrs => ["gidNumber"] ); # my $gidnumber = $mesg->entry(0)->get_value("gidNumber"); $mesg = $session->suad_mkdir("/home/groups/$cn", '2770'); # $mesg = $session->suad_chown("/home/groups/$cn",'root',$gidnumber); $mesg = $session->suad_chown("/home/groups/$cn",'root',$cn); if($SORTED_HOME ne "no" ) { $mesg = $session->suad_mkdir("/home/$cn", '751'); } if($OBSERV_HOME eq 'yes') { $mesg = $session->suad_mkdir("/home/classes/$cn","770"); } # Creating mailbox # my $mailbox = $cn; my $imap = new Net::IMAP($imaphost, Debug => 0) or die ("can't connect to $imaphost: $!\n"); my $resp = $imap->login($ADMINuid, $ADMINpasswd); $resp = $imap->create($mailbox); $resp = $imap->setacl($mailbox,$ADMINuid,"lrswipcda"); if($ADMINuid ne 'cyrus') { $resp = $imap->setacl($mailbox,'cyrus',"lrswipcda"); } $resp = $imap->setacl($mailbox,$cn,"lrs"); $resp = $imap->logout(); my %attributes = (); $attributes{fn} = $cn; $attributes{description} = $desc if $desc ne ""; $attributes{mailenabled} = "OK"; $attributes{mailDeliveryProgram}= "\"|/usr/bin/formail -I \\\"From \\\" |/usr/lib/cyrus/bin/deliver -e -r $cn -a cyrus -m $mailbox\""; $attributes{objectclass} = [ 'top', 'SuSEIMAPFolderObject' ]; $mesg = $ldap->add ( dn => "fn=$cn,$ldapbase", attr => [ %attributes ] ); } push @CLASSES, $cn; $NEWLIST->{$cn}->{'header'} = $HEADER; } # Wenn kein maildomain gegeben ist wird default verwendet if( defined $q->param('domain') && $q->param('domain') ne "") { $domain = $q->param('domain'); } else { $domain = $DOMAIN; } $q->param('mail',"$domain"); # Oh Gott wieviele möglichkeiten gibt es ?? DD-MM-YYYY DD:MM:YYYY DD MM YYYY DDMMYYYY ... $birthday =~ tr/.: /---/; if( $birthday =~ /(\d{2})(\d{2})(\d{4})/) { $birthday = "$3-$2-$1"; $q->param('birthday',$birthday); } elsif ( $birthday =~ /(\d+)-(\d+)-(\d{4})/) { $birthday = sprintf("$3-%02d-%02d",$2,$1); $q->param('birthday',$birthday); } elsif ( $birthday =~ /(\d{4})-(\d{2})-(\d{2})/) { $q->param('birthday',$birthday); } else { $ERRORS .= " $givenname $sn: $message->{birthday_format_false}\n"; $ERROR = 1; } # Schaumamal ob es diesen Schüler scho gibt: if( exists($ALLUSER{"$sn-$givenname-$birthday"}) ){ $uid=$ALLUSER{"$sn-$givenname-$birthday"}; if( $q->param('uid') eq "" ) { $q->param('uid',$uid); } else { if( $ALLUSER{"$sn-$givenname-$birthday"} ne $q->param('uid') ) { $ERRORS .= " $givenname $sn $birthday: $message->{same_person} $uid \n"; } } } # Erster Fehlersuche $_ = $q->param('classe'); if(( /all/i || $#classes > 0 ) && $SORTED_HOME ne "no" ) { $ERRORS .= " $givenname $sn: $message->{more_classes_for}\n"; $ERROR = 1; } if( $#classes < 0 && $SORTED_HOME ne "no" ) { $ERRORS .= " $givenname $sn: $message->{no_classe_for}\n"; $ERROR = 1; } # Und jetzt geht's los. if( $uid ne '') { #Zuers kommen die Alten if( $SORTED_HOME ne "no" ) { my $cn; $mesg = $ldap->search( base => $ldapbase, scope => "sub", filter => "(&(objectClass=SuSESchoolClass)(memberuid=$uid))", attrs => ["cn"]); if( $mesg->count == 1) { $cn = $mesg->entry(0)->get_value("cn"); } else { $ERROR = 1; $ERRORS .= "$givenname $sn $message->{not_in_a_class}. Login: \"$uid\"
\n"; } if( $ERROR eq 0 ) { # Ist ein Fehler aufgetreten machen wir nix if( $cn eq $classes[0]) { # Der/die arme ist durchgefallen $ERRORS .= "$givenname $sn $message->{stands} \"$cn\". Login: \"$uid\"
\n"; } else { # Diese(r) ist weitergekommen my $homedirold = "/home/$cn/$uid"; my $class_old = $cn; $mesg = $ldap->modify("cn=$cn,$ldapbase",delete => { 'memberuid' =>"$uid" }); $cn = $classes[0]; $mesg = $ldap->modify("cn=$cn,$ldapbase",add => { 'memberuid' =>"$uid" }); my $homedir = "/home/$cn/$uid"; $mesg = $ldap->modify("uid=$uid,$ldapbase",replace => { 'homeDirectory' =>"$homedir" }); my $ret = $session->suad_move($homedirold,$homedir); if( $ret->code ne "OK" ) { $ERRORS .= "$givenname $sn : $class_old => $cn. Login: \"$uid\" $message->{'not_moved'}
\n"; } else { $ERRORS .= "$givenname $sn $message->{'moved'}: $class_old => $cn. Login: \"$uid\"
\n"; } $mesg = $ldap->modify("uid=$uid,$ldapbase", replace => { 'ou' =>"$cn" }); # Nun ist jetzt addressbuch dran: $mesg = $ldap->modify("uid=$uid:system,o=AddressBook,$ldapbase", replace => { 'ou' =>"$cn" }); } push @AKTUID, $uid; } } else { $mesg = $ldap->search( base => $ldapbase, scope => 'one', filter => "(&(objectClass=SuSESchoolClass)(memberuid=$uid))", attrs => ['cn']); $ERRORS .= "$givenname $sn:".$message->{old_classes}.":"; foreach my $entry ($mesg->all_entries) { my $cn = $entry->get_value('cn'); $mesg = $ldap->modify ( "cn=$cn,$ldapbase", delete => { memberUid => "$uid" } ); $ERRORS .= " $cn"; } # Nun ist jetzt addressbuch dran: # $mesg = $ldap->search( base => $ldapbase, # scope => 'sub', # filter => "uid=$uid", # attrs => ['uidNumber']); # my $uidNumber = $mesg->entry(0)->get_value('uidNumber'); my $Classen = ""; foreach my $i (@classes) { $mesg = $ldap->modify ( "cn=$i,$ldapbase", add => { memberUid => "$uid" } ); $Classen .= "$i "; } $ERRORS .= " $message->{new_classes}: $Classen"; $mesg = $ldap->modify("uid=$uid:system,o=AddressBook,$ldapbase", replace => { 'ou' =>"$Classen" }); $mesg = $ldap->modify("uid=$uid,$ldapbase", replace => { 'ou' =>"$Classen" }); $ERRORS .= "
\n"; push @AKTUID, $uid; } } else { # Zuerst bekommt jeder ein passwort if( $q->param('userpassword') eq "" || !defined $q->param('userpassword') ) { # $q->param('userpassword','system'); my $passwd = ""; for( my $i=0; $i < 8; $i++){ $passwd .= pack( "C", int(rand(25)+97) ); } $q->param('userpassword',$passwd); } elsif ( $q->param('userpassword') eq "*" ){ my $passwd = ""; for( my $i=0; $i < 8; $i++){ $passwd .= pack( "C", int(rand(25)+97) ); } $q->param('userpassword',$passwd); } elsif( $q->param("userpassword") !~ /^[:\/\w\d§\$\%&!]+$/ ) { $ERRORS .= $message->{incorrect_passwd}.$q->param("userpassword"); $ERROR = 1; } # Handelt es sich um ein neuer Schueler, braucht er einen neuen eindeutigen uid if((! defined $q->param('uid')) || $q->param('uid') eq '' ) { my $gn = to_ascii(lc($givenname)); $uid = to_ascii(lc($sn)); if ( substr($SCHEME,0,1) eq "N" ) { $uid = substr($uid,0,$n1).substr($gn,0,$n2); } else { $uid = substr($gn,0,$n1).substr($uid,0,$n2); } $uid =~ s/ |-//g; $uid = $LOGIN_PREFIX.$uid; # Mal schauen ob es diese uid schon gibt. my $NOOK = 1; my $myuid = $uid; while ( $NOOK > 0 ) { my $mesg = $ldap->search( base => $ldapbase, scope => "sub", filter => "uid=$myuid", attrs => ["uidNumber"]); if( $mesg->count > 0 ) { $myuid = $uid.$NOOK; $NOOK++; } else { $NOOK = 0; } } $uid = $myuid; $q->param('uid',"$uid"); } else { $uid = $q->param('uid'); } my $params = $q->Vars(); if($params->{"uid"} eq "" || $params->{"sn"} eq "" || $params->{"userpassword"} eq "" || $params->{"mail"} eq "" || $params->{"o"} eq "" || $params->{"c"} eq "") { $ERRORS .= " $givenname $sn: $message->{miss_some_values}\n"; $ERROR = 1; } else { if($params->{"uid"} =~ /[^a-zA-Z0-9-_]+/ ) { # Match a non-word character $ERRORS .= " $givenname $sn: $message->{uid_invalid}\n"; $ERROR = 1; } $params->{"uid"} = lc($params->{"uid"}); # uid always lowercase # Don't allow anybody or anyone as uid (these keywords are needed by cyrus for ACLs) if( ($params->{"uid"} eq "anyone") || ($params->{"uid"} eq "anybody")){ $ERRORS .= " $givenname $sn: $message->{value_anyone_not_allowed}\n"; $ERROR = 1; } $params->{"mail"} = $params->{"uid"}."@".$params->{"mail"}; if(length $params->{"userpassword"} < 5 || ( $params->{"pwmech"} eq "SMD5" ? 0 : length($params->{"userpassword"}) > 8 ) ) { $ERRORS .= " $givenname $sn: $message->{incorrect_passwd_length}\n"; $ERROR = 1; } } if( !$ERROR ) { # Ist kein fehler aufgetreten wird der neue Benutzer angelegt. my $exit_value = 0; my $text = ""; ($exit_value, $errs) = $this->to_ldap($ldap); $ERRORS .= $errs; ($exit_value, $errs) = $this->to_cyrus(@def_folder); $ERRORS .= $errs; # Setting file system quota $session->suad_setfquota('/home',$uid,$fq_val); my $klassen = ""; foreach my $i (@classes) { $klassen .= "$i "; } $ERRORS = "$givenname $sn $message->{created} Login: \"$uid\" $message->{classe}: $klassen
\n".$ERRORS; push @AKTUID, $uid; } } print $q->start_table().$q->start_Tr().$q->start_td(); print $ERRORS; print $q->end_td().$q->end_Tr().$q->end_table()."\n"; if( $ERROR eq 0 ) { # Vorarbeit für die neue Liste: my $line = ""; foreach my $h (sort (keys %header)) { $line .= $q->param("$header{$h}").$sep; } $line =~ s/$sep\$//; Encode::from_to( $line ,'utf-8','iso-8859-2'); $NEWLIST->{@classes[0]}->{$uid} = $line; } # Blöd aber hilfreich! #$session->suad_service_exec("nscd","restart"); } if( $q->param('detail_list') ne 'on' ) { # Und jetzt werden die alten Schueler geloescht my $ind = {}; $ind->{$_} = 1 foreach(@AKTUID); foreach my $uid (@ALLUID ){ if(not exists($ind->{$uid})){ my $ERROR = ""; $mesg = $ldap->search ( # perform a search base => "$ldapbase", scope => "sub", attrs => ['homeDirectory','uidNumber'], filter => "uid=$uid" ); my $home = $mesg->entry(0)->get_value("homeDirectory"); my $uidNumber = $mesg->entry(0)->get_value('uidNumber'); my $ret = $session->suad_chown($home,0,102); if( $ret->code() ne "OK" ) { $this->display_error($ret->code(), $confParam->{cgi_path}."/menu.pl?sessionID=$sessionID"); } $ret = $session->suad_move("/home/profile/$uid","$home/profile"); $ret = $session->suad_move($home,"/home/archiv/$uid"); $ret = $session->suad_stdout_exec("echo -n $uidNumber > /home/archiv/$uid/UIDNUMBER"); my $exit_imap; ($exit_imap, $errs) = $this->from_imap($uid); if($exit_imap != 0) { $ERROR .= "del_user $uid IMAP $message->{failed}
\n\n"; $ERROR .= $errs."
"; } else { $ERROR .= "del_user $uid IMAP $message->{success}
\n"; } my $exit_sieve; ($exit_sieve, $errs) = $this->del_sieve($uid); if($exit_imap != 0) { $ERROR .= "del_user $uid SIEVE $message->{failed}
\n\n"; $ERROR .= $errs."
"; } else { $ERROR .= "del_user $uid SIEVE $message->{success}
\n"; } my $exit_ldap; ($exit_ldap, $errs) = $this->from_ldap($uid); if($exit_ldap == -2) { $ERROR .= "del_user $uid LDAP $message->{not_completely_executed}
\n\n"; $ERROR .= $errs."
"; } elsif($exit_ldap != 0) { $ERROR .= "del_user $uid LDAP $message->{failed}
\n\n"; $ERROR .= $errs."
"; } else { $ERROR .= "del_user $uid LDAP $message->{success}
\n"; } if($groupware eq 'all' || $groupware eq 'phpgw' ){ #Aus dem mysql muss auch alles ausgetragen werden my $mysqlc = "mysql -u $confParam->{uid} -p\'$confParam->{passwd}\' -h mailserver phpgroupware"; my $mysqla = ""; $mysqla = " DELETE FROM phpgw_acl WHERE acl_account=$uidNumber"; system("echo \'$mysqla\' | $mysqlc"); $mysqla = " DELETE FROM phpgw_preferences WHERE preference_owner=\'$uidNumber\'"; system("echo \'$mysqla\' | $mysqlc"); $mysqla = " DELETE FROM phpgw_categories WHERE cat_owner=$uidNumber"; system("echo \'$mysqla\' | $mysqlc"); $mysqla = "SELECT cal_id FROM phpgw_cal_user WHERE cal_login=$uidNumber"; my @calenders = `echo $mysqla | $mysqlc`; shift @calenders; foreach my $i (@calenders) { $mysqla = " DELETE FROM phpgw_cal_user WHERE cal_id=$i"; system("echo \'$mysqla\' | $mysqlc"); $mysqla = " DELETE FROM phpgw_cal WHERE cal_id=$i"; system("echo \'$mysqla\' | $mysqlc"); $mysqla = " DELETE FROM phpgw_cal_alarm WHERE cal_id=$i"; system("echo \'$mysqla\' | $mysqlc"); $mysqla = " DELETE FROM phpgw_cal_repeats WHERE cal_id=$i"; system("echo \'$mysqla\' | $mysqlc"); } #Adressbucheintrag wird auch gelöscht $mesg = $ldap->delete("uid=$uid:system,o=AddressBook,".$confParam->{'baseDN'}); #Eigene Einträge aus dem Adressbuch werden gelöscht. $mesg = $ldap->search ( # perform a search base => "o=AddressBook,".$confParam->{'baseDN'}, scope => "base", attrs => ['dn'], filter => "phpgwContactOwner=$uidNumber" ); if( $mesg->count > 0 ){ foreach my $entry ($mesg->all_entries) { my $dn = $entry->dn(); $ldap->delete($dn); } } } #Admineintrag wird ggf. gelöscht $mesg = $ldap->search ( # perform a search base => "cn=Admins,".$confParam->{'baseDN'}, scope => "base", attrs => ['member'], filter => "member=uid=$uid,".$confParam->{'baseDN'} ); if( $mesg->count > 0 ){ $ldap->modify( "cn=Admins,".$confParam->{'baseDN'}, delete => {"member" => "uid=$uid,".$confParam->{'baseDN'} } ); } # Delete symlinks if exixsts; $session->suad_stdout_exec("RM=`find /home/classes -name $uid`; test \$RM && rm \$RM;"); print $q->start_table().$q->start_Tr.$q->start_td()."\n"; print "Login: $uid $message->{deleted} /home/archiv/$uid.tgz
\n"; print "$ERROR\n"; print $q->end_td().$q->end_Tr().$q->end_table()."\n"; } } } # Und jetz wird die neue Liste gespeichert: my $directory = `date +%Y-%m-%d.%H-%M`; chop $directory; $session->suad_mkdir("/root/userimport.$directory"); foreach my $cl (@CLASSES){ my @ClassenListe = ("$HEADER"); foreach(keys %{$NEWLIST->{$cl}}) { if( $_ ne "header" ){ push @ClassenListe, $NEWLIST->{$cl}->{$_}; push @ClassenListe, " "; } } if( scalar @ClassenListe > 1 ) { $session->suad_save( \@ClassenListe, "/root/userimport.$directory/userlist.$cl.txt" ); } } # Jetzt führen wir die archivierung per Hand durch # system("sudo /usr/sbin/archiv_user"); $session->suad_service_exec("nscd", "restart"); $this->display_footer("$confParam->{cgi_path}/menu.pl?sessionID=$sessionID\&tab=$tab\&lang=$lang\&stab=$stab"); return (0, $errs); } sub to_ldap () { my $this = shift; my $ldap = shift; my @attrnames = ( "gidnumber", "uid", "sn", "givenname", "mail", "o", "l", "c", "preferredlanguage", "title", "initials", "homephone", "mobile", "facsimiletelephonenumber", "pager", "telephonenumber", "labeleduri", "street", "postalcode", "st"); my $q = $this->{"cgi"}; my $session = $this->{"session"}; my $confParam = $session->{"confParam"}; my $passwd = $q->param('userpassword'); my $params = $q->Vars(); my $defalias = $q->param('alias'); my $lang = $q->param('language'); my $group = $q->param('group'); my $uid = $q->param('uid'); my $pwmech = $q->param('pwmech'); my @classes = $q->param('classe'); my $birthday = $q->param('birthday'); my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $ldapbase = $confParam->{baseDN}; my $ldaphost = $confParam->{LDAPserver}; my $ldapport = $confParam->{LDAPport}; my $sessionID = $confParam->{sessionID}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $message = ($session->getLanguage($confParam->{LANG},'CREATE_USER','IMPORT_USER'))->data(); my $errs = ""; my $command = $confParam->{bin_path}."/add_user_ldap -"; my $cn = ""; my $homedir = ""; my $no_extern = read_rcconfig("SCHOOL_NO_EXTERN_MAIL") || 'yes'; my $SORTED_HOME = read_rcconfig("SCHOOL_SORTED_HOME") || 'no'; my $OBSERV_HOME = read_rcconfig("SCHOOL_TEACHER_OBSERV_HOME") || 'yes'; my $groupware = read_rcconfig("SCHOOL_GROUPWARE") || 'all'; my $mailenabled = "OK"; my $gidnumber = $q->param('gidnumber'); my $teacheraci = "cn initials mail title l description street postalcode st c homephone mobile pager facsimiletelephonenumber telephonenumber labeleduri sn givenname preferredlanguage birthday jpegphoto"; my $childaci = "preferredlanguage"; my $bind_dn = "uid=".$ADMINuid.",".$ldapbase; my $mesg; # my $ldap = Net::LDAP->new("$ldaphost",port=>$ldapport,version => 3); # if(!defined $ldap) { # $this->display_error("can't contact LDAP Server", # "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); # exit; # } # # my $mesg = $ldap->bind ( # bind to a directory with dn and password # dn => "$bind_dn", # password => "$ADMINpasswd" # ); # # if($mesg->code != 0) { # $errs = "bind $message->{failed}\n\n"; # $errs .= &LDAPerror($mesg); # $this->display_error($errs, # "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); # exit; # } #Traurig ist es aber so :-() sleep(3); my $cmd_args = "H=$ldaphost\nP=$ldapport\nal=$ADMINuid\n"; $cmd_args.= "bDN=$ldapbase\nap=$ADMINpasswd\n"; if( $gidnumber == 100 ) { $mesg = $ldap->modify($bind_dn, replace => {"defaultUserAci" => $childaci}); if( $SORTED_HOME ne "no" ) { $homedir = "/home/$classes[0]/$uid"; } else { $homedir = "/home/users/$uid"; } if ( $no_extern eq "yes" ) { $mailenabled = "local_only"; } $cmd_args.= "description=$message->{kidd}\n"; } elsif( $gidnumber == 102 ) { $mesg = $ldap->modify($bind_dn, replace => {"defaultUserAci" => $teacheraci}); $mesg = $ldap->modify("cn=users,$ldapbase", add => { memberUid => "$uid" } ); $mesg = $ldap->modify ( "cn=workstations,$ldapbase", add => { memberUid => "$uid" } ); # Defaultmäsig bekommen die Lehrer nicht erweiterte Adminrechte # $mesg = $ldap->modify("cn=Admins,$ldapbase", add => { member => "uid=$uid,$ldapbase" } ); $homedir = "/home/teachers/$uid"; $cmd_args.= "description=$message->{teacher}\n"; } my $crypt_passwd = "*"; if( $pwmech eq "CRYPT" ) { my $salt = pack("C2",(int(rand 26)+65),(int(rand 26)+65)); $crypt_passwd = crypt $passwd,$salt; $crypt_passwd = "{crypt}".$crypt_passwd; } elsif( $pwmech eq "SMD5" ) { my $salt = pack("C5",(int(rand 26)+65),(int(rand 26)+65)); my $ctx = new Digest::MD5(); $ctx->add($passwd); $ctx->add($salt); $crypt_passwd = "{smd5}".encode_base64($ctx->digest.$salt, ""); } $cmd_args.= "up=$crypt_passwd\n"; foreach my $attr (@attrnames){ if( defined $params->{$attr} && ($params->{$attr} ne "") ){ $cmd_args .= "$attr=".$params->{$attr}."\n"; } } $cmd_args.= "homedirectory=$homedir\n"; if( (defined $params->{"alias"}) && ($params->{"givenname"} ne "" ) ){ if ( $confParam->{LANG} eq "HU" ) { $cmd_args .= "alias=".to_ascii($params->{"sn"}).".".to_ascii($params->{"givenname"})."\n"; } else { $cmd_args .= "alias=".to_ascii($params->{"givenname"}).".".to_ascii($params->{"sn"})."\n"; } } if( defined $params->{"description"} ){ $params->{"description"} =~ s/(\r?\n)/$1 /mg; $cmd_args .= "description=".$params->{"description"}."\n"; } if(defined $params->{"writeglobaladdress"} && $params->{"writeglobaladdress"} eq "on") { $cmd_args .= "writeglobaladdress=allowed\n"; } else { $cmd_args .= "writeglobaladdress=denied\n"; } my $ou = ""; if( $params->{"classe"} =~ /all/i) { @classes = (); $mesg = $ldap->search ( # perform a search base => "$ldapbase", scope => "sub", attrs => ['cn','gidNumber'], filter => "objectclass=SuSESchoolClass" ); if($mesg->code == 0) { foreach my $entry ($mesg->all_entries) { my $cn = $entry->get_value("cn"); my $gn = $entry->get_value("gidNumber"); push @classes, $cn; $cmd_args .= "class=$cn\n"; } $ou .= "all "; } else { $errs = "search $message->{failed}\n\n"; $errs .= &LDAPerror($mesg); $ldap->unbind; # take down session $this->display_error($errs, "$confParam->{cgi_path}/menu.pl?sessionID=$sessionID"); exit; } } else { foreach my $i (@classes) { $cmd_args .= "class=$i\n"; $ou .= "$i "; } } chop $ou; if ( $ou ne "" ) { $cmd_args .= "ou=$ou\n"; } #teachers need extra rights for the classmailboxes if($gidnumber == 102){ my $imap = new Net::IMAP($imaphost, Debug => 0) or die ("can't connect to $imaphost: $!\n"); my $resp = $imap->login($ADMINuid, $ADMINpasswd); if($$resp{Status} ne "ok") { $errs .= "IMAP login failed: Serverresponse: $$resp{Status} => $$resp{Text}\n"; } else { foreach(@classes){ $resp = $imap->setacl($_,$uid,"lrswipcd"); if($$resp{Status} ne "ok") { $errs .= "IMAP setacl failed for $uid: Serverresponse: $$resp{Status} => $$resp{Text}\n"; } } } $imap->logout; } $cmd_args .= "birthday=$birthday\n"; $cmd_args .= "mailenabled=$mailenabled\n"; $cmd_args .= "homedirectory=$homedir\n"; $cmd_args .= "groupware=$groupware\n"; if(defined $params->{"rasAccess"} && $params->{"rasAccess"} eq "on") { $cmd_args .= "rasaccess=1\n"; } else { $cmd_args .= "rasaccess=0\n"; } # -- print STDERR "CMDARGS:\n".$cmd_args."\n"; $errs = cmd_pipe("$command", "$cmd_args"); # Was ist die neue uidNumber ?? $mesg = $ldap->search( base => $ldapbase, scope => "sub", filter => "uid=$uid", attrs => ["uidNumber"]); my $uidNumber = "-1"; if($mesg->code == 0 && $mesg->count > 0){ $uidNumber = $mesg->entry(0)->get_value("uidNumber"); $q->param(-name=>'uidnumber',-value=>"$uidNumber"); if($groupware eq 'all' || $groupware eq 'phpgw' ){ my $mysqlc = "mysql -u $ADMINuid -p\'$ADMINpasswd\' -h mailserver phpgroupware"; my $mysqla = " INSERT INTO phpgw_preferences VALUES (\'$uidNumber\',\'$message->{phpgw_prefs}\')"; system("echo -E \"$mysqla\" | $mysqlc"); } }else{ print STDERR $params->{"classe"}." : $ldapbase : $uid\n "; $errs = "search $message->{failed}\n\n"; $errs .= &LDAPerror($mesg); return (1, $errs); } $mesg = $session->suad_mkdir($homedir, '711'); if( $mesg->code() ne "OK" ){ $errs .= "mkdir ".$message->{'failed'}.": ".$mesg->code()."
\n"; }else{ $errs .= "mkdir ".$message->{'success'}."
\n"; } $mesg = $session->suad_copydir('/etc/skel/', $homedir); if( $mesg->code() ne "OK" ){ $errs .= "cp ".$message->{'failed'}.": ".$mesg->code()."
\n"; }else{ $errs .= "cp ".$message->{'success'}."
\n"; } $mesg = $session->suad_chown($homedir,$uidNumber,$gidnumber); if( $mesg->code() ne "OK" ){ $errs .= "chown ".$message->{'failed'}.": ".$mesg->code()."
\n"; }else{ $errs .= "chown ".$message->{'success'}."
\n"; } $mesg = $session->suad_smbadduser($uid, $passwd); if( $mesg->code() ne "OK" ){ $errs .= "smb_adduser ".$message->{'failed'}.": ".$mesg->code()."
\n"; }else{ $errs .= "smb_adduser ".$message->{'success'}."
\n"; } $mesg = $session->suad_move("$homedir/.profiles","/home/profile/$uid"); if( $mesg->code() ne "OK" ){ $errs .= "prepare_homedir3 ".$message->{'failed'}.": ".$mesg->code()."\n"; }else{ $errs .= "prepare_homedir3 ".$message->{'success'}."\n"; } $mesg = $session->suad_chown($homedir.'/public_html',$uidNumber,'nogroup'); $mesg = $session->suad_chmod($homedir.'/public_html','2755'); if($gidnumber == 100){ if($OBSERV_HOME eq 'yes' && $SORTED_HOME ne 'yes') { foreach(@classes){ $session->suad_stdout_exec("ln -s /home/users/$uid /home/classes/$_/$uid"); } $session->suad_stdout_exec("setfacl -R -m group:teachers:rwx $homedir"); $session->suad_stdout_exec("setfacl -R -d -m group:teachers:rwx $homedir"); } } elsif($gidnumber == 102){ $session->suad_stdout_exec("ln -s /home/groups/teachers $homedir/+allteachers"); if($OBSERV_HOME eq 'yes') { $session->suad_stdout_exec("ln -s /home/classes $homedir/+classes"); } } #make some symlinks to make the life easier $session->suad_stdout_exec("ln -s /home/all $homedir/+all"); $session->suad_stdout_exec("ln -s /home/groups $homedir/+groups"); $session->suad_stdout_exec("ln -s /home/software $homedir/+software"); sleep(1); return (0, $errs); } sub to_cyrus (){ my $this = shift; my @def_folder = @_; my $q = $this->{"cgi"}; my $confParam = $this->{"session"}->{"confParam"}; my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $uid = $q->param('uid'); my $q_val = $q->param('mquota'); # my @dflt_quota = parse_file("/etc/imapd.conf", "autocreatequota:"); # my $q_val = $dflt_quota[0]; my $errs = ""; my $command = $confParam->{bin_path}."/add_user_cyrus -"; $uid = lc($uid); # uid always lowercase my $cmd_args = "H=$imaphost\nP=$imapport\nal=$ADMINuid\n"; $cmd_args .= "ap=$ADMINpasswd\nuid=$uid\n"; if(defined $q_val && $q_val ne "") { $cmd_args .= "qv=$q_val\n"; } foreach(@def_folder){ $cmd_args .= "mb=$_\n"; } $errs = cmd_pipe($command, $cmd_args); if($errs ne "") { return (-1, $errs); } return (0, $errs); } sub default_folder(@) { my $this = shift; my $q = $this->{"cgi"}; my $confParam = $this->{"session"}->{"confParam"}; my $ADMINuid = $confParam->{uid}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $uid = $q->param('uid'); my $gidnumber = $q->param('gidnumber'); my $passwd = $q->param('passwd'); my @folder = @_; $uid = lc($uid); # uid always lowercase my $errs = ""; my $command = $confParam->{bin_path}."/add_folder -"; my $cmd_args = "H=$imaphost\nP=$imapport\nal=$ADMINuid\n"; $cmd_args .= "ul=$uid\nup=$passwd\n"; foreach (@folder) { $cmd_args .= "mb=$_\n"; } $errs = cmd_pipe($command, $cmd_args); # teachers haben alle Rechte fuer Schuelermailboxen: # if ( $gidnumber == 100) { # my $imap = new Net::IMAP($imaphost, Debug => 0) or die ("can't connect to $imaphost: $!\n"); # my $resp = $imap->login($ADMINuid, $ADMINpasswd); # if($$resp{Status} ne "ok") { # $errs .= "IMAP login failed: Serverresponse: $$resp{Status} => $$resp{Text}\n"; # } else { # $resp = $imap->setacl("user.".$uid,"group:teachers","lrswipcda"); # if($$resp{Status} ne "ok") { # $errs .= "IMAP setacl failed for $uid: Serverresponse: $$resp{Status} => $$resp{Text}\n"; # } # } # $imap->logout; # } if($errs ne "") { return (-1, $errs); } return (0, $errs); } sub revoke { my $this = shift; my $todo = shift; my $q = $this->{"cgi"}; my $confParam = $this->{"session"}->{"confParam"}; my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $ldapbase = $confParam->{baseDN}; my $ldaphost = $confParam->{LDAPserver}; my $ldapport = $confParam->{LDAPport}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $uid = $q->param('uid'); $uid = lc($uid); # uid always lowercase my $ev = 0; my $errs = ""; my $command = ""; if($todo eq "imap") { $command = $confParam->{bin_path}."/del_user -"; my $cmd_args = "CH=$imaphost\nCP=$imapport\n"; $cmd_args .= "al=$ADMINuid\nap=$ADMINpasswd\nuid=$uid\nimap\n"; $errs = cmd_pipe($command, $cmd_args); } elsif ($todo eq "ldap") { $command = $confParam->{bin_path}."/del_user -"; my $cmd_args = "LH=$ldaphost\nLP=$ldapport\n"; $cmd_args .= "al=$ADMINuid\nap=$ADMINpasswd\n"; $cmd_args .= "uid=$uid\nldap\nbDN=$ldapbase\n"; $errs = cmd_pipe($command, $cmd_args); } if($errs ne "") { return (-1, $errs); } return (0, $errs); } sub form_to_session{ my $this = shift; my $session = $this->{"session"}; my $cgi = $this->{'cgi'}; my %cgi_params = $cgi->Vars(); my $frozen = freeze (\%cgi_params); $frozen = unpack('H*',$frozen); my %tmp = ( "formdata" => $frozen ); my $s_reply=$session->modify(\%tmp); if( $s_reply->code() ne "OK" ) { return "ERR" }else { return "OK"; } } sub session_to_form{ my $this = shift; my $session = $this->{"session"}; my $confParam = $session->{'confParam'}; my $frozen = $confParam->{'formdata'}; $frozen = pack('H*',$frozen); my $formdata = thaw($frozen); return $formdata; } sub cleanupsession{ my $this = shift; my $session = $this->{"session"}; my $reply = $session->modify({"formdata" => "" }); } sub from_ldap () { my $this = shift; my $user = shift; my $confParam = $this->{"session"}->{"confParam"}; my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $ldapbase = $confParam->{baseDN}; my $ldaphost = $confParam->{LDAPserver}; my $ldapport = $confParam->{LDAPport}; my $errs = ""; my $command = $confParam->{bin_path}."/del_user -"; my $cmd_args = "LH=$ldaphost\nLP=$ldapport\nal=$ADMINuid\n"; $cmd_args .= "ap=$ADMINpasswd\nuid=$user\nldap\nbDN=$ldapbase\n"; $errs = cmd_pipe($command, $cmd_args); if($errs =~ /failed\sto\sdelete\suser\s.*/ ) { return (-1, $errs); } elsif($errs ne "") { return (-2, $errs); } return (0, $errs); } sub from_imap () { my $this = shift; my $user = shift; my $confParam = $this->{"session"}->{"confParam"}; my $ADMINuid = $confParam->{uid}; my $ADMINpasswd = $confParam->{passwd}; my $imaphost = $confParam->{IMAPserver}; my $imapport = $confParam->{IMAPport}; my $errs = ""; my $command = $confParam->{bin_path}."/del_user -"; my $cmd_args = "CH=$imaphost\nCP=$imapport\nal=$ADMINuid\n"; $cmd_args .= "ap=$ADMINpasswd\nuid=$user\nimap\n"; $errs = cmd_pipe($command, $cmd_args); if($errs ne "") { return (-1,$errs); } return (0, $errs); } sub del_sieve () { my $this = shift; my $user = shift; my $confParam = $this->{"session"}->{"confParam"}; my $ADMINuid = $confParam->{"uid"}; my $ADMINpasswd = $confParam->{"passwd"}; my $imaphost = $confParam->{"IMAPserver"}; my $sieveport = $confParam->{"SIEVEport"}; my $errs = ""; my $command = $confParam->{bin_path}."/del_user -"; my $cmd_args = "CH=$imaphost\nSP=$sieveport\nal=$ADMINuid\n"; $cmd_args .= "ap=$ADMINpasswd\nuid=$user\nsieve\n"; $errs = cmd_pipe($command, $cmd_args); if($errs ne "") { return (-1,$errs); } return (0, $errs); } 1;