Commit | Line | Data |
478358f5 |
1 | package System::Introspector::Sudoers; |
2 | use Moo; |
3 | |
4 | has sudoers_file => ( |
5 | is => 'ro', |
6 | default => sub { '/etc/sudoers' }, |
7 | ); |
8 | |
9 | has hostname => ( |
10 | is => 'ro', |
11 | default => sub { scalar `hostname` }, |
12 | ); |
13 | |
14 | sub gather { |
15 | my ($self) = @_; |
16 | my %file = $self->_gather_files($self->sudoers_file); |
17 | return \%file; |
18 | } |
19 | |
20 | sub _gather_files { |
21 | my ($self, $file) = @_; |
22 | open my $fh, '<', $file |
23 | or return $file => { error => "Unable to read: $!" }; |
24 | my @lines = <$fh>; |
25 | my %file = ($file => { body => join '', @lines }); |
26 | for my $line (@lines) { |
27 | chomp $line; |
28 | if ($line =~ m{^#include\s+(.+)$}) { |
29 | my $inc_file = $self->_insert_hostname($1); |
30 | %file = (%file, $self->_gather_files($inc_file)); |
31 | } |
32 | elsif ($line =~ m{^#includedir\s+(.+)$}) { |
33 | my $inc_dir = $self->_insert_hostname($1); |
34 | %file = (%file, $self->_gather_from_dir($inc_dir)); |
35 | } |
36 | } |
37 | return %file; |
38 | } |
39 | |
40 | sub _gather_from_dir { |
41 | my ($self, $dir) = @_; |
42 | opendir(my $dh, $dir); |
43 | return $dir => { error => "Unable to read dir $dir: $!" } |
44 | unless $dh; |
45 | my %file; |
46 | while (my $file = readdir $dh) { |
47 | next if $file =~ m{\.} or $file =~ m{~$}; |
48 | %file = (%file, $self->_gather_files("$dir/$file")); |
49 | } |
50 | return %file; |
51 | } |
52 | |
53 | sub _insert_hostname { |
54 | my ($self, $value) = @_; |
55 | my $hostname = $self->hostname; |
56 | $value =~ s{\%h}{$hostname}g; |
57 | return $value; |
58 | } |
59 | |
60 | 1; |