mirror of
git://git.gnu.org.ua/pam-modules.git
synced 2025-04-26 16:39:53 +03:00
176 lines
4.2 KiB
Perl
Executable file
176 lines
4.2 KiB
Perl
Executable file
#! /usr/bin/perl
|
|
# This file is part of pam-modules.
|
|
# Copyright (C) 2014 Sergey Poznyakoff
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3, or (at your option)
|
|
# any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
use strict;
|
|
use Net::LDAP;
|
|
|
|
=head1 NAME
|
|
|
|
ldappubkey - get user public ssh keys from the LDAP database
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
B<ldappubkey> I<LOGIN>
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Produces on the standard output public ssh keys for the user I<LOGIN>, each
|
|
on a separate line. The program is designed for use with B<sshd>(8) version
|
|
6.2p1 or higher. Public keys are obtained from a LDAP database. The
|
|
configuration is looked up in the following files: B</etc/ldap.conf>,
|
|
B</etc/ldap/ldap.conf> and B</etc/openldap/ldap.conf>. These files are
|
|
tried in this order and the first one of them that exists is read.
|
|
|
|
The following configuration statements are used (all keywords are
|
|
case-insensitive):
|
|
|
|
=over 4
|
|
|
|
=item B<uri> B<ldap[si]://>[I<name>[:I<port>]] ...>
|
|
|
|
Specifies the URI of the LDAP server (or servers) to connect to. The default
|
|
is B<ldap://127.0.0.1>.
|
|
|
|
=item B<base> I<DN>
|
|
|
|
Specifies the default base DN to use when performing ldap operations.
|
|
The base must be specified as a Distinguished Name in LDAP format.
|
|
|
|
=item B<binddn> I<DN>
|
|
|
|
Specifies the default bind DN to use.
|
|
|
|
=item B<bindpw> I<PASS>
|
|
|
|
Specifies the password to use with B<binddn>.
|
|
|
|
=item B<uid> I<ATTR>
|
|
|
|
Name of the attribute to use instead of B<uid>. The LDAP record is searched
|
|
using the filter B<(&(objectClass=posixAccount)(I<ATTR>=I<LOGIN>))>.
|
|
|
|
=item B<publickeyattribute> I<ATTR>
|
|
|
|
Name of the attribute which holds the public key. Default is B<grayPublicKey>.
|
|
|
|
=back
|
|
|
|
=head1 OPTIONS
|
|
|
|
=over 4
|
|
|
|
=item B<-h>
|
|
|
|
Show program usage.
|
|
|
|
=item B<--help>
|
|
|
|
Show detailed help page.
|
|
|
|
=back
|
|
|
|
=head1 SEE ALSO
|
|
|
|
B<sshd>(8), B<sshd_config>(5), B<ldap.conf>(5).
|
|
|
|
=head1 BUGS
|
|
|
|
LDAP filter string is hardcoded.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Sergey Poznyakoff <gray@gnu.org>
|
|
|
|
=cut
|
|
|
|
# ###################################
|
|
# Configuration file handling
|
|
# ###################################
|
|
|
|
my %config = ('uri' => 'ldap://127.0.0.1', 'uid' => 'uid',
|
|
'publickeyattribute' => 'grayPublicKey');
|
|
|
|
sub read_config_file($) {
|
|
my $config_file = shift;
|
|
my $file;
|
|
my $line = 0;
|
|
|
|
open($file, "<", $config_file) or die("cannot open $config_file: $!");
|
|
while (<$file>) {
|
|
++$line;
|
|
chomp;
|
|
s/^\s+//;
|
|
s/\s+$//;
|
|
s/#.*//;
|
|
next if ($_ eq "");
|
|
my @kwp = split(/\s*\s+\s*/, $_, 2);
|
|
$config{lc($kwp[0])} = $kwp[1];
|
|
}
|
|
close($file);
|
|
}
|
|
|
|
sub assert {
|
|
my $mesg = shift;
|
|
my $action = shift;
|
|
die("An error occurred $action: ".$mesg->error) if ($mesg->code);
|
|
return $mesg;
|
|
}
|
|
|
|
# ###################################
|
|
# MAIN
|
|
# ###################################
|
|
|
|
die "bad number of arguments; try perldoc $0 for more info"
|
|
unless ($#ARGV == 0);
|
|
|
|
## Read configuration
|
|
foreach my $file ("/etc/ldap.conf", "/etc/ldap/ldap.conf",
|
|
"/etc/openldap/ldap.conf") {
|
|
if (-e $file) {
|
|
read_config_file($file);
|
|
last;
|
|
}
|
|
}
|
|
|
|
my $ldap = Net::LDAP->new($config{'uri'})
|
|
or die("Unable to connect to LDAP server $config{'uri'}: $!");
|
|
my @bindargs = ();
|
|
if (defined($config{'binddn'})) {
|
|
push(@bindargs, $config{'binddn'});
|
|
push(@bindargs, password => $config{'bindpw'})
|
|
if defined($config{'bindpw'});
|
|
}
|
|
assert($ldap->bind(@bindargs), "binding to the server");
|
|
|
|
my $attr = $config{'publickeyattribute'};
|
|
my $filter = "(&(objectClass=posixAccount)($config{'uid'}=$ARGV[0]))";
|
|
|
|
my $res = assert($ldap->search(base => $config{'base'},
|
|
filter => $filter,
|
|
attr => [ $attr ] ),
|
|
"searching for $filter in $config{'base'}");
|
|
|
|
foreach my $entry ($res->entry(0)) {
|
|
my $keyref = $entry->get_value($attr, asref => 1);
|
|
for (@{$keyref}) {
|
|
print "$_\n";
|
|
}
|
|
}
|
|
|
|
# END
|
|
|
|
|