[pve-devel] r4891 - pve-access-control/trunk
svn-commits at proxmox.com
svn-commits at proxmox.com
Wed Jul 14 11:02:21 CEST 2010
Author: dietmar
Date: 2010-07-14 09:02:21 +0000 (Wed, 14 Jul 2010)
New Revision: 4891
Modified:
pve-access-control/trunk/AccessControl.pm
pve-access-control/trunk/ChangeLog
Log:
* AccessControl.pm (ldap_bind): rename to authenticate_user_ad (AD
only)
(load_domains_config): return a reference to an array (not the
array itself)
(parse_config): return a reference to an array (not the array
itself)
(authenticate_user_domain): restructure code - this is no the
centralized interface for authenticationn
(authenticate_user_domain): add 'shadow' and 'PAM' default entries
if there is no configuration for them in domain.cfg
(authenticate_user_shadow): renamed from authenticate_user_pve
Modified: pve-access-control/trunk/AccessControl.pm
===================================================================
--- pve-access-control/trunk/AccessControl.pm 2010-07-14 07:02:20 UTC (rev 4890)
+++ pve-access-control/trunk/AccessControl.pm 2010-07-14 09:02:21 UTC (rev 4891)
@@ -422,19 +422,21 @@
return undef;
}
-sub authenticate_user_pve {
+sub authenticate_user_shadow {
my ($username, $password) = @_;
+ die "no password\n" if !$password;
+
my $shadow_cfg = load_shadow_config();
if ($shadow_cfg->{users}->{$username}) {
my $encpw = crypt($password, $shadow_cfg->{users}->{$username}->{shadow});
if ($encpw ne $shadow_cfg->{users}->{$username}->{shadow}) {
sleep(4);
- die "SHADOW auth failed\n";
+ die "invalid credentials\n";
}
} else {
- die "SHADOW password not set\n";
+ die "no password set\n";
}
}
@@ -443,7 +445,7 @@
# user (www-data) need to be able to read /etc/passwd /etc/shadow
- die "PAM auth failed: no password\n" if !$password;
+ die "no password\n" if !$password;
my $pamh = new Authen::PAM ('common-auth', $username, sub {
my @res;
@@ -465,57 +467,98 @@
if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS) {
my $err = $pamh->pam_strerror($res);
- die "PAM auth failed: $err\n";
+ die "$err\n";
}
if (($res = $pamh->pam_acct_mgmt (0)) != PAM_SUCCESS) {
my $err = $pamh->pam_strerror($res);
- die "PAM auth failed: $err\n";
+ die "$err\n";
}
$pamh = 0; # call destructor
}
+sub authenticate_user_ad {
+
+ my ($server, $username, $password) = @_;
+
+ my $ldap = Net::LDAP->new($server) || die "$@\n";
+
+ my $res = $ldap->bind($username, password => $password);
+
+ my $code = $res->code();
+ my $err = $res->error;
+
+ $ldap->unbind();
+
+ die "$err\n" if $code;
+}
+
sub authenticate_user_domain {
my ($username, $password) = @_;
- my $ldap_resp;
- my @domain_cfg = load_domains_config();
+
+ my $domain_cfg = load_domains_config();
+
my (undef, $user, $domain) = verify_username($username);
- foreach my $entry (@domain_cfg) {
- foreach my $doms ($entry->{domains}) {
+
+ my $shadow = {
+ type => "shadow",
+ domains => [ '' ], # names without domain part
+ };
+
+ my $pam = {
+ type => "PAM",
+ domains => [ 'localhost' ],
+ };
+
+ my @entries = @$domain_cfg;
+ # add 'PAM' if not configured if domain.cfg
+ push @entries, $pam if !grep {$_->{type} eq 'PAM'} @entries;
+ # add 'shadow' if not configured if domain.cfg
+ push @entries, $shadow if !grep {$_->{type} eq 'shadow'} @entries;
+
+ my $found;
+
+ my $errmsg = '';
+
+ foreach my $entry (@$domain_cfg, $pam, $shadow) {
+ foreach my $doms ($entry->{domains}) {
foreach my $dom (@$doms) {
- if ($dom eq $domain) {
- $ldap_resp = ldap_bind($entry->{server}, $entry->{type}, $username, $password);
- if ($ldap_resp =~ m/route/) {
- warn $ldap_resp . "\n";
- next;
+ if ($domain =~ m/^${dom}$/) {
+
+ $found = 1;
+
+ eval {
+ if ($entry->{type} eq 'shadow') {
+ authenticate_user_shadow($username, $password);
+ } elsif ($entry->{type} eq 'PAM') {
+ authenticate_user_pam($user, $password);
+ } elsif ($entry->{type} eq 'AD') {
+ authenticate_user_ad($entry->{server}, $username, $password);
+ } else {
+ die "unknown auth type '$entry->{type}'\n";
+ }
+ };
+ my $err = $@;
+
+ if ($err) {
+ chomp($err);
+ $errmsg .= "$entry->{type}: $err\n";
+ #warn "$entry->{type} auth failed: $err\n";
+ next;
}
- return 1 if ($ldap_resp == 0);
- die "invalid credentials\n" if ($ldap_resp == 49);
+
+ # no exceptions, so auth was successful
+ return 1;
}
}
}
}
- die "domain \'$domain\' not defined\n" if !$ldap_resp;
- die "$ldap_resp\n";
-}
-sub ldap_bind {
+ die "domain \'$domain\' not defined\n" if !$found;
- my ($server, $type, $username, $password) = @_;
- my $res;
- my $ldap = Net::LDAP->new($server) || die "$@\n";
- if ($type eq "AD") {
- $res = $ldap->bind( $username, password=>$password );
- } else {
- #fixme: Implement LDAP:my $res = $ldap->bind( $username, password=>$password );
- die "LDAP Authentication not yet implemented.";
- }
- my $code = $res->code();
- $ldap->unbind();
- return $code;
-
+ die $errmsg || "internal error";
}
sub user_enabled {
@@ -547,13 +590,7 @@
die "no such user ('$username')\n" if !user_enabled($usercfg, $username);
- if (!$domain) {
- if ($username eq 'root') { # always use PAM for root
- authenticate_user_pam($username, $password);
- } else {
- authenticate_user_pve($username, $password);
- }
- } elsif ($domain eq 'localhost') {
+ if ($username eq 'root') { # always use PAM for root
authenticate_user_pam($username, $password);
} else {
authenticate_user_domain($username, $password);
@@ -1192,7 +1229,7 @@
sub parse_domains {
my ($filename, $fh) = @_;
- my @connlist = ();
+ my $connlist = [];
my $ad = {};
die "MODE: '$/'" if !$/;
@@ -1206,7 +1243,7 @@
$line =~ s/\s+$//; # delete trailing blanks
if ($line =~ m/^\S+:\s*\S+$/) {
if ($ad->{domains}) {
- push(@connlist, $ad);
+ push(@$connlist, $ad);
$ad = {};
}
my($type,$domains) = split (/:/, $line);
@@ -1229,8 +1266,8 @@
}
}
}
-push(@connlist, $ad);
-return @connlist;
+ push(@$connlist, $ad);
+ return $connlist;
}
my $user_config_cache;
@@ -1267,21 +1304,21 @@
return $shadow_config_cache;
}
-my @domains_config_cache;
+my $domains_config_cache;
sub load_domains_config {
my ($reload) = @_;
- return @domains_config_cache if !$reload && @domains_config_cache;
+ return $domains_config_cache if !$reload && $domains_config_cache;
- my @cfg = {};
+ my $cfg = [];
my $fh = IO::File->new ($domainconfigpath, 'r');
- @cfg = parse_domains($domainconfigpath, $fh);
+ $cfg = parse_domains($domainconfigpath, $fh);
$fh->close() if $fh;
- @domains_config_cache = @cfg;
+ $domains_config_cache = $cfg;
- return @domains_config_cache;
+ return $domains_config_cache;
}
sub save_shadow_config {
Modified: pve-access-control/trunk/ChangeLog
===================================================================
--- pve-access-control/trunk/ChangeLog 2010-07-14 07:02:20 UTC (rev 4890)
+++ pve-access-control/trunk/ChangeLog 2010-07-14 09:02:21 UTC (rev 4891)
@@ -1,6 +1,16 @@
2010-07-14 Proxmox Support Team <support at proxmox.com>
- * AccessControl.pm (ldap_bind): correctly raise exception on error
+ * AccessControl.pm (ldap_bind): rename to authenticate_user_ad (AD
+ only)
+ (load_domains_config): return a reference to an array (not the
+ array itself)
+ (parse_config): return a reference to an array (not the array
+ itself)
+ (authenticate_user_domain): restructure code - this is no the
+ centralized interface for authenticationn
+ (authenticate_user_domain): add 'shadow' and 'PAM' default entries
+ if there is no configuration for them in domain.cfg
+ (authenticate_user_shadow): renamed from authenticate_user_pve
* control.in (Depends): add libnet-ldap-perl
More information about the pve-devel
mailing list