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

Properties

Name Value
svn:executable *

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