/[pdpsoft]/trunk/nl.nikhef.ndpf.tools/mkgroup-sshlpk/mkgroup-sshlpk
ViewVC logotype

Contents of /trunk/nl.nikhef.ndpf.tools/mkgroup-sshlpk/mkgroup-sshlpk

Parent Directory Parent Directory | Revision Log Revision Log


Revision 387 - (show annotations) (download)
Wed Jun 3 08:50:07 2009 UTC (12 years, 11 months ago) by davidg
File size: 6190 byte(s)
Added homedir ssh creation capability

1 #! /usr/bin/perl -w
2 #
3 use strict;
4 use Getopt::Long qw(:config no_ignore_case bundling);
5 use Net::LDAP qw(:all); # for all code
6 use Net::LDAP::Util qw(ldap_error_name
7 ldap_error_text); # for error handling
8
9 my $verb=0;
10 my $force=0;
11 my $uid=0;
12 my $display_help;
13 my $ldapurl="ldaps://teugel.nikhef.nl/";
14 my $defldapbase="ou=DirectoryGroups,dc=farmnet,dc=nikhef,dc=nl";
15 my $defldapuidbase="ou=LocalUsers,dc=farmnet,dc=nikhef,dc=nl";
16 my $outputfile;
17 my $commandprefix;
18 my $uidldapfilter;
19 my $ldapbase;
20 my $def_uidldapfilter = '(objectclass=*)';
21
22 &GetOptions(
23 "verbose|v+" => \$verb,
24 "url|H=s" => \$ldapurl,
25 "base|b=s" => \$ldapbase,
26 "uid|u+" => \$uid,
27 "output|o=s" => \$outputfile,
28 "command|c=s" => \$commandprefix,
29 "filter=s" => \$uidldapfilter,
30 "help|h" => \$display_help,
31 "force|f" => \$force
32 );
33
34 defined $ldapbase or do {
35 if ( $uid ) { $ldapbase = $defldapuidbase; } else { $ldapbase = $defldapbase; };
36 };
37
38 if ( $display_help ) {
39 print <<EOF;
40
41 Generate a list of all unique sshPublicKeys for all members of the
42 directory groups or uids specified on the command line.
43
44 Usage: $0 [-h] [-c|--comand strin] [-H uri] [-b DITbase] [-o file]
45 [-f] [-v[v]] groupRDN [groupRDN]
46 -h Display this help text
47 --uid Retrieve sshPublicKeys for uids instead of groups
48 -H uri Connect to LDAP server at <uri>
49 (default: $ldapurl)
50 -b base Search base DIT for groups
51 (default: $ldapbase)
52 -c prfx Prefix pre-pended to each line written. Any text in the
53 original sshPublicKey attribute before the tokens " ssh-.sa "
54 or " \\d+ \\d+ " is replaced.
55 In the prefix itself, \@UID\@, \@GID\@, \@UIDNUMBER\@ are replaced
56 -o file Writing list of sshPublicKeys to <file>
57 (only when at least one sshPublicKey is retrieved, unless
58 -f is also specified)
59 -f Force writing even if the list of keys is empty
60
61 groupRDN name of groups to traverse for members (list)
62
63 Example:
64 $0 systemAdministrators nDPFPrivilegedUsers
65 $0 -c 'command="svnserve -t -r /project/srv/svn --tunnel-user=\@UID\@",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty' -o ~svn/.ssh/authorized_keys nDPFSubversionUsers
66
67 Dependencies:
68 perl-LDAP, and perl-IO-Socket-SSL & perl-Net-SSLeay for ldaps ($verb)
69
70 EOF
71 exit (0);
72 };
73
74 defined $ARGV[0] or die "groupRDN is a required argument\n";
75
76 my $ldap = Net::LDAP->new( $ldapurl, timeout=>20 );
77 $ldap or die "Cannot contact remote server at $ldapurl: $!\n".
78 " LDAP status: ".$ldap->error."\n";
79
80 # start collecting ssh keys from all users in all groups requested
81 my @keys = ();
82 defined $uidldapfilter or $uidldapfilter = $def_uidldapfilter;
83
84 if ( $uid ) {
85 foreach my $uidRDN ( @ARGV ) {
86 push @keys, &writeUidLines("uid=$uidRDN,$ldapbase","uid=$uidRDN");
87 }
88 } else {
89 foreach my $groupRDN ( @ARGV ) {
90
91 my $groupresults=$ldap->search(
92 base=>$ldapbase,
93 scope=>"sub",
94 filter=>"(cn=$groupRDN)"
95 );
96 $groupresults->code and die "Search failed: ".$groupresults->error."\n";
97 $groupresults->count() or die "No group found matching $groupRDN, exiting\n";
98
99 # list of entries for all groups matching this groupRDN
100 my @grouplistentries=$groupresults->entries;
101
102 foreach my $groupentry ( @grouplistentries ) {
103 my @groupmembers = $groupentry->get_value("uniqueMember");
104 foreach my $memberDN ( @groupmembers ) {
105 push @keys, &writeUidLines($memberDN,$groupentry->get_value("cn"));
106 }
107 }
108 }
109 }
110
111 # when writing to file, there must be at least one key to indicate
112 # sanity, unless -f has been specified and you don't care
113 # otherwise, an LDAP search error or typo may accidentally wipe
114 # a authorized_keys file
115
116 ( defined $outputfile ) and (@keys == 0) and
117 die "Empty key list will not be written to $outputfile (use \"-f\" to force)\n";
118
119 # print each key only once
120 my %uniqueKeys;
121 foreach ( @keys ) { $uniqueKeys{$_}=2; }
122
123 if ( defined $outputfile ) {
124 open OF,">$outputfile" or die "Cannot open $outputfile for writing: $!\n";
125 print OF "# Generated by $0 on ".gmtime(time())." UTC\n";
126 print OF "# from groups @ARGV\n";
127 foreach ( keys %uniqueKeys ) { print OF "$_\n"; }
128 close OF;
129 } else {
130 # just write to stdout
131 foreach ( keys %uniqueKeys ) { print "$_\n"; }
132 }
133
134
135 ##############################################################################
136 # fill an array with ssh keys for a (list of) uid DNs
137 #
138 sub writeUidLines($$) {
139 my ( $memberDN, $basename ) = @_;
140
141 my @lines;
142 my $uidresult;
143 # sanity check: the DN must exist or the directory is inconsistent
144 # if the filter is fully open, but it need not have an ldapPublicKey
145 $uidresult =
146 $ldap->search( base=>$memberDN, scope=>"sub",
147 filter=>"$uidldapfilter" );
148
149 if ( $uidresult->count() <= 0 ) {
150 if ( $uidldapfilter eq $def_uidldapfilter ) {
151 die "DN $memberDN not found, extracted from group $basename.\n";
152 } else {
153 next;
154 }
155 }
156
157 # but does it have an ldapPublicKey?
158 $uidresult =
159 $ldap->search( base=>$memberDN, scope=>"sub",
160 filter=>"(objectclass=ldapPublicKey)" );
161
162 $uidresult->code or do {
163 my @uidentries = $uidresult->entries;
164 foreach my $uidentry ( @uidentries ) {
165 foreach my $keyAttrib ( $uidentry->get_value("sshPublicKey") ) {
166 defined $commandprefix and $commandprefix ne "" and do {
167 my ($val,$cmd) = ("",$commandprefix);
168 $val = $uidentry->get_value('uid');
169 $cmd=~s/\@UID\@/$val/g;
170 $val = $uidentry->get_value('cn');
171 $cmd=~s/\@CN\@/$val/g;
172 $val = $uidentry->get_value('uidNumber');
173 $cmd=~s/\@UIDNUMBER\@/$val/g;
174 $val = $uidentry->get_value('gidNumber');
175 $cmd=~s/\@GIDNUMBER\@/$val/g;
176 $keyAttrib=~s/^.* (ssh-\wsa\s+)/$1/;
177 $keyAttrib=~s/^.* (\d+\s+\d+\s+)/$1/;
178 $keyAttrib="$cmd $keyAttrib";
179 };
180 push @lines,$keyAttrib;
181 }
182 }
183 };
184
185 return @lines;
186 }

Properties

Name Value
svn:executable *

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28