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; |
8b69d66e |
46 | return { __error__ => $err }; |
610f74e8 |
47 | } |
48 | return { body => $out }; |
49 | } |
50 | |
51 | sub _gather_ssh_keys { |
52 | my ($self, $user, $home) = @_; |
95c7aba8 |
53 | my $ssh_dir = "$home/.ssh"; |
82d8f33c |
54 | my $ssh_authkeys = "$ssh_dir/authorized_keys"; |
95c7aba8 |
55 | return { |
56 | files => {}, |
82d8f33c |
57 | authorized => { file_name => $ssh_authkeys, body => '' } |
95c7aba8 |
58 | } unless -d $ssh_dir; |
610f74e8 |
59 | my %key; |
a4e48221 |
60 | for my $item (files_from_dir $ssh_dir) { |
610f74e8 |
61 | next unless $item =~ m{\.pub$}; |
a4e48221 |
62 | $key{ $item } = transform_exceptions { |
63 | return { |
95c7aba8 |
64 | file_name => "$ssh_dir/$item", |
a4e48221 |
65 | body => scalar output_from_file "$ssh_dir/$item", |
66 | }; |
67 | }; |
610f74e8 |
68 | } |
82d8f33c |
69 | my $auth_keys = (-e $ssh_authkeys) ? (transform_exceptions { |
95c7aba8 |
70 | return { |
82d8f33c |
71 | file_name => $ssh_authkeys, |
72 | body => scalar output_from_file $ssh_authkeys, |
95c7aba8 |
73 | }; |
82d8f33c |
74 | }) : { file_name => $ssh_authkeys, body => '' }; |
95c7aba8 |
75 | return { files => \%key, authorized => $auth_keys }; |
610f74e8 |
76 | } |
77 | |
78 | sub _gather_user_groups { |
79 | my ($self, $user) = @_; |
d2180c8c |
80 | my $groups = output_from_command [groups => $user]; |
1b608727 |
81 | return [split m{\s+}, $groups]; |
610f74e8 |
82 | } |
83 | |
84 | sub _deparse_htpasswd_line { |
85 | my ($self, $line) = @_; |
86 | chomp $line; |
87 | my %value; |
88 | @value{qw( username uid gid comment home shell )} |
89 | = (split m{:}, $line)[0, 2..6]; |
90 | return \%value; |
91 | } |
92 | |
93 | sub _open_passwd_fh { |
94 | my ($self) = @_; |
a39ee88f |
95 | return handle_from_file $self->passwd_file; |
610f74e8 |
96 | } |
97 | |
98 | 1; |
535e84b6 |
99 | |
100 | __END__ |
101 | |
102 | =head1 NAME |
103 | |
104 | System::Introspector::Users - Gather user information |
105 | |
106 | =head1 DESCRIPTION |
107 | |
108 | Gathers information for all users in C</etc/passwd>, including cronjobs and |
109 | installed SSH public keys. |
110 | |
111 | =head1 SEE ALSO |
112 | |
113 | =over |
114 | |
115 | =item L<System::Introspector> |
116 | |
117 | =back |
118 | |
119 | =cut |
120 | |