[pve-devel] r5559 - in pve-access-control/trunk: . PVE PVE/API2

svn-commits at proxmox.com svn-commits at proxmox.com
Thu Feb 17 14:15:03 CET 2011


Author: dietmar
Date: 2011-02-17 14:15:02 +0100 (Thu, 17 Feb 2011)
New Revision: 5559

Added:
   pve-access-control/trunk/PVE/API2/Domains.pm
Modified:
   pve-access-control/trunk/ChangeLog
   pve-access-control/trunk/PVE/API2/AccessControl.pm
   pve-access-control/trunk/PVE/API2/Makefile
   pve-access-control/trunk/PVE/AccessControl.pm
Log:
new API to for domains.cfg



Modified: pve-access-control/trunk/ChangeLog
===================================================================
--- pve-access-control/trunk/ChangeLog	2011-02-17 11:06:18 UTC (rev 5558)
+++ pve-access-control/trunk/ChangeLog	2011-02-17 13:15:02 UTC (rev 5559)
@@ -1,5 +1,7 @@
 2011-02-17  Proxmox Support Team  <support at proxmox.com>
 
+	* PVE/API2/Domains.pm: new API to for domains.cfg
+
 	* PVE/AccessControl.pm (authenticate_user_domain): added a 'domid'
 	attribute to users. This references an entry in the domain
 	config. This is simpler than the previous domain search

Modified: pve-access-control/trunk/PVE/API2/AccessControl.pm
===================================================================
--- pve-access-control/trunk/PVE/API2/AccessControl.pm	2011-02-17 11:06:18 UTC (rev 5558)
+++ pve-access-control/trunk/PVE/API2/AccessControl.pm	2011-02-17 13:15:02 UTC (rev 5559)
@@ -7,6 +7,7 @@
 use Apache2::Const qw(:http);
 
 use PVE::RESTHandler;
+use PVE::API2::Domains;
 use PVE::API2::User;
 use PVE::API2::Group;
 use PVE::API2::Role;
