[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