made introspector executable
[scpubgit/System-Introspector.git] / lib / System / Introspector / Probe / Users.pm
1 package System::Introspector::Probe::Users;
2 use Moo;
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 );
12
13 has passwd_file => (is => 'ro', default => sub { '/etc/passwd' });
14
15 sub gather {
16     my ($self) = @_;
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             };
33             $user{ $data->{username} } = $data;
34         }
35         return { users => \%user };
36     };
37 }
38
39 sub _gather_crontab {
40     my ($self, $user) = @_;
41     my ($out, $err, $ok) = output_from_command
42         ['crontab', '-u', $user, '-l'];
43     unless ($ok) {
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) = @_;
53     my $ssh_dir = "$home/.ssh";
54     return {
55         files => {},
56         authorized => { file_name => "$ssh_dir/authorized_keys", body => '' }
57     } unless -d $ssh_dir;
58     my %key;
59     for my $item (files_from_dir $ssh_dir) {
60         next unless $item =~ m{\.pub$};
61         $key{ $item } = transform_exceptions {
62             return {
63                 file_name => "$ssh_dir/$item",
64                 body => scalar output_from_file "$ssh_dir/$item",
65             };
66         };
67     }
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 };
75 }
76
77 sub _gather_user_groups {
78     my ($self, $user) = @_;
79     my $groups = output_from_command [groups => $user];
80     return { list => [split m{\s+}, $groups] };
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) = @_;
94     return handle_from_file $self->passwd_file;
95 }
96
97 1;
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