@@ -35,6 +36,11 @@
 });
 
 __PACKAGE__->register_method ({
+    subclass => "PVE::API2::Domains",  
+    path => 'domains',
+});
+
+__PACKAGE__->register_method ({
     name => 'index', 
     path => '', 
     method => 'GET',

Added: pve-access-control/trunk/PVE/API2/Domains.pm
===================================================================
--- pve-access-control/trunk/PVE/API2/Domains.pm	                        (rev 0)
+++ pve-access-control/trunk/PVE/API2/Domains.pm	2011-02-17 13:15:02 UTC (rev 5559)
@@ -0,0 +1,250 @@
+package PVE::API2::Domains;
+
+use strict;
+use warnings;
+use PVE::Cluster qw (cfs_read_file cfs_write_file);
+use PVE::AccessControl;
+use PVE::JSONSchema qw(get_standard_option);
+
+use PVE::SafeSyslog;
+
+use Data::Dumper; # fixme: remove
+
+use PVE::RESTHandler;
+
+my $domainconfigfile = "priv/domains.cfg";
+
+use base qw(PVE::RESTHandler);
+
+# fixme: index should return more/all attributes?
+__PACKAGE__->register_method ({
+    name => 'index', 
+    path => '', 
+    method => 'GET',
+    description => "Authentication domain index.",
+    parameters => {
+	additionalProperties => 0,
+	properties => {},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		id => { type => 'string' },
+	    },
+	},
+	links => [ { rel => 'child', href => "{id}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+    
+	my $res = [];
+
+	my $cfg = cfs_read_file($domainconfigfile);
+ 
+	foreach my $domid (keys %$cfg) {
+	    my $d = $cfg->{$domid};
+	    my $entry = { id => $domid, type => $d->{type} };
+	    $entry->{comment} = $d->{comment} if $d->{comment};
+	    push @$res, $entry;
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'create', 
+    protected => 1,
+    path => '{domid}', 
+    method => 'POST',
+    description => "Add an authentication server.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    domid =>  get_standard_option('domid'),
+	    type => {
+		description => "Server type.",
+		type => 'string', 
+		enum => [ 'AD', 'LDAP' ],
+	    },
+	    server1 => { 
+		description => "Server IP address (or DNS name)",		
+		type => 'string',
+	    },
+	    server2 => { 
+		description => "Fallback Server IP address (or DNS name)",
+		type => 'string',
+		optional => 1,
+	    },
+	    comment => { 
+		type => 'string', 
+		optional => 1,
+	    },
+	    port => {
+		description => "LDAP Server port",
+		type => 'integer',
+		minimum => 1,
+		maximum => 65535,
+		optional => 1,
+	    },
+	    basedn => {
+		description => "LDAP base domain name",
+		type => 'string',
+		optional => 1,
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	PVE::AccessControl::lock_domain_config(
+	    sub {
+			
+		my $cfg = cfs_read_file($domainconfigfile);
+
+		my $domid = $param->{domid};
+	
+		die "domain '$domid' already exists\n" 
+		    if $cfg->{$domid};
+
+		$cfg->{$domid} = {
+		    type => $param->{type},
+		    server1 => $param->{server1},
+		};
+
+		foreach my $p (qw(server2 port basedn)) {
+		    $cfg->{$domid}->{$p} = $param->{$p} if $param->{$p};
+		}
+
+		cfs_write_file($domainconfigfile, $cfg);
+	    }, "add auth server failed");
+
+	return undef;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'update', 
+    protected => 1,
+    path => '{domid}', 
+    method => 'PUT',
+    description => "Add an authentication server.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    domid =>  get_standard_option('domid'),
+	    server1 => { 
+		description => "Server IP address (or DNS name)",		
+		type => 'string',
+		optional => 1,
+	    },
+	    server2 => { 
+		description => "Fallback Server IP address (or DNS name)",
+		type => 'string',
+		optional => 1,
+	    },
+	    comment => { 
+		type => 'string', 
+		optional => 1,
+	    },
+	    port => {
+		description => "LDAP Server port",
+		type => 'integer',
+		minimum => 1,
+		maximum => 65535,
+		optional => 1,
+	    },
+	    basedn => {
+		description => "LDAP base domain name",
+		type => 'string',
+		optional => 1,
+	    },
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	PVE::AccessControl::lock_domain_config(
+	    sub {
+			
+		my $cfg = cfs_read_file($domainconfigfile);
+
+		my $domid = $param->{domid};
+		delete $param->{domid};
+
+		die "domain '$domid' does not exist\n" 
+		    if !$cfg->{$domid};
+
+		foreach my $p (keys %$param) {
+		    $cfg->{$domid}->{$p} = $param->{$p};
+		}
+
+		cfs_write_file($domainconfigfile, $cfg);
+	    }, "update auth server failed");
+
+	return undef;
+    }});
+
+# fixme: return format!
+__PACKAGE__->register_method ({
+    name => 'read', 
+    path => '{domid}', 
+    method => 'GET',
+    description => "Get auth server configuration.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    domid =>  get_standard_option('domid'),
+	},
+    },
+    returns => {},
+    code => sub {
+	my ($param) = @_;
+
+	my $cfg = cfs_read_file($domainconfigfile);
+
+	my $domid = $param->{domid};
+	
+	my $data = $cfg->{$domid};
+	die "domain '$domid' does not exist\n" if !$data;
+
+	return $data;
+    }});
+
+
+__PACKAGE__->register_method ({
+    name => 'delete', 
+    protected => 1,
+    path => '{domid}', 
+    method => 'DELETE',
+    description => "Delete an authentication server.",
+    parameters => {
+   	additionalProperties => 0,
+	properties => {
+	    domid =>  get_standard_option('domid'),
+	}
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	PVE::AccessControl::lock_user_config(
+	    sub {
+
+		my $cfg = cfs_read_file($domainconfigfile);
+
+		my $domid = $param->{domid};
+	
+		die "domain '$domid' does not exist\n" if !$cfg->{$domid};
+
+		delete $cfg->{$domid};
+
+		cfs_write_file($domainconfigfile, $cfg);
+	    }, "delete auth server failed");
+	
+	return undef;
+    }});
+
+1;

Modified: pve-access-control/trunk/PVE/API2/Makefile
===================================================================
--- pve-access-control/trunk/PVE/API2/Makefile	2011-02-17 11:06:18 UTC (rev 5558)
+++ pve-access-control/trunk/PVE/API2/Makefile	2011-02-17 13:15:02 UTC (rev 5559)
@@ -1,6 +1,7 @@
 
 API2_SOURCES= 		 \
 	AccessControl.pm \
+	Domains.pm	 \
 	ACL.pm		 \
 	Role.pm		 \
 	Group.pm	 \

Modified: pve-access-control/trunk/PVE/AccessControl.pm
===================================================================
--- pve-access-control/trunk/PVE/AccessControl.pm	2011-02-17 11:06:18 UTC (rev 5558)
+++ pve-access-control/trunk/PVE/AccessControl.pm	2011-02-17 13:15:02 UTC (rev 5559)
@@ -37,7 +37,8 @@
 		  \&write_shadow_config);
 
 cfs_register_file($domainconfigfile, 
-		  \&parse_domains);
+		  \&parse_domains,
+		  \&write_domains);
 
 
 sub lock_user_config {
@@ -52,6 +53,18 @@
     }
 }
 
