added base pod to all probes
[scpubgit/System-Introspector.git] / lib / System / Introspector / Users.pm
1 package System::Introspector::Users;
2 use Moo;
3 use IPC::Run qw( run );
4
5 sub gather {
6     my ($self) = @_;
7     my $fh = $self->_open_passwd_fh;
8     my %user;
9     while (defined( my $line = <$fh> )) {
10         my $data = $self->_deparse_htpasswd_line($line);
11         my $user = $data->{username};
12         my $home = $data->{home};
13         $data->{groups}    = $self->_gather_user_groups($user);
14         $data->{ssh}{keys} = $self->_gather_ssh_keys($user, $home);
15         $data->{crontab}   = $self->_gather_crontab($user);
16         $user{ $data->{uid} } = $data;
17     }
18     return \%user;
19 }
20
21 sub _gather_crontab {
22     my ($self, $user) = @_;
23     my ($in, $out, $err) = (('') x 3);
24     run(['crontab', '-u', $user, '-l'], \$in, \$out, \$err);
25     if (length $err) {
26         return {}
27             if $err =~ m{^no crontab}i;
28         return { error => $err };
29     }
30     return { body => $out };
31 }
32
33 sub _gather_ssh_keys {
34     my ($self, $user, $home) = @_;
35     my $ssh_dir = "$home/.ssh/";
36     return {}
37         unless -d $ssh_dir;
38     my $dh;
39     opendir $dh, $ssh_dir
40         or return { error => $! };
41     my %key;
42     while (defined( my $item = readdir $dh )) {
43         next unless $item =~ m{\.pub$};
44         my $item_path = "$ssh_dir/$item";
45         open my $key_fh, '<', $item_path;
46         if ($key_fh) {
47             $key{ $item }{body} = do { local $/; <$key_fh> };
48         }
49         else {
50             $key{ $item }{error} = $!;
51         }
52     }
53     return { files => \%key };
54 }
55
56 sub _gather_user_groups {
57     my ($self, $user) = @_;
58     return [split m{\s+}, `groups $user`];
59 }
60
61 sub _deparse_htpasswd_line {
62     my ($self, $line) = @_;
63     chomp $line;
64     my %value;
65     @value{qw( username uid gid comment home shell )}
66         = (split m{:}, $line)[0, 2..6];
67     return \%value;
68 }
69
70 sub _open_passwd_fh {
71     my ($self) = @_;
72     open my $fh, '<', '/etc/passwd'
73         or die "Unable to open /etc/passwd: $!\n";
74     return $fh;
75 }
76
77 1;
78
79 __END__
80
81 =head1 NAME
82
83 System::Introspector::Users - Gather user information
84
85 =head1 DESCRIPTION
86
87 Gathers information for all users in C</etc/passwd>, including cronjobs and
88 installed SSH public keys.
89
90 =head1 SEE ALSO
91
92 =over
93
94 =item L<System::Introspector>
95
96 =back
97
98 =cut
99