1 | #!/usr/bin/perl |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | |
---|
6 | use LWP::UserAgent; |
---|
7 | use JSON; |
---|
8 | |
---|
9 | use Getopt::Long; |
---|
10 | use Pod::Usage; |
---|
11 | |
---|
12 | =head1 NAME |
---|
13 | |
---|
14 | rla-sshkey |
---|
15 | |
---|
16 | =head1 SYNOPSIS |
---|
17 | |
---|
18 | rla-sshkey -u http://comptes/ |
---|
19 | |
---|
20 | =head1 DESCRIPTION |
---|
21 | |
---|
22 | Query existing ssh-key in Latmos-Accounts base and push the keys inside user's home. |
---|
23 | |
---|
24 | Before writing the tools checks: |
---|
25 | |
---|
26 | =over 4 |
---|
27 | |
---|
28 | =item the user's home directory exists |
---|
29 | |
---|
30 | =item the home directory is really owned by the user |
---|
31 | |
---|
32 | =back |
---|
33 | |
---|
34 | =head1 OPTIONS |
---|
35 | |
---|
36 | =over 4 |
---|
37 | |
---|
38 | =item -u|--url http://... |
---|
39 | |
---|
40 | The url of the base Latmos-Accounts website |
---|
41 | |
---|
42 | =item -c|--create |
---|
43 | |
---|
44 | Only create .ssh/autorized_keys, dont modify it if it already exists |
---|
45 | |
---|
46 | =item -h|--help |
---|
47 | |
---|
48 | Display this help |
---|
49 | |
---|
50 | =back |
---|
51 | |
---|
52 | =cut |
---|
53 | |
---|
54 | GetOptions( |
---|
55 | 'u|url=s' => \my $url, |
---|
56 | 'c|create' => \my $create, |
---|
57 | 'h|help' => sub { pod2usage(0) }, |
---|
58 | ) or pod2usage(0); |
---|
59 | |
---|
60 | my $ua = LWP::UserAgent->new; |
---|
61 | $ua->timeout(10); |
---|
62 | |
---|
63 | $ua->ssl_opts( |
---|
64 | verify_hostname => 0, |
---|
65 | SSL_verify_mode => 0x00 |
---|
66 | ) if ($ua->can('ssl_opts')); |
---|
67 | |
---|
68 | my $json = JSON->new->utf8(1); |
---|
69 | |
---|
70 | my $response = $ua->post( |
---|
71 | $url . '/remote/listing', |
---|
72 | { |
---|
73 | otype => 'user', |
---|
74 | q => [ 'exported=1', 'sshPublicKey=*' ], |
---|
75 | attribute => [ qw(sshPublicKey uidNumber gidNumber homeDirectory) ], |
---|
76 | } |
---|
77 | ); |
---|
78 | |
---|
79 | if (!$response->is_success) { |
---|
80 | die('Cannot fetch url: ' . $response->status_line); |
---|
81 | } |
---|
82 | |
---|
83 | my $res = $response->decoded_content(); |
---|
84 | |
---|
85 | my $var = $json->decode($res); |
---|
86 | |
---|
87 | foreach my $user (keys %{ $var }) { |
---|
88 | |
---|
89 | |
---|
90 | my ($uid,$gid) = ($var->{$user}->{uidNumber}[0], $var->{$user}->{gidNumber}[0]); |
---|
91 | |
---|
92 | my $home = $var->{$user}->{homeDirectory}[0]; |
---|
93 | my @keys = @{ $var->{$user}->{sshPublicKey} || [] }; |
---|
94 | |
---|
95 | my @stat = stat($home) or do { |
---|
96 | warn "Cannot stat $user\'s home: $!, skiping\n"; |
---|
97 | next; |
---|
98 | }; |
---|
99 | if( $stat[4] != $uid) { |
---|
100 | warn "$user\'s home is owned by $stat[4] instead " . $var->{$user}->{uidNumber}[0] . ", skipping\n"; |
---|
101 | next; |
---|
102 | } |
---|
103 | |
---|
104 | if ($create && -f "$home/.ssh/authorized_keys") { |
---|
105 | next; |
---|
106 | } |
---|
107 | |
---|
108 | my @curkeys; |
---|
109 | if (open(my $handle, '<', "$home/.ssh/authorized_keys")) { |
---|
110 | while (my $line = <$handle>) { |
---|
111 | chomp($line); |
---|
112 | push(@curkeys, $line); |
---|
113 | } |
---|
114 | close($handle); |
---|
115 | } |
---|
116 | |
---|
117 | my @newkeys; |
---|
118 | foreach my $key (@keys) { |
---|
119 | my $need = 1; |
---|
120 | foreach my $curkey (@curkeys) { |
---|
121 | if ($key eq $curkey) { |
---|
122 | $need = 0; |
---|
123 | last; |
---|
124 | } |
---|
125 | } |
---|
126 | push(@newkeys, $key) if ($need); |
---|
127 | } |
---|
128 | |
---|
129 | @newkeys or next; |
---|
130 | |
---|
131 | if (! -d "$home/.ssh") { |
---|
132 | mkdir("$home/.ssh", 0700) or do { |
---|
133 | warn "Cannot create $home/.ssh: $!\n"; |
---|
134 | next; |
---|
135 | }; |
---|
136 | chown($uid, $gid, "$home/.ssh"); |
---|
137 | } |
---|
138 | |
---|
139 | if (open(my $handle, '>>', "$home/.ssh/authorized_keys")) { |
---|
140 | print $handle "$_\n" foreach(@newkeys); |
---|
141 | close($handle); |
---|
142 | chown($uid, $gid, "$home/.ssh/authorized_keys"); |
---|
143 | } else { |
---|
144 | warn "Cannot open $home/.ssh/authorized_keys: $!\n"; |
---|
145 | } |
---|
146 | } |
---|