+sub lock_domain_config {
+    my ($code, $errmsg) = @_;
+
+    my $parent = ( caller(1) )[3];
+
+    cfs_lock_file($domainconfigfile, undef, $parent, $code);
+    my $err = $@;
+    if ($err) {
+	$errmsg ? die "$errmsg: $err" : die $err;
+    }
+}
+
 sub lock_shadow_config {
     my ($code, $errmsg) = @_;
 
@@ -458,19 +471,20 @@
     'Administrator' => $valid_privs, # all priviledges
 };
 
-my $valid_authtype = {
-    pam => 1,
-    ldap => 1,
-    shadow => 1,
-    ident => 1, 
-};
-
 my $valid_attributes = {
-    server1 => '[\w\d]+(.[\w\d]+)*',
-    server2 => '[\w\d]+(.[\w\d]+)*',
-    base_dn => '\w+=[\w\s]+(,\s*\w+=[\w\s]+)*',
-    user_attr => '\S{2,}',
-    port => '\d*',
+    ad => {
+	server1 => '[\w\d]+(.[\w\d]+)*',
+	server2 => '[\w\d]+(.[\w\d]+)*',
+	comment => '.*',
+    },
+    ldap => {
+	server1 => '[\w\d]+(.[\w\d]+)*',
+	server2 => '[\w\d]+(.[\w\d]+)*',
+	base_dn => '\w+=[\w\s]+(,\s*\w+=[\w\s]+)*',
+	user_attr => '\S{2,}',
+	port => '\d*',
+	comment => '.*',
+    }
 };
 
 sub add_role_privs {
@@ -767,6 +781,41 @@
     return $shadow;
 }
 
+sub write_domains {
+    my ($filename, $cfg) = @_;
+
+    my $data = '';
+
+    foreach my $domid (sort keys %$cfg) {
+	my $entry = $cfg->{$domid};
+	next if !$entry->{type};
+
+	my $formats = $valid_attributes->{$entry->{type}};
+	next if !$formats;
+
+	$data .= "$entry->{type}: $domid\n";
+
+	foreach my $k (sort keys %$entry) {
+	    next if $k eq 'type';
+	    my $v = $entry->{$k};
+	    if ($formats->{$k}) {
+		if ($v =~ m/^$formats->{$k}$/) {
+		    $v = encode_text($v) if $k eq 'comment';
+		    $data .= "\t$k $v\n";
+		} else {
+		    die "invalid value '$v' for attribute '$k'\n";
+		}
+	    } else {
+		die "invalid attribute '$k' - not supported\n";
+	    }
+	}
+
+	$data .= "\n";
+    }
+
+    return $data;
+}
+
 sub parse_domains {
     my ($filename, $raw) = @_;
 
@@ -805,11 +854,14 @@
 		    
 		next if $ignore; # skip
 
+		my $formats = $valid_attributes->{$entry->{type}};
+
 		if ($line =~ m/^\s+(\S+)(\s+(.*\S))?\s*$/) {
 		    my ($k, $v) = (lc($1), $3);
-		    if ($valid_attributes->{$k}) {
-			if ($v =~ m/^$valid_attributes->{$k}$/) {
+		    if ($formats->{$k}) {
+			if ($v =~ m/^$formats->{$k}$/) {
 			    if (!defined($entry->{$k})) {
+				$v = decode_text($v) if $k eq 'comment';
 				$entry->{$k} = $v;
 			    } else {
 				warn "ignoring duplicate attribute '$k $v'\n";



More information about the pve-devel mailing list