1 | #!/usr/bin/perl -w |
---|
2 | |
---|
3 | use strict; |
---|
4 | |
---|
5 | use lib 'lib'; |
---|
6 | |
---|
7 | use Ocsinventory::Agent::Config; |
---|
8 | |
---|
9 | |
---|
10 | my $old_linux_agent_dir = "/etc/ocsinventory-client"; |
---|
11 | |
---|
12 | my $config; |
---|
13 | my @cacert; |
---|
14 | my $binpath; |
---|
15 | my $randomtime; |
---|
16 | my $cron_line; |
---|
17 | |
---|
18 | sub loadModules { |
---|
19 | my @modules = @_; |
---|
20 | |
---|
21 | foreach (@modules) { |
---|
22 | eval "use $_;"; |
---|
23 | if ($@) { |
---|
24 | print STDERR "Failed to load $_. Please install it and restart the postinst.pl script ( ./postinst.pl ).\n"; |
---|
25 | exit 1; |
---|
26 | |
---|
27 | } |
---|
28 | } |
---|
29 | |
---|
30 | } |
---|
31 | |
---|
32 | sub ask_yn { |
---|
33 | my $promptUser = shift; |
---|
34 | my $default = shift; |
---|
35 | |
---|
36 | die unless $default =~ /^(y|n)$/; |
---|
37 | |
---|
38 | my $cpt = 5; |
---|
39 | while (1) { |
---|
40 | my $line = prompt("$promptUser\nPlease enter 'y' or 'n'?>", $default); |
---|
41 | return 1 if $line =~ /^y$/; |
---|
42 | return if $line =~ /^n$/; |
---|
43 | if ($cpt-- < 0) { |
---|
44 | print STDERR "to much user input, exit...\n"; |
---|
45 | exit(0); |
---|
46 | } |
---|
47 | } |
---|
48 | } |
---|
49 | |
---|
50 | sub promptUser { |
---|
51 | my ($promptUser, $default, $regex, $notice) = @_; |
---|
52 | |
---|
53 | my $string = $promptUser; |
---|
54 | $string .= "?>"; |
---|
55 | |
---|
56 | my $line; |
---|
57 | my $cpt = 5; |
---|
58 | while (1) { |
---|
59 | |
---|
60 | $line = prompt($string, $default); |
---|
61 | |
---|
62 | if ($regex && $line !~ /$regex/) { |
---|
63 | print STDERR $notice."\n"; |
---|
64 | } else { |
---|
65 | last; |
---|
66 | } |
---|
67 | |
---|
68 | if ($cpt-- < 0) { |
---|
69 | print STDERR "to much user input, exit...\n"; |
---|
70 | exit(0); |
---|
71 | } |
---|
72 | |
---|
73 | } |
---|
74 | |
---|
75 | return $line; |
---|
76 | } |
---|
77 | |
---|
78 | sub pickConfigdir { |
---|
79 | my @choices = @_; |
---|
80 | |
---|
81 | foreach (@choices) { |
---|
82 | |
---|
83 | my $t = $_.'/ocsinventory-agent.cfg'; |
---|
84 | |
---|
85 | if (-f $t) { |
---|
86 | print "Config file found are $t! Reusing it.\n"; |
---|
87 | return $_; |
---|
88 | } |
---|
89 | } |
---|
90 | |
---|
91 | print STDERR "Where do you want to write the configuration file?\n"; |
---|
92 | foreach (0..$#choices) { |
---|
93 | print STDERR " ".$_." -> ".$choices[$_]."\n"; |
---|
94 | } |
---|
95 | my $input = -1; |
---|
96 | my $configdir; |
---|
97 | while (1) { |
---|
98 | $input = prompt("?>"); |
---|
99 | if ($input =~ /^\d+$/ && $input >= 0 && $input <= $#choices) { |
---|
100 | last; |
---|
101 | } else { |
---|
102 | print STDERR "Value must be between 0 and ".$#choices."\n"; |
---|
103 | } |
---|
104 | } |
---|
105 | |
---|
106 | |
---|
107 | if (! -d $choices[$input]) { |
---|
108 | if (ask_yn ("Do you want to create the directory ".$choices[$input]."?", 'y')) { |
---|
109 | if (!mkdir $choices[$input]) { |
---|
110 | print "Failed to create ".$choices[$input].". Are you root?\n"; |
---|
111 | exit 1; |
---|
112 | } |
---|
113 | } else { |
---|
114 | print "Please create the ".$choices[$input]." directory first.\n"; |
---|
115 | exit 1; |
---|
116 | } |
---|
117 | } |
---|
118 | |
---|
119 | return $choices[$input]; |
---|
120 | } |
---|
121 | |
---|
122 | sub recMkdir { |
---|
123 | my $dir = shift; |
---|
124 | |
---|
125 | my @t = split /\//, $dir; |
---|
126 | shift @t; |
---|
127 | return unless @t; |
---|
128 | |
---|
129 | my $t; |
---|
130 | foreach (@t) { |
---|
131 | $t .= '/'.$_; |
---|
132 | if ((!-d $t) && (!mkdir $t)) { |
---|
133 | return; |
---|
134 | } |
---|
135 | } |
---|
136 | 1; |
---|
137 | } |
---|
138 | |
---|
139 | sub mkFullServerUrl { |
---|
140 | |
---|
141 | my $server = shift; |
---|
142 | |
---|
143 | my $ret = 'http://' unless $server =~ /^http(s|):\/\//; |
---|
144 | $ret .= $server; |
---|
145 | |
---|
146 | if ($server !~ /http(|s):\/\/\S+\/\S+/) { |
---|
147 | $ret .= '/ocsinventory'; |
---|
148 | } |
---|
149 | |
---|
150 | return $ret; |
---|
151 | |
---|
152 | } |
---|
153 | |
---|
154 | |
---|
155 | #################################################### |
---|
156 | ################### main ########################### |
---|
157 | #################################################### |
---|
158 | |
---|
159 | loadModules (qw/XML::Simple ExtUtils::MakeMaker/); |
---|
160 | |
---|
161 | if (!ask_yn("Do you want to configure the agent", 'y')) { |
---|
162 | exit 0; |
---|
163 | } |
---|
164 | |
---|
165 | |
---|
166 | my $configdir = pickConfigdir ("/etc/ocsinventory", "/usr/local/etc/ocsinventory", "/etc/ocsinventory-agent"); |
---|
167 | |
---|
168 | if (-f $old_linux_agent_dir.'/ocsinv.conf' && ask_yn("Should the old linux_agent settings be imported?", 'y')) { |
---|
169 | my $ocsinv = XMLin($old_linux_agent_dir.'/ocsinv.conf'); |
---|
170 | $config->{server} = mkFullServerUrl($ocsinv->{'OCSFSERVER'}); |
---|
171 | |
---|
172 | if (-f $old_linux_agent_dir.'/cacert.pem') { |
---|
173 | open CACERT, $old_linux_agent_dir.'/cacert.pem' or die "Can'i import the CA certificat: ".$!; |
---|
174 | @cacert = <CACERT>; |
---|
175 | close CACERT; |
---|
176 | } |
---|
177 | |
---|
178 | my $admcontent = ''; |
---|
179 | |
---|
180 | |
---|
181 | if (-f "$old_linux_agent_dir/ocsinv.adm") { |
---|
182 | if (!open(ADM, "<:encoding(iso-8859-1)", "$old_linux_agent_dir/ocsinv.adm")) { |
---|
183 | warn "Can't open $old_linux_agent_dir/ocsinv.adm"; |
---|
184 | } else { |
---|
185 | $admcontent .= $_ foreach (<ADM>); |
---|
186 | close ADM; |
---|
187 | my $admdata = XMLin($admcontent) or die; |
---|
188 | if (ref ($admdata->{ACCOUNTINFO}) eq 'ARRAY') { |
---|
189 | foreach (@{$admdata->{ACCOUNTINFO}}) { |
---|
190 | $config->{tag} = $_->{KEYVALUE} if $_->{KEYNAME} =~ /^TAG$/; |
---|
191 | } |
---|
192 | } elsif ( |
---|
193 | exists($admdata->{ACCOUNTINFO}->{KEYNAME}) && |
---|
194 | exists($admdata->{ACCOUNTINFO}->{KEYVALUE}) && |
---|
195 | $admdata->{ACCOUNTINFO}->{KEYNAME} eq 'TAG' |
---|
196 | ) { |
---|
197 | print $admdata->{ACCOUNTINFO}->{KEYVALUE}."\n"; |
---|
198 | $config->{tag} = $admdata->{ACCOUNTINFO}->{KEYVALUE}; |
---|
199 | } |
---|
200 | } |
---|
201 | } |
---|
202 | } |
---|
203 | |
---|
204 | if (-f $configdir."/ocsinventory-agent.cfg") { |
---|
205 | open (CONFIG, "<".$configdir."/ocsinventory-agent.cfg") or |
---|
206 | die "Can't open ".$configdir."/ocsinventory-agent.cfg: ".$!; |
---|
207 | |
---|
208 | foreach (<CONFIG>) { |
---|
209 | s/#.+//; |
---|
210 | if (/(\w+)\s*=\s*(.+)/) { |
---|
211 | my $key = $1; |
---|
212 | my $val = $2; |
---|
213 | # Remove the quotes |
---|
214 | $val =~ s/\s+$//; |
---|
215 | $val =~ s/^'(.*)'$/$1/; |
---|
216 | $val =~ s/^"(.*)"$/$1/; |
---|
217 | $config->{$key} = $val; |
---|
218 | } |
---|
219 | } |
---|
220 | close CONFIG; |
---|
221 | } |
---|
222 | |
---|
223 | print "[info] The config file will be written in /etc/ocsinventory/ocsinventory-agent.cfg,\n"; |
---|
224 | |
---|
225 | my $tmp = promptUser('What is the address of your ocs server', exists ($config->{server})?$config->{server}:'ocsinventory-ng'); |
---|
226 | $config->{server} = mkFullServerUrl($tmp); |
---|
227 | if (!$config->{server}) { |
---|
228 | print "Server is empty. Leaving...\n"; |
---|
229 | exit 1; |
---|
230 | } |
---|
231 | my $uri; |
---|
232 | if ($config->{server} =~ /^http(|s):\/\//) { |
---|
233 | $uri = $config->{server}; |
---|
234 | } else { # just the hostname |
---|
235 | $uri = "http://".$config->{server}."/ocsinventory" |
---|
236 | } |
---|
237 | |
---|
238 | if (ask_yn ("Do you need credential for the server? (You probably don't)", 'n')) { |
---|
239 | $config->{user} = promptUser("user", $config->{user}); |
---|
240 | $config->{password} = promptUser("password"); |
---|
241 | print "[info] The realm can be found in the login popup of your Internet browser.\n[info] In general, it's something like 'Restricted Area'.\n"; |
---|
242 | $config->{realm} = promptUser("realm"); |
---|
243 | } else { |
---|
244 | delete ($config->{user}); |
---|
245 | delete ($config->{password}); |
---|
246 | delete ($config->{realm}); |
---|
247 | } |
---|
248 | |
---|
249 | if (ask_yn('Do you want to apply an administrative tag on this machine', 'y')) { |
---|
250 | |
---|
251 | $config->{tag} = promptUser("tag", $config->{tag}); |
---|
252 | } else { |
---|
253 | delete($config->{tag}); |
---|
254 | } |
---|
255 | |
---|
256 | |
---|
257 | chomp($binpath = `which ocsinventory-agent 2>/dev/null`); |
---|
258 | if (! -x $binpath) { |
---|
259 | # Packaged version with perl and agent ? |
---|
260 | $binpath = $^X; |
---|
261 | $binpath =~ s/perl/ocsinventory-agent/; |
---|
262 | } |
---|
263 | |
---|
264 | if (! -x $binpath) { |
---|
265 | print "sorry, can't find ocsinventory-agent in \$PATH\n"; |
---|
266 | exit 1; |
---|
267 | } else { |
---|
268 | print "ocsinventory agent presents: $binpath\n"; |
---|
269 | } |
---|
270 | |
---|
271 | |
---|
272 | $randomtime = int(rand(60)).' '.int(rand(24)); |
---|
273 | $cron_line = $randomtime." * * * root $binpath --lazy > /dev/null 2>&1\n"; |
---|
274 | |
---|
275 | if ($^O =~ /solaris/) { |
---|
276 | if (ask_yn("Do yo want to install the cron task in current user crontab ?", 'y')) { |
---|
277 | my $crontab = `crontab -l`; |
---|
278 | |
---|
279 | # Let's suppress Linux cron/anacron user column |
---|
280 | $cron_line =~ s/ root / /; |
---|
281 | $crontab .= $cron_line; |
---|
282 | |
---|
283 | open CRONP, "| crontab" || die "Can't run crontab: $!"; |
---|
284 | print CRONP $crontab; |
---|
285 | close(CRONP); |
---|
286 | |
---|
287 | } |
---|
288 | } |
---|
289 | elsif (-d "/etc/cron.d") { |
---|
290 | if (ask_yn("Do yo want to install the cron task in /etc/cron.d", 'y')) { |
---|
291 | |
---|
292 | open DEST, '>/etc/cron.d/ocsinventory-agent' or die $!; |
---|
293 | # Save the root PATH |
---|
294 | print DEST "PATH=".$ENV{PATH}."\n"; |
---|
295 | print DEST $randomtime." * * * root $binpath --lazy > /dev/null 2>&1\n"; |
---|
296 | close DEST; |
---|
297 | } |
---|
298 | } |
---|
299 | |
---|
300 | my $default_vardir; |
---|
301 | if ($^O =~ /solaris/) { |
---|
302 | $default_vardir = '/var/opt/ocsinventory-agent'; |
---|
303 | } else { |
---|
304 | $default_vardir = '/var/lib/ocsinventory-agent' |
---|
305 | } |
---|
306 | |
---|
307 | $config->{basevardir} = promptUser('Where do you want the agent to store its files? (You probably don\'t need to change it)', exists ($config->{basevardir})?$config->{basevardir}:$default_vardir, '^\/\w+', 'The location must begin with /'); |
---|
308 | |
---|
309 | if (!-d $config->{basevardir}) { |
---|
310 | if (ask_yn ("Do you want to create the ".$config->{basevardir}." directory?\n", 'y')) { |
---|
311 | mkdir $config->{basevardir} or die $!; |
---|
312 | } else { |
---|
313 | print "Please create the ".$config->{basevardir}." directory\n"; |
---|
314 | exit 1; |
---|
315 | } |
---|
316 | } |
---|
317 | |
---|
318 | open CONFIG, ">$configdir/ocsinventory-agent.cfg" or die "Can't write the config file in $configdir: ".$!; |
---|
319 | print CONFIG $_."=".$config->{$_}."\n" foreach (keys %$config); |
---|
320 | close CONFIG; |
---|
321 | chmod 0600, "$configdir/ocsinventory-agent.cfg"; |
---|
322 | |
---|
323 | print "New settings written! Thank you for using OCS Inventory\n"; |
---|
324 | |
---|
325 | if (ask_yn ("Should I remove the old linux_agent", 'n')) { |
---|
326 | foreach (qw# |
---|
327 | /etc/ocsinventory-client |
---|
328 | /etc/logrotate.d/ocsinventory-client |
---|
329 | /usr/sbin/ocsinventory-client.pl |
---|
330 | /etc/cron.d/ocsinventory-client |
---|
331 | /bin/ocsinv |
---|
332 | #) { |
---|
333 | print $_."\n"; |
---|
334 | next; |
---|
335 | rmdir if -d; |
---|
336 | unlink if -f || -l; |
---|
337 | } |
---|
338 | print "done\n" |
---|
339 | } |
---|
340 | |
---|
341 | # Create the vardirectory for this server |
---|
342 | my $dir = $config->{server}; |
---|
343 | $dir =~ s/\//_/g; |
---|
344 | my $vardir = $config->{basevardir}."/".$dir; |
---|
345 | recMkdir($vardir) or die "Can't create $vardir!"; |
---|
346 | |
---|
347 | if (@cacert) { # we need to migrate the certificat |
---|
348 | open CACERT, ">".$vardir."/cacert.pem" or die "Can't open ".$vardir.'/cacert.pem: '.$!; |
---|
349 | print CACERT foreach (@cacert); |
---|
350 | close CACERT; |
---|
351 | print "Certificat copied in ".$vardir."/cacert.pem\n"; |
---|
352 | } |
---|
353 | |
---|
354 | my $download_enable = ask_yn("Do you want to use OCS-Inventory software deployment feature?", 'y'); |
---|
355 | my $snmp_enable = ask_yn("Do you want to use OCS-Inventory SNMP scans feature?", 'y'); |
---|
356 | |
---|
357 | open MODULE, ">$configdir/modules.conf" or die "Can't write modules.conf in $configdir: ".$!; |
---|
358 | print MODULE "# this list of module will be load by the at run time\n"; |
---|
359 | print MODULE "# to check its syntax do:\n"; |
---|
360 | print MODULE "# #perl modules.conf\n"; |
---|
361 | print MODULE "# You must have NO error. Else the content will be ignored\n"; |
---|
362 | print MODULE "# This mechanism goal is to launch agent extension modules\n"; |
---|
363 | print MODULE "\n"; |
---|
364 | print MODULE ($download_enable?'':'#'); |
---|
365 | print MODULE "use Ocsinventory::Agent::Modules::Download;\n"; |
---|
366 | print MODULE ($snmp_enable?'':'#'); |
---|
367 | print MODULE "use Ocsinventory::Agent::Modules::Snmp;\n"; |
---|
368 | print MODULE "\n"; |
---|
369 | print MODULE "# DO NOT REMOVE THE 1;\n"; |
---|
370 | print MODULE "1;\n"; |
---|
371 | close MODULE; |
---|
372 | |
---|
373 | |
---|
374 | #Prevent security risks by removing existing snmp_com.txt file which is no longer used |
---|
375 | my $snmp_com_file = $vardir."/snmp/snmp_com.txt"; |
---|
376 | if ( -f $snmp_com_file ) { |
---|
377 | print "$snmp_com_file seems to exists...removing it to prevent security risks !\n"; |
---|
378 | unlink $snmp_com_file; |
---|
379 | } |
---|
380 | |
---|
381 | |
---|
382 | if (ask_yn("Do you want to send an inventory of this machine?", 'y')) { |
---|
383 | system("$binpath --force"); |
---|
384 | if (($? >> 8)==0) { |
---|
385 | print " -> Success!\n"; |
---|
386 | } else { |
---|
387 | print " -> Failed!\n"; |
---|
388 | print "You may want to launch the agent with the --verbose or --debug flag.\n"; |
---|
389 | } |
---|
390 | } |
---|