Commit | Line | Data |
478358f5 |
1 | package System::Introspector::Sudoers; |
2 | use Moo; |
3 | |
da47168a |
4 | use System::Introspector::Util qw( |
5 | handle_from_command |
6 | files_from_dir |
7 | output_from_file |
8 | transform_exceptions |
9 | ); |
10 | |
478358f5 |
11 | has sudoers_file => ( |
12 | is => 'ro', |
13 | default => sub { '/etc/sudoers' }, |
14 | ); |
15 | |
16 | has hostname => ( |
17 | is => 'ro', |
18 | default => sub { scalar `hostname` }, |
19 | ); |
20 | |
21 | sub gather { |
22 | my ($self) = @_; |
23 | my %file = $self->_gather_files($self->sudoers_file); |
24 | return \%file; |
25 | } |
26 | |
27 | sub _gather_files { |
28 | my ($self, $file) = @_; |
da47168a |
29 | my $result = transform_exceptions { |
30 | my @lines = output_from_file $file; |
31 | my @result = ({ body => join '', @lines }); |
32 | for my $line (@lines) { |
33 | chomp $line; |
34 | if ($line =~ m{^#include\s+(.+)$}) { |
35 | my $inc_file = $self->_insert_hostname($1); |
36 | push @result, $self->_gather_files($inc_file); |
37 | } |
38 | elsif ($line =~ m{^#includedir\s+(.+)$}) { |
39 | my $inc_dir = $self->_insert_hostname($1); |
40 | push @result, $self->_gather_from_dir($inc_dir); |
41 | } |
478358f5 |
42 | } |
da47168a |
43 | return \@result; |
44 | }; |
480d348a |
45 | return $file => $result |
46 | if ref $result eq 'HASH'; |
da47168a |
47 | return $file => @$result; |
478358f5 |
48 | } |
49 | |
50 | sub _gather_from_dir { |
51 | my ($self, $dir) = @_; |
da47168a |
52 | my @files = files_from_dir $dir; |
478358f5 |
53 | my %file; |
da47168a |
54 | for my $file (@files) { |
478358f5 |
55 | next if $file =~ m{\.} or $file =~ m{~$}; |
56 | %file = (%file, $self->_gather_files("$dir/$file")); |
57 | } |
58 | return %file; |
59 | } |
60 | |
61 | sub _insert_hostname { |
62 | my ($self, $value) = @_; |
63 | my $hostname = $self->hostname; |
64 | $value =~ s{\%h}{$hostname}g; |
65 | return $value; |
66 | } |
67 | |
68 | 1; |
535e84b6 |
69 | |
70 | __END__ |
71 | |
72 | =head1 NAME |
73 | |
74 | System::Introspector::Sudoers - Gather sudoer information |
75 | |
76 | =head1 DESCRIPTION |
77 | |
78 | Reads C<sudoers> files to gather information about sudo abilities. This |
79 | probe will also read all included files. |
80 | |
81 | =head1 ATTRIBUTES |
82 | |
83 | =head2 sudoers_file |
84 | |
85 | The path to the original C<sudoers> file that should be read. Includes from this |
86 | file will be followed and provided as well. |
87 | |
88 | =head2 hostname |
89 | |
90 | The hostname used to resolve C<%h> hostname markers in inclusions. |
91 | |
92 | =head1 SEE ALSO |
93 | |
94 | =over |
95 | |
96 | =item L<System::Introspector> |
97 | |
98 | =back |
99 | |
100 | =cut |
101 | |