[pve-devel] r5530 - in pve-manager/pve2: . lib/PVE lib/PVE/API2

svn-commits at proxmox.com svn-commits at proxmox.com
Tue Feb 15 13:38:49 CET 2011


Author: dietmar
Date: 2011-02-15 13:38:49 +0100 (Tue, 15 Feb 2011)
New Revision: 5530

Modified:
   pve-manager/pve2/ChangeLog
   pve-manager/pve2/lib/PVE/API2/Nodes.pm
   pve-manager/pve2/lib/PVE/APIDaemon.pm
   pve-manager/pve2/lib/PVE/REST.pm
Log:


Modified: pve-manager/pve2/ChangeLog
===================================================================
--- pve-manager/pve2/ChangeLog	2011-02-15 12:33:51 UTC (rev 5529)
+++ pve-manager/pve2/ChangeLog	2011-02-15 12:38:49 UTC (rev 5530)
@@ -1,3 +1,8 @@
+2011-02-15  Proxmox Support Team  <support at proxmox.com>
+
+	* lib/PVE/REST.pm (rest_handler): check access permissions using
+	new PVE::ACLCache.
+
 2011-02-11  Proxmox Support Team  <support at proxmox.com>
 
 	* lib/PVE/API2/VM.pm: moved code to Cluster.pm

Modified: pve-manager/pve2/lib/PVE/API2/Nodes.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2/Nodes.pm	2011-02-15 12:33:51 UTC (rev 5529)
+++ pve-manager/pve2/lib/PVE/API2/Nodes.pm	2011-02-15 12:38:49 UTC (rev 5530)
@@ -157,6 +157,10 @@
     method => 'GET',
     description => "Read system log",
     proxyto => 'node',
+    permissions => {
+	path => '/nodes/{node}',
+	privs => [ 'SYS.Syslog' ],
+    },
     parameters => {
     	additionalProperties => 0,
 	properties => {

Modified: pve-manager/pve2/lib/PVE/APIDaemon.pm
===================================================================
--- pve-manager/pve2/lib/PVE/APIDaemon.pm	2011-02-15 12:33:51 UTC (rev 5529)
+++ pve-manager/pve2/lib/PVE/APIDaemon.pm	2011-02-15 12:38:49 UTC (rev 5530)
@@ -4,7 +4,6 @@
 use warnings;
 use vars qw(@ISA);
 use PVE::SafeSyslog;
-use PVE::Cluster;
 use PVE::INotify;
 use PVE::RPCEnvironment;
 
@@ -268,8 +267,6 @@
 			my $parser = HTTP::Request::Params->new({req => $r});
 			my $params = $parser->params;
 
-			PVE::Cluster::cfs_update();
-
 			my $res = PVE::REST::rest_handler($method, $uri, $rel_uri, $ticket, $params);
 
 			if ($res->{proxy}) {

Modified: pve-manager/pve2/lib/PVE/REST.pm
===================================================================
--- pve-manager/pve2/lib/PVE/REST.pm	2011-02-15 12:33:51 UTC (rev 5529)
+++ pve-manager/pve2/lib/PVE/REST.pm	2011-02-15 12:38:49 UTC (rev 5530)
@@ -17,6 +17,7 @@
 use HTML::Entities;
 use PVE::JSONSchema;
 use PVE::AccessControl;
+use PVE::ACLCache;
 
 use Data::Dumper; # fixme: remove
 
@@ -262,28 +263,62 @@
     return OK;
 }
 
+my $aclcache;
+my $aclversion;
+
 sub rest_handler {
     my ($method, $abs_uri, $rel_uri, $ticket, $params) = @_;
  
+    PVE::Cluster::cfs_update();
+
+    my $ucvers = PVE::Cluster::cfs_file_version('user.cfg'); 
+    if (!$aclcache || !defined($aclversion) || !defined($ucvers) || 
+	($ucvers ne $aclversion)) {
+	$aclversion = $ucvers;
+	eval {
+	    my $cfg = PVE::Cluster::cfs_read_file('user.cfg');
+	    $aclcache = PVE::ACLCache->new($cfg);
+	};
+	if (my $err = $@) {
+	    my $msg = "Unable to load access control list: $err";
+	    syslog('err', $msg);
+	    return { status => HTTP_INTERNAL_SERVER_ERROR,
+		     message =>  $msg};
+	}
+    }
+
     my $euid = $>;
    
     if ($rel_uri eq '/ticket') {
 	my $user = $params->{username} || '';
 	my $pw = $params->{password} || '';
 
+	if (!$aclcache->user_enabled($user)) {
+	    return { 
+		status => HTTP_FORBIDDEN,
+		message => "No such user (user not enabled).",
+	    };
+	}
+
 	return { proxy => 'localhost' } if ($euid != 0);
 
 	#syslog('info', "ticket auth $user $pw");
 
 	if (!($ticket = create_ticket($user, $pw))) {
-	    return { status => HTTP_UNAUTHORIZED };
+	    return { 
+		status => HTTP_FORBIDDEN,
+		message => "Unable to verify credentials.",
+	    };
 	}
 	 
 	if (defined($params->{path}) || defined($params->{permissions})) {
+	    my $privs = PVE::Tools::split_list($params->{permissions});
 	    if (!($params->{path} && $params->{permissions} &&
-		  PVE::AccessControl::check_permissions($user, $params->{path}, 
-							$params->{permissions}))) {
-		return { status => HTTP_UNAUTHORIZED };
+		  $aclcache->check($user, $params->{path}, $privs))) {
+		return { 
+		    status => HTTP_FORBIDDEN,
+		    message => "permission check failed ($params->{path}, $params->{permissions})",
+		};
 	    }
 	}
 
@@ -318,6 +353,22 @@
 	$uri_param->{$p} = $params->{$p};
     }
 
+    # check access permissions
+    if (my $perm = $info->{permissions}) {
+	if (!$aclcache->check($username, $perm->{path}, $perm->{privs})) {
+	    my $privstr = join(',', @{$perm->{privs}});
+	    my $path = PVE::Tools::template_replace($perm->{path}, $uri_param);
+	    return { 
+		status => HTTP_FORBIDDEN, 
+		message => "permission check failed ($path, $privstr)",
+	    };
+	}
+    } else {
+	if ($username ne 'root') {
+	    return { status => HTTP_FORBIDDEN };
+	}
+    }
+
     if ($info->{proxyto}) {
 	my $remip;
 	eval {
@@ -416,8 +467,6 @@
      my ($rel_uri, $format) = split_abs_uri($abs_uri);
      return HTTP_NOT_IMPLEMENTED if !$format;
 
-     PVE::Cluster::cfs_update();
-
      my $res = rest_handler($method, $abs_uri, $rel_uri, $ticket, $params);
 
      if ($res->{proxy}) {



More information about the pve-devel mailing list