11 |
gdo |
1 |
#!/usr/bin/perl
|
|
|
2 |
# ---------------------------------------------------------------------- #
|
|
|
3 |
# Copyright: (C) 2002 Leader.IT S.r.l. <http://leader.it>
|
|
|
4 |
# Authors: Guido Brugnara <gdo@leader.it>
|
|
|
5 |
#
|
|
|
6 |
# $Revision: 16 $
|
|
|
7 |
# ---------------------------------------------------------------------- #
|
|
|
8 |
#
|
|
|
9 |
# richiamata da samba ad ogni connessione della share 'netlogon'
|
|
|
10 |
# tipicamente viene chiamata ad ogni connessione o quando l'utente
|
|
|
11 |
# dovesse accedervi manualmente
|
|
|
12 |
#
|
|
|
13 |
require 5.002;
|
16 |
gdo |
14 |
open STDERR, ">>/var/log/samba_netlogon.log" || die "Errore [$!] apertura file '/var/log/samba_netlogon.log'\n";
|
11 |
gdo |
15 |
|
|
|
16 |
$Mode = shift;
|
|
|
17 |
$User = shift;
|
|
|
18 |
$Group = shift;
|
|
|
19 |
$Luser = shift;
|
|
|
20 |
$Machine = shift;
|
|
|
21 |
$IPmachine = shift;
|
|
|
22 |
$Server = shift;
|
|
|
23 |
$Platform = shift; ## O.S. platform: Win95 Win2k ...
|
|
|
24 |
|
|
|
25 |
# flag installazione poweroff (alpha stage)
|
|
|
26 |
$inst_poweroff=0;
|
|
|
27 |
$reboot_poweroff=0;
|
|
|
28 |
|
|
|
29 |
# flag lancio vnc su tutti gli utenti
|
|
|
30 |
$startVnc = 1;
|
|
|
31 |
$startVncAll = 1;
|
|
|
32 |
$startVncDelay = 0;
|
|
|
33 |
$startBrowseDelay = 0;
|
|
|
34 |
|
|
|
35 |
# TIMEOUT controllo stato di Logon in 1/10 di secondi
|
|
|
36 |
$CheckTimeoutStart=1200;
|
|
|
37 |
$CheckTimeoutContinue=400;
|
|
|
38 |
|
|
|
39 |
# orario per i log
|
|
|
40 |
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
|
|
41 |
my $time = sprintf("%04d/%02d/%02d %02d:%02d:%02d.%03d", 1900+$year, $mon+1, $mday, $hour, $min, $sec, $2);
|
|
|
42 |
|
|
|
43 |
my $DEBUG=1;
|
|
|
44 |
umask '0007';
|
|
|
45 |
use POSIX 'setsid';
|
|
|
46 |
use IO::Select;
|
|
|
47 |
use IO::Socket::INET;
|
|
|
48 |
|
|
|
49 |
my $samba_group = getgrnam('samba');
|
|
|
50 |
|
16 |
gdo |
51 |
|
11 |
gdo |
52 |
# =============================================================== SHARE
|
|
|
53 |
if($Machine eq $Server){
|
|
|
54 |
# create share if not exist
|
|
|
55 |
# usata per l'autenticazione di squid
|
|
|
56 |
if( ! -d "/home/samba/machine/$IPmachine"){
|
|
|
57 |
new_dir("/home/samba/machine/$IPmachine", 0750);
|
|
|
58 |
symlink "/etc/samba/addons/proxyauth", "/home/samba/machine/$IPmachine/proxyauth";
|
|
|
59 |
}
|
|
|
60 |
$DEBUG && warn "calling machine is server $Server\n";
|
|
|
61 |
exit 0;
|
|
|
62 |
}
|
|
|
63 |
# create share if not exist
|
|
|
64 |
if( ! -d "/home/samba/machine/$IPmachine"){
|
|
|
65 |
new_dir("/home/samba/machine/$IPmachine", 0750);
|
|
|
66 |
new_dir("/home/samba/machine/$IPmachine/.system", 0750);
|
|
|
67 |
symlink "/etc/samba/addons/config.reg", "/home/samba/machine/$IPmachine/.system/.config.reg";
|
|
|
68 |
new_dir("/home/samba/machine/$IPmachine/.system/.logs", 0730);
|
|
|
69 |
}
|
|
|
70 |
|
|
|
71 |
# individuo indirizzo IP del Server
|
16 |
gdo |
72 |
$NET=$IPmachine;
|
|
|
73 |
$NET=~s/\.(\d+)$/./;
|
|
|
74 |
open IFCONFIG, "ifconfig |";
|
|
|
75 |
while(<IFCONFIG>){
|
|
|
76 |
### inet addr:192.168.8.120 Bcast:192.168.8.255 Mask:255.255.255.0
|
|
|
77 |
if(m/inet addr:(\d+\.\d+\.\d+\.\d+)\s+Bcast:$NET/){
|
|
|
78 |
$IP_SERVER=$1;
|
11 |
gdo |
79 |
last;
|
16 |
gdo |
80 |
}
|
11 |
gdo |
81 |
}
|
16 |
gdo |
82 |
close IFCONFIG;
|
|
|
83 |
($IP_SERVER) || die "No server IP on network $NET\n";
|
11 |
gdo |
84 |
|
16 |
gdo |
85 |
# individuo indirizzo IP del Server
|
|
|
86 |
#use Net::DNS;
|
|
|
87 |
#my $res = new Net::DNS::Resolver;
|
|
|
88 |
#my $query = $res->search($Server);
|
|
|
89 |
#if($query){
|
|
|
90 |
# foreach my $rr ($query->answer) {
|
|
|
91 |
# next unless $rr->type eq "A";
|
|
|
92 |
# $IP_SERVER=$rr->address;
|
|
|
93 |
# last;
|
|
|
94 |
# }
|
|
|
95 |
#}else{
|
|
|
96 |
# print STDERR "no dns\n";
|
|
|
97 |
# die "query failed: ", $res->errorstring, "\n";
|
|
|
98 |
#}
|
|
|
99 |
|
11 |
gdo |
100 |
# =============================================================== SQL CONNECTION
|
|
|
101 |
use DBI;
|
|
|
102 |
my $dbh = DBI->connect('dbi:Pg:dbname=cms;host=localhost', 'cms', 'cmsutil') || die "DBI Error open database: ".DBI::errstr."\n";
|
|
|
103 |
$dbh->{RaiseError} = 1;
|
|
|
104 |
$dbh->{InactiveDestroy} = 1;
|
|
|
105 |
$dbh->{AutoCommit} = 1;
|
|
|
106 |
$dbh->do('set DateStyle to SQL, EUROPEAN');
|
|
|
107 |
# =============================================================== LOAD DATA
|
|
|
108 |
my $sthloadip = $dbh->prepare("select pcname, pcstatus, usrid, id, osversion from classlayout where pcip = ? and pcstatus != 'PCBLANK'");
|
|
|
109 |
my $sthloaduser = $dbh->prepare("select pcname, pcstatus, pcip from classlayout where usrid = ? and pcstatus != 'PCBLANK'");
|
|
|
110 |
my $sthuser = $dbh->prepare('select profile from usr where id=?');
|
|
|
111 |
my $sthipteacher = $dbh->prepare("select class.id as class,cl1.id as site,ipteacher from class,classlayout as cl1, classlayout as cl2 where ipteacher=cl1.pcip and cl1.id=cl2.id and cl2.pcip=?");
|
|
|
112 |
my $sthuserroom = $dbh->prepare("select class.id as class, classlayout.id as roomteacher, cl.id as room, classlayout.pcname as pcteacher, class.ipteacher as ipteacher from class,classlayout,usrclass,classlayout as cl where classlayout.pcip=class.ipteacher and class.id=usrclass.classid and usrclass.usrid=? and cl.pcip=? and (classlayout.id=cl.id or cl.id=class.classroompersistent)");
|
|
|
113 |
|
|
|
114 |
# =============================================================== UPDATE DATA
|
|
|
115 |
my $sthupdate = $dbh->prepare('update classlayout set pcname = ?, pcstatus = ?, usrid = ?, connect = ? where pcip = ?');
|
|
|
116 |
my $sthstatus = $dbh->prepare('update classlayout set pcstatus = ? where pcip = ?');
|
|
|
117 |
my $sthosversion = $dbh->prepare('update classlayout set osversion = ? where pcip = ?');
|
|
|
118 |
|
|
|
119 |
sub copy_file($$$){
|
|
|
120 |
my($source, $dest, $perm)=@_;
|
|
|
121 |
# copio il file
|
|
|
122 |
system 'cp', $source, $dest;
|
|
|
123 |
chmod $perm, $dest;
|
|
|
124 |
chown 0, $samba_group, $dest;
|
|
|
125 |
}
|
|
|
126 |
sub new_dir($$){
|
|
|
127 |
my($name,$perm)=@_;
|
|
|
128 |
mkdir $name;
|
|
|
129 |
chmod $perm, $name;
|
|
|
130 |
chown 0, $samba_group, $name;
|
|
|
131 |
}
|
|
|
132 |
|
|
|
133 |
# delete previous file
|
|
|
134 |
my $LOG="/home/samba/machine/$IPmachine/.system/.logs/.$IPmachine.log";
|
|
|
135 |
if(-f $LOG){
|
|
|
136 |
unlink $LOG;
|
|
|
137 |
}
|
|
|
138 |
my $STARTUP="/home/samba/machine/$IPmachine/.system/.startup.bat";
|
|
|
139 |
my $LOGON="/home/samba/machine/$IPmachine/.system/.logon.bat";
|
|
|
140 |
|
16 |
gdo |
141 |
# if(-f $LOGON){
|
|
|
142 |
# unlink $LOGON;
|
|
|
143 |
# }
|
11 |
gdo |
144 |
|
16 |
gdo |
145 |
# if(-f $STARTUP){
|
|
|
146 |
# unlink $STARTUP;
|
|
|
147 |
# }
|
11 |
gdo |
148 |
|
|
|
149 |
my $OTU="/home/samba/machine/$IPmachine/.system/.otu.exe";
|
|
|
150 |
my $POWEROFF="/home/samba/machine/$IPmachine/.system/.poweroff.exe";
|
|
|
151 |
|
|
|
152 |
if( $Mode eq '-preexec'){
|
|
|
153 |
$DEBUG && print STDERR "preexec $IPmachine $User $Machine $time $Platform\n";
|
|
|
154 |
# link <group>.POL to CONFIG.POL
|
|
|
155 |
my $configpol = "/home/samba/machine/$IPmachine/CONFIG.POL";
|
|
|
156 |
unlink $configpol;
|
|
|
157 |
if( -f "/etc/samba/addons/$User.pol"){
|
|
|
158 |
symlink "/etc/samba/addons/$User.pol", $configpol;
|
|
|
159 |
}else{
|
|
|
160 |
if( -f "/etc/samba/addons/$Group.pol"){
|
|
|
161 |
symlink "/etc/samba/addons/$Group.pol", $configpol;
|
|
|
162 |
}else{
|
|
|
163 |
# standard CONFIG.POL
|
|
|
164 |
symlink "/etc/samba/addons/config.pol", $configpol;
|
|
|
165 |
}
|
|
|
166 |
}
|
|
|
167 |
# profilo utente
|
|
|
168 |
$sthuser->execute($User);
|
|
|
169 |
my($UserProfile) = $sthuser->fetchrow_array;
|
|
|
170 |
$DEBUG && print STDERR "user '$User' with profile '$UserProfile'\n";
|
|
|
171 |
# verifico se c'è già un utente connesso con lo stesso login
|
|
|
172 |
$sthloadip->execute($IPmachine);
|
|
|
173 |
my @rowip = $sthloadip->fetchrow_array;
|
|
|
174 |
if(@rowip){
|
|
|
175 |
my($pcname, $pcstatus, $usrid, $id, $osversion)=@rowip;
|
|
|
176 |
# esiste il record
|
|
|
177 |
if($usrid eq $User && $pcstatus eq 'PCLOGON' ){
|
|
|
178 |
# utente gia connesso su quella stessa macchina
|
|
|
179 |
$DEBUG && print STDERR "preexec: user $User already connected on same machine $pcname\n";
|
|
|
180 |
exit;
|
|
|
181 |
}else{
|
|
|
182 |
if(lc $UserProfile eq 'student'){
|
|
|
183 |
# verifico se l'utente è realmente connesso sul PC di indirizzo IP
|
|
|
184 |
$sthloaduser->execute($User); # select pcname, pcstatus, pcip from classlayout where usrid = ?
|
|
|
185 |
while(my @rowuser = $sthloaduser->fetchrow_array){
|
|
|
186 |
my($pcname2, $pcstatus2, $pcip2)=@rowuser;
|
|
|
187 |
if($pcip2 ne $IPmachine){
|
|
|
188 |
# utente probabilmente gia allocato su altro PC
|
|
|
189 |
# verifico se la connessione è ancora attiva
|
|
|
190 |
my $newstatus = &status_machine($pcip2);
|
|
|
191 |
# aggiorno il record relativo
|
|
|
192 |
my $newuser = $User;
|
|
|
193 |
if($newstatus ne 'PCLOGON' && $newstatus ne 'ERROR'){
|
|
|
194 |
$sthupdate->execute($pcname2, $newstatus, '', undef, $pcip2);
|
|
|
195 |
}
|
|
|
196 |
if($newstatus eq 'PCLOGON'){
|
|
|
197 |
$DEBUG && print STDERR "preexec: utente studente $User già connesso in $rowuser[0] ip:$pcip2\n";
|
|
|
198 |
$sthupdate->execute($Machine, 'PCON', $User, $undef, $IPmachine);
|
|
|
199 |
my $action='logoff';
|
|
|
200 |
if($osversion =~ m/ 95| 98| Millennium/i){
|
|
|
201 |
$action=undef;
|
|
|
202 |
}
|
|
|
203 |
&message_machine($IPmachine, $action, "utente studente $User già connesso su PC $pcname2");
|
|
|
204 |
exit 1;
|
|
|
205 |
}
|
|
|
206 |
}
|
|
|
207 |
}
|
|
|
208 |
}
|
|
|
209 |
# aggiorno il record
|
|
|
210 |
$sthupdate->execute($Machine, 'PCLOGIN', $User, $date.' '.$time, $IPmachine);
|
|
|
211 |
}
|
|
|
212 |
}else{
|
|
|
213 |
# richiesta di connessione da host non riconosciuto
|
|
|
214 |
if($Group ne 'admin'){
|
|
|
215 |
# se la login è di un utente diverso da tecnico non accetto ...
|
|
|
216 |
$DEBUG && print STDERR "preexec: richiesta connessione da host '$IPmachine' sconosciuto\n";
|
|
|
217 |
$sthupdate->execute($Machine, 'PCON', $User, $undef, $IPmachine);
|
|
|
218 |
exit 1;
|
|
|
219 |
}
|
|
|
220 |
}
|
|
|
221 |
# verifico se l'utente studente connesso sta connettendosi nella stessa aula del docente oppure dall'aula permanente
|
|
|
222 |
if(lc $UserProfile eq 'student'){
|
|
|
223 |
# devo consultare le classi a cui appartiene l'utente e individuare la classe attiva di appartenenza
|
|
|
224 |
# verifico che l'indirizzo IP sia nella stessa aula
|
|
|
225 |
$sthuserroom->execute($User,$IPmachine);
|
|
|
226 |
my @rowip = $sthuserroom->fetchrow_array;
|
|
|
227 |
if(@rowip){
|
|
|
228 |
my($class, $roomteacher, $room, $pcteacher, $ipteacher)=@rowip;
|
|
|
229 |
$DEBUG && print STDERR "preexec: richiesta connessione utente $User da $IPmachine accettata ".
|
|
|
230 |
"(classe $class, aula $room; docente da pc $pcteacher:$ipteacher, aula $roomteacher)\n";
|
|
|
231 |
}else{
|
|
|
232 |
$DEBUG && print STDERR "preexec: richiesta connessione utente $User da $IPmachine rifiutata; nessuna classe attiva o persistente\n";
|
|
|
233 |
exit 1;
|
|
|
234 |
}
|
|
|
235 |
}
|
16 |
gdo |
236 |
open LOG, ">$LOG" || die "Errore [$!] apertura file '$LOG'\n";
|
11 |
gdo |
237 |
close LOG;
|
|
|
238 |
chmod 0660, $LOG;
|
|
|
239 |
chown 0, $samba_group, $LOG;
|
|
|
240 |
|
|
|
241 |
# creo file otu.exe per il controllo remoto e per avere un file aperto che occupi la share [netlogon]
|
|
|
242 |
if( ! -f $OTU){
|
|
|
243 |
# copio l'eseguibile otu.exe
|
|
|
244 |
symlink "/opt/cms/lib/otu.exe", $OTU;
|
|
|
245 |
}
|
|
|
246 |
# creo/aggiorno il file di logon
|
|
|
247 |
# Windows XP non esegue lo startup indicato nelle policy; lo eseguo invece dallo script di logon
|
16 |
gdo |
248 |
open CMD, ">$LOGON" || die "Errore [$!] apertura file '$LOGON'\n";
|
11 |
gdo |
249 |
# print CMD "net use P: /HOME /YES\r\n";
|
|
|
250 |
print CMD "net use H: \\\\$Server\\HOME /YES\r\n";
|
|
|
251 |
print CMD "net use N: \\\\$Server\\NETLOGON /YES\r\n";
|
|
|
252 |
if($Platform =~ m/Win2k/i ){
|
|
|
253 |
print CMD "start N:\\.system\\.startup.bat\r\n";
|
|
|
254 |
$startVnc=0; # disabilito il lancio di VNC dal Server
|
|
|
255 |
}
|
|
|
256 |
close CMD;
|
|
|
257 |
# permessi file di logon
|
|
|
258 |
chmod 0660, $LOGON;
|
|
|
259 |
chown 0, $samba_group, $LOGON;
|
|
|
260 |
|
|
|
261 |
# creo/aggiorno il file di startup che verrà eseguito dal PC client
|
16 |
gdo |
262 |
open CMD, ">$STARTUP" || die "Errore [$!] apertura file '$STARTUP'\n";;
|
11 |
gdo |
263 |
print CMD <<__CMD__;
|
|
|
264 |
\@ECHO OFF\r
|
|
|
265 |
REM net use N: \\\\$Server\\netlogon /YES\r
|
|
|
266 |
REM start N:\\.system\\.otu.exe -h 1 -p 50001 -a $IP_SERVER\r
|
|
|
267 |
REM net use P: /HOME /YES\r
|
|
|
268 |
REM net use S: \\\\$Server\\segreteria /YES\r
|
|
|
269 |
regedit /S N:\\.system\\.config.reg\r
|
|
|
270 |
ver >N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
271 |
__CMD__
|
|
|
272 |
if($Platform !~ m/Win2k/i ){
|
|
|
273 |
print CMD "net time \\\\$Server >>N:\\.system\\.logs\\.$IPmachine.log\r\n";
|
|
|
274 |
}
|
|
|
275 |
print CMD <<__CMD__;
|
|
|
276 |
if "\%OS\%" == "Windows_NT" goto NT\r
|
|
|
277 |
net config /Y >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
278 |
goto END\r
|
|
|
279 |
:NT\r
|
|
|
280 |
net config Workstation /Y >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
281 |
:END\r
|
|
|
282 |
REM echo logon $IPmachine $$ >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
283 |
__CMD__
|
|
|
284 |
# riga che verrà intercettata nella fase finale del logon
|
|
|
285 |
print CMD "echo logon $IPmachine $$ >>N:\\.system\\.logs\\.$IPmachine.log\r\n";
|
|
|
286 |
if($inst_poweroff){
|
|
|
287 |
# verifico se è attivo poweroff (utilizzato per controllare lo spegnimento o reboot del PC)
|
|
|
288 |
# apertura connessione con il PC
|
|
|
289 |
my $sock = IO::Socket::INET->new(PeerAddr => $IPmachine,
|
|
|
290 |
PeerPort => 50000,
|
|
|
291 |
Proto => 'tcp',
|
|
|
292 |
Timeout => 15 );
|
|
|
293 |
if($sock){
|
|
|
294 |
my $sel = new IO::Select($sock);
|
|
|
295 |
# leggo il canale con un timeout di 5 secondi
|
|
|
296 |
my @ready = $sel->can_read(5);
|
|
|
297 |
if(@ready){
|
|
|
298 |
my $sh = pop @ready;
|
|
|
299 |
my $R = <$sh>;
|
|
|
300 |
if($R =~ m/^201 Welcome to Poweroff 3\.0\.0\.12 created by Jorgen Bosman \(cms path\)$/i){
|
|
|
301 |
print $sock "quit\n";
|
|
|
302 |
my @ready = $sel->can_read(0.5);
|
|
|
303 |
}
|
|
|
304 |
}else{
|
|
|
305 |
$DEBUG && print STDERR "Timeout error on poweroff port\n";
|
|
|
306 |
}
|
|
|
307 |
close($sock);
|
|
|
308 |
}else{
|
|
|
309 |
$DEBUG && print STDERR "no poweroff active\n";
|
|
|
310 |
if( ! -f $POWEROFF){
|
|
|
311 |
# copio l'eseguibile poweroff.exe
|
|
|
312 |
symlink "/opt/cms/lib/poweroff.exe", $POWEROFF;
|
|
|
313 |
}
|
|
|
314 |
# provvedo all'installazione del servizio
|
|
|
315 |
print CMD <<__CMD__;
|
|
|
316 |
echo install poweroff >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
317 |
REM start N:\\.system\\.poweroff.exe -allow_remote -notray -nocancel -force -remote_port 50000 -remote_pswd test -run -quiet -create_service >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
318 |
__CMD__
|
|
|
319 |
if($reboot_poweroff){
|
|
|
320 |
print CMD <<__CMD__;
|
|
|
321 |
start N:\\.system\\.poweroff.exe reboot -warn -msg "Reboot per installazione Controllo Classi" -force -warntime 10 -nocancel -scheduled -seconds 4 -quiet >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
322 |
__CMD__
|
|
|
323 |
}
|
|
|
324 |
}
|
|
|
325 |
}
|
|
|
326 |
#
|
|
|
327 |
$sthipteacher->execute($IPmachine);
|
|
|
328 |
my @rowt = $sthipteacher->fetchrow_array;
|
|
|
329 |
my($CLASSNAME, $SITE, $IP_TEACHER)=@rowt;
|
|
|
330 |
$IP_TEACHER || ($IP_TEACHER='127.0.0.1');
|
|
|
331 |
$listgroups = `/usr/bin/groups $User`;
|
|
|
332 |
chomp $listgroups;
|
|
|
333 |
$listgroups .= ' ';
|
|
|
334 |
$listgroups =~ s/.*://;
|
|
|
335 |
if(lc $UserProfile ne 'student'){
|
|
|
336 |
# verifico che l'utente abbia il gruppo 'cupsadm'
|
|
|
337 |
if($listgroups !~ m/ cupsadm /){
|
|
|
338 |
$listgroups =~ s/^\s+//;
|
|
|
339 |
$listgroups=~s/ /,/g;
|
|
|
340 |
$listgroups.='cupsadm';
|
|
|
341 |
$DEBUG && warn "/usr/sbin/usermod -G '$listgroups' $User\n";
|
|
|
342 |
`/usr/sbin/usermod -G '$listgroups' $User`;
|
|
|
343 |
}
|
|
|
344 |
}else{
|
|
|
345 |
# verifico che lo studente non abbia il gruppo 'cupsadm'
|
|
|
346 |
if($listgroups =~ m/ cupsadm /){
|
|
|
347 |
$listgroups =~ s/ cupsadm //;
|
|
|
348 |
$listgroups =~ s/^\s+//;
|
|
|
349 |
$listgroups =~ s/\s+$//;
|
|
|
350 |
$listgroups =~ s/ /,/g;
|
|
|
351 |
$DEBUG && warn "/usr/sbin/usermod -G '$listgroups' $User\n";
|
|
|
352 |
`/usr/sbin/usermod -G '$listgroups' $User`;
|
|
|
353 |
}
|
|
|
354 |
}
|
|
|
355 |
# verifico se installare VNC e con quale autorizzazioni di accesso
|
|
|
356 |
if($startVnc && ($startVncAll || lc $UserProfile eq 'student') ){
|
|
|
357 |
$DEBUG && print STDERR "run VNC opened from $IP_TEACHER\n";
|
|
|
358 |
# preparo la copia del file da lanciare
|
|
|
359 |
my $VNC="/home/samba/machine/$IPmachine/.system/.vnc";
|
|
|
360 |
if(! -d "$VNC"){
|
|
|
361 |
symlink "/opt/cms/lib/vnc", "/home/samba/machine/$IPmachine/.system/.vnc";
|
|
|
362 |
}
|
|
|
363 |
# genero il file da caricare con regedit
|
16 |
gdo |
364 |
my $VNCFILE="/home/samba/machine/$IPmachine/.system/.vnc.reg";
|
|
|
365 |
open VNC, ">$VNCFILE" || die "Errore [$!] apertura file '$VNCFILE'\n";;
|
11 |
gdo |
366 |
print VNC <<__VNC__;
|
|
|
367 |
REGEDIT4\r
|
|
|
368 |
\r
|
|
|
369 |
[HKEY_LOCAL_MACHINE\\SOFTWARE\\ORL]\r
|
|
|
370 |
\r
|
|
|
371 |
[HKEY_LOCAL_MACHINE\\SOFTWARE\\ORL\\VNC]\r
|
|
|
372 |
\r
|
|
|
373 |
[HKEY_LOCAL_MACHINE\\SOFTWARE\\ORL\\VNC\\3.3.3]\r
|
|
|
374 |
\r
|
|
|
375 |
[HKEY_LOCAL_MACHINE\\SOFTWARE\\ORL\\WinVNC3]\r
|
|
|
376 |
"AuthRequired"=dword:00000000\r
|
|
|
377 |
"AuthHosts"="-:+$IP_SERVER:+$IP_TEACHER"\r
|
|
|
378 |
\r
|
|
|
379 |
[HKEY_LOCAL_MACHINE\\SOFTWARE\\ORL\\WinVNC3\\Default]\r
|
|
|
380 |
"AllowProperties"=dword:00000001\r
|
|
|
381 |
"AllowShutdown"=dword:00000001\r
|
|
|
382 |
\r
|
|
|
383 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks]\r
|
|
|
384 |
\r
|
|
|
385 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs]\r
|
|
|
386 |
\r
|
|
|
387 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\CALC.EXE]\r
|
|
|
388 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
389 |
"use_Timer"=dword:00000000\r
|
|
|
390 |
"use_KeyPress"=dword:00000000\r
|
|
|
391 |
"use_LButtonUp"=dword:00000000\r
|
|
|
392 |
"use_Deferral"=dword:00000001\r
|
|
|
393 |
\r
|
|
|
394 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\CLOCK.EXE]\r
|
|
|
395 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
396 |
"use_Timer"=dword:00000001\r
|
|
|
397 |
"use_KeyPress"=dword:00000000\r
|
|
|
398 |
"use_Deferral"=dword:00000001\r
|
|
|
399 |
"use_LButtonUp"=dword:00000000\r
|
|
|
400 |
\r
|
|
|
401 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\explorer.exe]\r
|
|
|
402 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
403 |
"use_Timer"=dword:00000000\r
|
|
|
404 |
"use_KeyPress"=dword:00000001\r
|
|
|
405 |
"use_Deferral"=dword:00000001\r
|
|
|
406 |
"use_LButtonUp"=dword:00000000\r
|
|
|
407 |
\r
|
|
|
408 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\fpxpress.exe]\r
|
|
|
409 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
410 |
"use_Timer"=dword:00000000\r
|
|
|
411 |
"use_KeyPress"=dword:00000001\r
|
|
|
412 |
"use_Deferral"=dword:00000001\r
|
|
|
413 |
"use_LButtonUp"=dword:00000001\r
|
|
|
414 |
\r
|
|
|
415 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\Ide.exe]\r
|
|
|
416 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
417 |
"use_Timer"=dword:00000000\r
|
|
|
418 |
"use_KeyPress"=dword:00000001\r
|
|
|
419 |
"use_Deferral"=dword:00000001\r
|
|
|
420 |
"use_LButtonUp"=dword:00000001\r
|
|
|
421 |
\r
|
|
|
422 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\iexplore.exe]\r
|
|
|
423 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
424 |
"use_Timer"=dword:00000000\r
|
|
|
425 |
"use_KeyPress"=dword:00000001\r
|
|
|
426 |
"use_Deferral"=dword:00000001\r
|
|
|
427 |
"use_LButtonUp"=dword:00000001\r
|
|
|
428 |
\r
|
|
|
429 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\MSDEV.EXE]\r
|
|
|
430 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
431 |
"use_Timer"=dword:00000000\r
|
|
|
432 |
"use_KeyPress"=dword:00000000\r
|
|
|
433 |
"use_Deferral"=dword:00000001\r
|
|
|
434 |
"use_LButtonUp"=dword:00000001\r
|
|
|
435 |
\r
|
|
|
436 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\mspaint.exe]\r
|
|
|
437 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
438 |
"use_Timer"=dword:00000000\r
|
|
|
439 |
"use_KeyPress"=dword:00000001\r
|
|
|
440 |
"use_LButtonUp"=dword:00000001\r
|
|
|
441 |
"use_Deferral"=dword:00000001\r
|
|
|
442 |
\r
|
|
|
443 |
[HKEY_CURRENT_USER\\Software\\ORL\\VNCHooks\\Application_Prefs\\NOTEPAD.EXE]\r
|
|
|
444 |
"use_GetUpdateRect"=dword:00000001\r
|
|
|
445 |
"use_Timer"=dword:00000000\r
|
|
|
446 |
"use_KeyPress"=dword:00000001\r
|
|
|
447 |
"use_Deferral"=dword:00000001\r
|
|
|
448 |
"use_LButtonUp"=dword:00000001\r
|
|
|
449 |
__VNC__
|
|
|
450 |
close VNC;
|
|
|
451 |
chmod 0640, "/home/samba/machine/$IPmachine/.system/.vnc.reg";
|
|
|
452 |
chown 0, $samba_group, "/home/samba/machine/$IPmachine/.system/.vnc.reg";
|
|
|
453 |
print CMD "regedit /S N:\\.system\\.vnc.reg\r\n";
|
|
|
454 |
if(!$startVncDelay){
|
|
|
455 |
print CMD "start N:\\.system\\.vnc\\winvnc.exe -run\r\n";
|
|
|
456 |
}
|
|
|
457 |
}
|
|
|
458 |
# se l'utente è un docente apro il browser sulla pagina di login dell'applicazione
|
|
|
459 |
# non apro la pagina se il PC è Win2k (problemi rilevati su WinXP)
|
|
|
460 |
if(!$startBrowseDelay && lc $UserProfile eq 'teacher' && $Platform !~ m/Win2k/i){
|
|
|
461 |
print CMD "start http://$Server/cms/\r\n";
|
|
|
462 |
}
|
|
|
463 |
print CMD <<__CMD__;
|
|
|
464 |
echo . >>N:\\.system\\.logs\\.$IPmachine.log\r
|
|
|
465 |
start N:\\.system\\.otu.exe -h 1 -p 50001 -a $IP_SERVER\r
|
|
|
466 |
EXIT\r
|
|
|
467 |
__CMD__
|
|
|
468 |
close CMD;
|
|
|
469 |
chmod 0660, $STARTUP;
|
|
|
470 |
chown 0, $samba_group, $STARTUP;
|
|
|
471 |
# sgancio il processo padre e attendo il completamento del logon sul PC client
|
|
|
472 |
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
|
|
|
473 |
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
|
|
|
474 |
defined(my $pid = fork) or die "Can't fork: $!";
|
|
|
475 |
if($pid){
|
|
|
476 |
# processo padre
|
|
|
477 |
exit 0;
|
|
|
478 |
}
|
|
|
479 |
setsid or die "Can't start a new session: $!";
|
|
|
480 |
$DEBUG && print STDERR "Fork\n";
|
|
|
481 |
# mi preparo a monitorare il file di log
|
|
|
482 |
open SYNC, "<$LOG";
|
|
|
483 |
seek(SYNC, 0, 0);
|
|
|
484 |
my $curpos;
|
|
|
485 |
my $Count=$CheckTimeoutStart;
|
|
|
486 |
my $os_ver;
|
|
|
487 |
LOOP: while($Count--){
|
|
|
488 |
for ($curpos = tell(SYNC); $_ = <SYNC>; $curpos = tell(SYNC)){
|
|
|
489 |
chop;
|
|
|
490 |
$Count=$CheckTimeoutContinue;
|
|
|
491 |
$DEBUG && print STDERR "READ $_\n";
|
|
|
492 |
# salto righe vuote
|
|
|
493 |
next if(m/^\s*$/);
|
|
|
494 |
if(!$os_ver){
|
|
|
495 |
$os_ver=$_;
|
|
|
496 |
}
|
|
|
497 |
if(!$os_ver){
|
|
|
498 |
$os_ver='';
|
|
|
499 |
}
|
|
|
500 |
if(m/^logon (.+) (\d+)/){
|
|
|
501 |
my $IP=$1;
|
|
|
502 |
my $PID=$2;
|
|
|
503 |
$DEBUG && print STDERR "detect $IP $PID\n";
|
|
|
504 |
# verifico che l'informazione registrata durante la fase 'reexec' corrisponda
|
|
|
505 |
$sthloadip->execute($IPmachine);
|
|
|
506 |
my @rowip = $sthloadip->fetchrow_array;
|
|
|
507 |
if(@rowip && $rowip[1] eq 'PCLOGIN'){
|
|
|
508 |
# il Client ha terminato l'esecuzione dello script di logon; posso aggiornare il database
|
|
|
509 |
# cambiando lo stato
|
|
|
510 |
$sthstatus->execute('PCLOGON', $IPmachine);
|
|
|
511 |
$sthosversion->execute($os_ver, $IPmachine);
|
|
|
512 |
}else{
|
|
|
513 |
# sequenza non corretta; non accetto la connessione
|
|
|
514 |
$DEBUG && print STDERR "logon: sequenza non corretta, $rowip[1] != PCLOGIN\n";
|
|
|
515 |
$sthstatus->execute('PCERR', $IPmachine);
|
|
|
516 |
}
|
|
|
517 |
# se l'utente è un docente apro il browser sulla pagina di login dell'applicazione
|
|
|
518 |
if($startBrowseDelay && lc $UserProfile eq 'teacher'){
|
|
|
519 |
select(undef, undef, undef, 4);
|
|
|
520 |
$DEBUG && print STDERR "lancio http://$Server/cms/\n";
|
|
|
521 |
my $err=&call_client($IPmachine, "start http://$Server/cms/");
|
|
|
522 |
$DEBUG && print STDERR "start http://$Server/cms/ err=$err\n";
|
|
|
523 |
}
|
|
|
524 |
# lancio vnc in ritardo qualche secondo ...
|
|
|
525 |
if($startVncDelay && $startVnc && ($startVncAll || lc $UserProfile eq 'student')){
|
|
|
526 |
select(undef, undef, undef, 15);
|
|
|
527 |
$DEBUG && print STDERR "lancio vnc\n";
|
|
|
528 |
my $err=&call_client($IPmachine, "N:\\.system\\.vnc\\winvnc.exe -run");
|
|
|
529 |
$DEBUG && print STDERR "winvnc.exe err=$err\n";
|
|
|
530 |
}
|
|
|
531 |
# unlink $STARTUP, $LOG, $OTU, $POWEROFF;
|
|
|
532 |
exit;
|
|
|
533 |
}
|
|
|
534 |
}
|
|
|
535 |
select(undef, undef, undef, 0.1);
|
|
|
536 |
seek(SYNC, $curpos, 0);
|
|
|
537 |
}
|
|
|
538 |
# unlink $STARTUP, $LOG, $OTU, $POWEROFF;
|
|
|
539 |
$sthstatus->execute('PCTIMEOUT', $IPmachine);
|
|
|
540 |
print STDERR "Timeout read logon for user=$User IP=$IPmachine\n";
|
|
|
541 |
exit;
|
|
|
542 |
}elsif( $Mode eq '-postexec'){
|
|
|
543 |
$DEBUG && print STDERR "postexec $IPmachine -1 $User $Machine $time $Platform\n";
|
|
|
544 |
# il Client ha terminato l'uso della share [netlogon]; posso aggiornare il database
|
|
|
545 |
$sthupdate->execute($Machine, 'PCON', $User, undef, $IPmachine);
|
|
|
546 |
}else{
|
|
|
547 |
|
|
|
548 |
close LOG;
|
|
|
549 |
exit 1;
|
|
|
550 |
}
|
|
|
551 |
close LOG;
|
|
|
552 |
|
|
|
553 |
# esecuzione remota di comandi
|
|
|
554 |
sub call_client{
|
|
|
555 |
my $host = shift;
|
|
|
556 |
my $cmd = join(' ',@_);
|
|
|
557 |
$cmd || ($cmd='-');
|
|
|
558 |
$DEBUG && print STDERR "call_client '$host' with [$cmd]\n";
|
|
|
559 |
return 1 if(!$host);
|
|
|
560 |
my $sock = IO::Socket::INET->new(PeerAddr => $host,
|
|
|
561 |
PeerPort => 50001,
|
|
|
562 |
Proto => 'tcp',
|
|
|
563 |
Timeout => 4 );
|
|
|
564 |
|
|
|
565 |
if(!$sock){
|
|
|
566 |
$DEBUG && print STDERR "\topen sock ($!)";
|
|
|
567 |
if($! eq 'Connection refused'){
|
|
|
568 |
return 2;
|
|
|
569 |
}elsif($! eq 'No route to host'){
|
|
|
570 |
return 3;
|
|
|
571 |
}elsif($! eq 'Operation now in progress'){
|
|
|
572 |
return 4;
|
|
|
573 |
}else{
|
|
|
574 |
return 5;
|
|
|
575 |
}
|
|
|
576 |
}
|
|
|
577 |
my $sel = new IO::Select($sock);
|
|
|
578 |
print $sock "$cmd\n";
|
|
|
579 |
# leggo il canale con un timeout di 2 secondi
|
|
|
580 |
my @ready = $sel->can_read(4);
|
|
|
581 |
if(!@ready){
|
|
|
582 |
close($sock);
|
|
|
583 |
return 6;
|
|
|
584 |
}
|
|
|
585 |
my $sh = pop @ready;
|
|
|
586 |
my $ret = <$sh>;
|
|
|
587 |
chomp $ret;
|
|
|
588 |
close($sock);
|
|
|
589 |
return 7 if $ret !~ m/OK/;
|
|
|
590 |
return 0;
|
|
|
591 |
}
|
|
|
592 |
|
|
|
593 |
# verifica lo stato della macchina
|
|
|
594 |
# PCOFF PCON PCLOGON
|
|
|
595 |
sub status_machine($){
|
|
|
596 |
my $IP=shift;
|
|
|
597 |
# per determinare lo stato della connessione mi affido alla risposta del programma otu.exe
|
|
|
598 |
# installato sul PC client
|
|
|
599 |
my $status = &call_client($IP);
|
|
|
600 |
if($status == 4){
|
|
|
601 |
# ritento una seconda volta
|
|
|
602 |
$status = &call_client($IP);
|
|
|
603 |
}
|
|
|
604 |
if($status eq '0'){
|
|
|
605 |
$status = 'PCLOGON';
|
|
|
606 |
}elsif($status eq '2'){
|
|
|
607 |
$status = 'PCON';
|
|
|
608 |
}elsif($status eq '3'){
|
|
|
609 |
$status = 'PCOFF';
|
|
|
610 |
}elsif($status eq '4'){
|
|
|
611 |
$status = 'PCOFF';
|
|
|
612 |
}else{
|
|
|
613 |
$status = 'ERROR';
|
|
|
614 |
}
|
|
|
615 |
$DEBUG && print STDERR "status_machine($IP)=$status\n";
|
|
|
616 |
return $status;
|
|
|
617 |
}
|
|
|
618 |
|
|
|
619 |
# visualizza un messaggio sul PC remoto
|
|
|
620 |
sub message_machine($$$){
|
|
|
621 |
my($host, $action, $mess)=@_;
|
|
|
622 |
my $simulate;
|
|
|
623 |
if($action){
|
|
|
624 |
$simulate='off';
|
|
|
625 |
}else{
|
|
|
626 |
$simulate='on';
|
|
|
627 |
$action='logoff';
|
|
|
628 |
}
|
|
|
629 |
my $sock = IO::Socket::INET->new(PeerAddr => $host,
|
|
|
630 |
PeerPort => 50000,
|
|
|
631 |
Proto => 'tcp',
|
|
|
632 |
Timeout => 10 );
|
|
|
633 |
return if(!$sock);
|
|
|
634 |
my @dialog = (
|
|
|
635 |
'/^201 Welcome to Poweroff 3\.0\.0\.12 created by Jorgen Bosman \(cms path\)$/i',
|
|
|
636 |
'password test',
|
|
|
637 |
'/^250 OK$/i',
|
|
|
638 |
"action $action",
|
|
|
639 |
'/^250 OK$/i',
|
|
|
640 |
"simulate $simulate",
|
|
|
641 |
'/^250 OK$/i',
|
|
|
642 |
'runprg off',
|
|
|
643 |
'/^250 OK$/i',
|
|
|
644 |
"message $mess",
|
|
|
645 |
'/^250 OK$/i',
|
|
|
646 |
'wait 0',
|
|
|
647 |
'/^250 OK$/i',
|
|
|
648 |
'warning on',
|
|
|
649 |
'/^250 OK$/i',
|
|
|
650 |
'warntime 5',
|
|
|
651 |
'/^250 OK$/i',
|
|
|
652 |
'doit',
|
|
|
653 |
'/^250 OK$/i',
|
|
|
654 |
'quit','/.*/i',
|
|
|
655 |
);
|
|
|
656 |
my $sel = new IO::Select($sock);
|
|
|
657 |
my $Count=0;
|
|
|
658 |
for(;;){
|
|
|
659 |
# leggo il canale con un timeout di 2 secondi
|
|
|
660 |
my @ready = $sel->can_read(2);
|
|
|
661 |
if(!@ready){
|
|
|
662 |
die "Timeout read from host";
|
|
|
663 |
}
|
|
|
664 |
|
|
|
665 |
my $sh = pop @ready;
|
|
|
666 |
my $ret = <$sh>;
|
|
|
667 |
chomp $ret;
|
|
|
668 |
$ret =~ s/\r$//;
|
|
|
669 |
$DEBUG && print STDERR "GET[$ret]\n";
|
|
|
670 |
my $test;
|
|
|
671 |
eval '$test =( $ret =~ '.$dialog[$Count].')';
|
|
|
672 |
if($@){
|
|
|
673 |
die "Error eval[$Count]: $@";
|
|
|
674 |
}
|
|
|
675 |
if($test){
|
|
|
676 |
$Count++;
|
|
|
677 |
last if($Count >= @dialog);
|
|
|
678 |
my $cmd;
|
|
|
679 |
$cmd = $dialog[$Count];
|
|
|
680 |
$DEBUG && print STDERR "PUT[".$cmd."]\n";
|
|
|
681 |
print $sock $cmd."\n";
|
|
|
682 |
$Count++;
|
|
|
683 |
}else{
|
|
|
684 |
die "\nError row $Count: '$ret' don't match '$dialog[$Count]'\n";
|
|
|
685 |
}
|
|
|
686 |
last if($Count >= @dialog);
|
|
|
687 |
}
|
|
|
688 |
close($sock);
|
|
|
689 |
}
|