Commit | Line | Data |
afd7c030 |
1 | package System::Introspector::Probe::Users; |
610f74e8 |
2 | use Moo; |
a4e48221 |
3 | |
4 | use System::Introspector::Util qw( |
5 | handle_from_command |
6 | transform_exceptions |
7 | output_from_file |
8 | output_from_command |
9 | files_from_dir |
10 | handle_from_file |
11 | ); |
610f74e8 |
12 | |
a39ee88f |
13 | has passwd_file => (is => 'ro', default => sub { '/etc/passwd' }); |
14 | |
610f74e8 |
15 | sub gather { |
16 | my ($self) = @_; |
a4e48221 |
17 | return transform_exceptions { |
18 | my $fh = $self->_open_passwd_fh; |
19 | my %user; |
20 | while (defined( my $line = <$fh> )) { |
21 | my $data = $self->_deparse_htpasswd_line($line); |
22 | my $user = $data->{username}; |
23 | my $home = $data->{home}; |
24 | $data->{groups} = transform_exceptions { |
25 | $self->_gather_user_groups($user); |
26 | }; |
27 | $data->{ssh}{keys} = transform_exceptions { |
28 | $self->_gather_ssh_keys($user, $home); |
29 | }; |
30 | $data->{crontab} = transform_exceptions { |
31 | $self->_gather_crontab($user); |
32 | }; |
386a00c7 |
33 | $user{ $data->{username} } = $data; |
a4e48221 |
34 | } |
35 | return { users => \%user }; |
36 | }; |
610f74e8 |
37 | } |
38 | |
39 | sub _gather_crontab { |
40 | my ($self, $user) = @_; |
a4e48221 |
41 | my ($out, $err, $ok) = output_from_command |
42 | ['crontab', '-u', $user, '-l']; |
43 | unless ($ok) { |
610f74e8 |
44 | return {} |
45 | if $err =~ m{^no crontab}i; |
46 | return { error => $err }; |
47 | } |
48 | return { body => $out }; |
49 | } |
50 | |
51 | sub _gather_ssh_keys { |
52 | my ($self, $user, $home) = @_; |
95c7aba8 |
53 | my $ssh_dir = "$home/.ssh"; |
54 | return { |
55 | files => {}, |
56 | authorized => { file_name => "$ssh_dir/authorized_keys", body => '' } |
57 | } unless -d $ssh_dir; |
610f74e8 |
58 | my %key; |
a4e48221 |
59 | for my $item (files_from_dir $ssh_dir) { |
610f74e8 |
60 | next unless $item =~ m{\.pub$}; |
a4e48221 |
61 | $key{ $item } = transform_exceptions { |
62 | return { |
95c7aba8 |
63 | file_name => "$ssh_dir/$item", |
a4e48221 |
64 | body => scalar output_from_file "$ssh_dir/$item", |
65 | }; |
66 | }; |
610f74e8 |
67 | } |
95c7aba8 |
68 | my $auth_keys = transform_exceptions { |
69 | return { |
70 | file_name => "$ssh_dir/authorized_keys", |
71 | body => scalar output_from_file "$ssh_dir/authorized_keys", |
72 | }; |
73 | }; |
74 | return { files => \%key, authorized => $auth_keys }; |
610f74e8 |
75 | } |
76 | |
77 | sub _gather_user_groups { |
78 | my ($self, $user) = @_; |
d2180c8c |
79 | my $groups = output_from_command [groups => $user]; |
a4e48221 |
80 | return { list => [split m{\s+}, $groups] }; |
610f74e8 |
81 | } |
82 | |
83 | sub _deparse_htpasswd_line { |
84 | my ($self, $line) = @_; |
85 | chomp $line; |
86 | my %value; |
87 | @value{qw( username uid gid comment home shell )} |
88 | = (split m{:}, $line)[0, 2..6]; |
89 | return \%value; |
90 | } |
91 | |
92 | sub _open_passwd_fh { |
93 | my ($self) = @_; |
a39ee88f |
94 | return handle_from_file $self->passwd_file; |
610f74e8 |
95 | } |
96 | |
97 | 1; |
535e84b6 |
98 | |
99 | __END__ |
100 | |
101 | =head1 NAME |
102 | |
103 | System::Introspector::Users - Gather user information |
104 | |
105 | =head1 DESCRIPTION |
106 | |
107 | Gathers information for all users in C</etc/passwd>, including cronjobs and |
108 | installed SSH public keys. |
109 | |
110 | =head1 SEE ALSO |
111 | |
112 | =over |
113 | |
114 | =item L<System::Introspector> |
115 | |
116 | =back |
117 | |
118 | =cut |
119 | |