[pve-devel] r5558 - in pve-access-control/trunk: . PVE PVE/API2
svn-commits at proxmox.com
svn-commits at proxmox.com
Thu Feb 17 12:06:19 CET 2011
Author: dietmar
Date: 2011-02-17 12:06:18 +0100 (Thu, 17 Feb 2011)
New Revision: 5558
Modified:
pve-access-control/trunk/ChangeLog
pve-access-control/trunk/PVE/API2/User.pm
pve-access-control/trunk/PVE/AccessControl.pm
pve-access-control/trunk/README
pve-access-control/trunk/control.in
Log:
* 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
algorithm.
* PVE/API2/User.pm: save domid, name, comment and expire time for
user entries.
* PVE/AccessControl.pm (authenticate_user): check for expired
accounts
* control.in (Depends): depend on liburi-perl (we use URI::Escape
to encode text in our config files).
* PVE/AccessControl.pm (enable_user, disable_user): removed
clumsy methods, not needed.
Modified: pve-access-control/trunk/ChangeLog
===================================================================
--- pve-access-control/trunk/ChangeLog 2011-02-17 06:04:47 UTC (rev 5557)
+++ pve-access-control/trunk/ChangeLog 2011-02-17 11:06:18 UTC (rev 5558)
@@ -1,3 +1,22 @@
+2011-02-17 Proxmox Support Team <support at proxmox.com>
+
+ * 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
+ algorithm.
+
+ * PVE/API2/User.pm: save domid, name, comment and expire time for
+ user entries.
+
+ * PVE/AccessControl.pm (authenticate_user): check for expired
+ accounts
+
+ * control.in (Depends): depend on liburi-perl (we use URI::Escape
+ to encode text in our config files).
+
+ * PVE/AccessControl.pm (enable_user, disable_user): removed
+ clumsy methods, not needed.
+
2011-02-16 Proxmox Support Team <support at proxmox.com>
* README (privileges): Changes set of privileges. We try to be as
Modified: pve-access-control/trunk/PVE/API2/User.pm
===================================================================
--- pve-access-control/trunk/PVE/API2/User.pm 2011-02-17 06:04:47 UTC (rev 5557)
+++ pve-access-control/trunk/PVE/API2/User.pm 2011-02-17 11:06:18 UTC (rev 5558)
@@ -15,6 +15,24 @@
use base qw(PVE::RESTHandler);
+my $extract_user_data = sub {
+ my ($data) = @_;
+
+ my $res;
+
+ foreach my $prop (qw(domid enabled expire name comment)) {
+ $res->{$prop} = $data->{$prop} if defined($data->{$prop});
+ }
+
+ if ($data->{groups}) {
+ if (my @ga = keys %{$data->{groups}}) {
+ $res->{groups} = join(',', @ga);
+ }
+ }
+
+ return $res;
+};
+
# fixme: index should return more/all attributes?
__PACKAGE__->register_method ({
name => 'index',
@@ -45,7 +63,9 @@
foreach my $user (keys %{$usercfg->{users}}) {
next if $user eq 'root';
- push @$res, { id => $user };
+ my $entry = &$extract_user_data($usercfg->{users}->{$user});
+ $entry->{id} = $user;
+ push @$res, $entry;
}
return $res;
@@ -83,8 +103,17 @@
additionalProperties => 0,
properties => {
userid => get_standard_option('userid'),
+ domid => get_standard_option('domid', { optional => 1 }),
password => { type => 'string', optional => 1 },
groups => { type => 'string', optional => 1, format => 'pve-groupid-list'},
+ name => { type => 'string', optional => 1 },
+ comment => { type => 'string', optional => 1 },
+ expire => {
+ description => "Account expiration date (seconds since epoch). '0' means no expiration date.",
+ type => 'integer',
+ minimum => 0,
+ optional => 1
+ },
},
},
returns => { type => 'null' },
@@ -94,24 +123,22 @@
PVE::AccessControl::lock_user_config(
sub {
- my ($username, undef, $domain) =
- PVE::AccessControl::verify_username($param->{userid});
+ my $username = PVE::AccessControl::verify_username($param->{userid});
my $usercfg = cfs_read_file("user.cfg");
die "user '$username' already exists\n"
if $usercfg->{users}->{$username};
-
- if ($param->{password}) {
- if ($domain) {
- die "can't set password on auth domain '$domain'\n";
- } else {
- PVE::AccessControl::store_shadow_password($username, $param->{password});
- }
- }
+
+ my $domid = $param->{domid};
- PVE::AccessControl::enable_user($username, $usercfg);
+ PVE::AccessControl::domain_set_password($domid, $username, $param->{password})
+ if $param->{password};
+ $usercfg->{users}->{$username} = { enabled => 1 };
+ $usercfg->{users}->{$username}->{domid} = $domid if $domid;
+ $usercfg->{users}->{$username}->{expire} = $param->{expire} if $param->{expire};
+
if ($param->{groups}) {
foreach my $group (split_list($param->{groups})) {
if ($usercfg->{groups}->{$group}) {
@@ -122,6 +149,9 @@
}
}
+ $usercfg->{users}->{$username}->{name} = $param->{name} if $param->{name};
+ $usercfg->{users}->{$username}->{comment} = $param->{comment} if $param->{comment};
+
cfs_write_file("user.cfg", $usercfg);
}, "create user failed");
@@ -139,7 +169,17 @@
userid => get_standard_option('userid'),
},
},
- returns => {},
+ returns => {
+ additionalProperties => 0,
+ properties => {
+ domid => get_standard_option('domid'),
+ enabled => { type => 'boolean' },
+ expire => { type => 'integer' },
+ name => { type => 'string', optional => 1 },
+ comment => { type => 'string', optional => 1 },
+ groups => { type => 'string', optional => 1, format => 'pve-groupid-list'},
+ }
+ },
code => sub {
my ($param) = @_;
@@ -152,7 +192,7 @@
die "user '$username' does not exist\n" if !$data;
- return $data;
+ return &$extract_user_data($data);
}});
__PACKAGE__->register_method ({
@@ -165,6 +205,7 @@
additionalProperties => 0,
properties => {
userid => get_standard_option('userid'),
+ domid => get_standard_option('domid', { optional => 1 }),
password => { type => 'string', optional => 1 },
groups => { type => 'string', optional => 1, format => 'pve-groupid-list' },
append => {
@@ -176,6 +217,12 @@
unlock => { type => 'boolean', optional => 1 },
name => { type => 'string', optional => 1 },
comment => { type => 'string', optional => 1 },
+ expire => {
+ description => "Account expiration date (seconds since epoch). '0' means no expiration date.",
+ type => 'integer',
+ minimum => 0,
+ optional => 1
+ },
},
},
returns => { type => 'null' },
@@ -196,18 +243,19 @@
die "user '$username' does not exist\n"
if !$usercfg->{users}->{$username};
- if ($param->{password}) {
- if ($domain) {
- die "can't set password on auth domain '$domain'\n";
- } else {
- PVE::AccessControl::store_shadow_password($username, $param->{password});
- }
- }
+ my $domid = $param->{domid};
- PVE::AccessControl::enable_user($username, $usercfg) if $param->{unlock};
+ PVE::AccessControl::domain_set_password($domid, $username, $param->{password})
+ if $param->{password};
- PVE::AccessControl::disable_user($username, $usercfg) if $param->{lock};
+ $usercfg->{users}->{$username}->{enabled} = 1 if $param->{unlock};
+ $usercfg->{users}->{$username}->{enabled} = 0 if $param->{lock};
+
+ $usercfg->{users}->{$username}->{domid} = $domid if $domid;
+
+ $usercfg->{users}->{$username}->{expire} = $param->{expire} if $param->{expire};
+
PVE::AccessControl::delete_user_group($username, $usercfg)
if (!$param->{append} && $param->{groups});
@@ -221,10 +269,9 @@
}
}
- PVE::AccessControl::name_user($username, $usercfg) if $param->{name};
+ $usercfg->{users}->{$username}->{name} = $param->{name} if $param->{name};
+ $usercfg->{users}->{$username}->{comment} = $param->{comment} if $param->{comment};
- PVE::AccessControl::comment_user($username, $usercfg) if $param->{comment};
-
cfs_write_file("user.cfg", $usercfg);
}, "update user failed");
Modified: pve-access-control/trunk/PVE/AccessControl.pm
===================================================================
--- pve-access-control/trunk/PVE/AccessControl.pm 2011-02-17 06:04:47 UTC (rev 5557)
+++ pve-access-control/trunk/PVE/AccessControl.pm 2011-02-17 11:06:18 UTC (rev 5558)
@@ -11,6 +11,8 @@
use PVE::Tools qw(run_command lock_file file_get_contents split_list safe_print);
use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
use PVE::JSONSchema;
+use Encode;
+use URI::Escape;
use Data::Dumper; # fixme: remove
@@ -198,13 +200,13 @@
sub authenticate_user_ldap {
- my ($entry, $username, $password) = @_;
+ my ($entry, $server, $username, $password) = @_;
my (undef, $user, $domain) = verify_username($username);
my $default_port = ($entry->{type} eq 'ldap') ? 389 : 636;
my $port = $entry->{port} ? $entry->{port} : $default_port;
my $conn_string = $entry->{type} . "://" if ($entry->{type} ne 'ldap');
- $conn_string .= $entry->{server} . ":" . $port;
+ $conn_string .= $server . ":" . $port;
my $ldap = Net::LDAP->new($conn_string, verify => 'none') || die "$@\n";
my $search = $entry->{user_attr} . "=" . $user;
my $result = $ldap->search( base => "$entry->{base_dn}",
@@ -225,74 +227,46 @@
}
sub authenticate_user_domain {
-
- my ($username, $password) = @_;
+ my ($domid, $username, $password) = @_;
my $domain_cfg = cfs_read_file($domainconfigfile);
- my (undef, $user, $domain) = verify_username($username);
+ die "no auth domain specified" if !$domid;
- my $shadow = {
- type => "shadow",
- domains => [ '' ], # names without domain part
- };
+ if ($domid eq 'pam') {
+ authenticate_user_pam($username, $password);
+ return;
+ }
- my $pam = {
- type => "PAM",
- domains => [ 'localhost' ],
- };
+ eval {
+ if ($domid eq 'pve') {
+ authenticate_user_shadow($username, $password);
+ } else {
- 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 ((!$domain && ($dom eq '')) ||
- ($domain && ($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);
- } elsif (($entry->{type} eq 'ldap') || ($entry->{type} eq 'ldaps')) {
- authenticate_user_ldap($entry, $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;
- }
-
- # no exceptions, so auth was successful
- return 1;
- }
+ my $cfg = $domain_cfg->{$domid};
+ die "auth domain '$domid' does not exists\n" if !$cfg;
+
+ if ($cfg->{type} eq 'ad') {
+ eval { authenticate_user_ad($cfg->{server1}, $username, $password); };
+ my $err = $@;
+ return if !$err;
+ die $err if !$cfg->{server2};
+ authenticate_user_ad($cfg->{server2}, $username, $password);
+ } elsif (($cfg->{type} eq 'ldap') || ($cfg->{type} eq 'ldaps')) {
+ eval { authenticate_user_ldap($cfg, $cfg->{server1}, $username, $password); };
+ my $err = $@;
+ return if !$err;
+ die $err if !$cfg->{server2};
+ authenticate_user_ldap($cfg, $cfg->{server2}, $username, $password);
+ } else {
+ die "unknown auth type '$cfg->{type}'\n";
}
}
+ };
+ if (my $err = $@) {
+ sleep(2); # timeout after failed auth
+ die $err;
}
-
- sleep(2); # timeout after failed auth
-
- die "domain \'$domain\' not defined\n" if !$found;
- die $errmsg || "internal error";
}
sub user_enabled {
@@ -317,18 +291,28 @@
die "no username specified\n" if !$username;
- my ($user, $domain);
-
- ($username, $user, $domain) = verify_username($username);
+ $username = verify_username($username);
my $usercfg = cfs_read_file('user.cfg');
- die "no such user ('$username')\n" if !user_enabled($usercfg, $username);
+ if (!user_enabled($usercfg, $username)) {
+ sleep(2);
+ die "no such user ('$username')\n"
+ }
+ my $ctime = time();
+ my $expire = $usercfg->{users}->{$username}->{expire};
+ my $domid = $usercfg->{users}->{$username}->{domid};
+
+ if ($expire && ($expire < $ctime)) {
+ sleep(2);
+ die "account expired\n"
+ }
+
if ($username eq 'root') { # always use PAM for root
authenticate_user_pam($username, $password);
} else {
- authenticate_user_domain($username, $password);
+ authenticate_user_domain($domid, $username, $password);
}
};
@@ -338,8 +322,8 @@
}
sub delete_shadow_password {
-
my ($username) = @_;
+
lock_shadow_config(sub {
my $shadow_cfg = cfs_read_file($shadowconfigfile);
delete ($shadow_cfg->{users}->{$username})
@@ -349,8 +333,8 @@
}
sub store_shadow_password {
-
- my ($username,$password) = @_;
+ my ($username, $password) = @_;
+
lock_shadow_config(sub {
my $shadow_cfg = cfs_read_file($shadowconfigfile);
$shadow_cfg->{users}->{$username}->{shadow} = encrypt_pw($password);
@@ -365,6 +349,35 @@
return crypt (encode("utf8", $pw), "\$5\$$time\$");
}
+sub store_pam_password {
+ my ($username, $password) = @_;
+
+ my $cmd = ['/usr/sbin/usermod'];
+
+ my $epw = encrypt_pw($password);
+ push @$cmd, '-p', $epw;
+
+ push @$cmd, $username;
+
+ run_command($cmd);
+}
+
+sub domain_set_password {
+ my ($domid, $username, $password) = @_;
+
+ if ($username eq 'root') {
+ store_pam_password($username, $password);
+ } elsif ($domid) {
+ if ($domid eq 'pam') {
+ store_pam_password($username, $password);
+ } else {
+ die "can't set password on auth domain '$domid'\n";
+ }
+ } else {
+ store_shadow_password($username, $password);
+ }
+}
+
sub add_user_group {
my ($username, $usercfg, $group) = @_;
@@ -406,34 +419,20 @@
}
-sub disable_user {
+sub encode_text {
+ my ($text) = @_;
- my ($username, $usercfg) = @_;
-
- $usercfg->{users}->{$username} = { enabled => 0 };
-
+ # all control and hi-bit characters, and ':'
+ my $unsafe = "^\x20-\x39\x3b-\x7e";
+ return uri_escape(Encode::encode("utf8", $text), $unsafe);
}
-sub enable_user {
+sub decode_text {
+ my ($data) = @_;
- my ($username, $usercfg) = @_;
-
- $usercfg->{users}->{$username} = { enabled => 1 };
-
+ return Encode::decode("utf8", uri_unescape($data));
}
-sub name_user {
-
- warn "change name not implemented\n";
-
-}
-
-sub comment_user {
-
- warn "change comment not implemented\n";
-
-}
-
my $valid_privs = {
'VM.Audit' => 1,
'VM.Modify' => 1,
@@ -467,7 +466,8 @@
};
my $valid_attributes = {
- server => '[\w\d]+(.[\w\d]+)*',
+ 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*',
@@ -518,8 +518,6 @@
return undef;
}
- $username =~ s/root\@localhost/root/;
-
# we only allow a limited set of characters (colon is not allowed,
# because we store usernames in colon separated lists)!
if ($username =~ m/^([A-Za-z0-9\.\-_]+)(\@([A-Za-z0-9\.\-_]+))?$/) {
@@ -535,6 +533,10 @@
type => 'string', format => 'pve-userid',
});
+PVE::JSONSchema::register_standard_option('domid', {
+ description => "Authentication domain ID",
+ type => 'string', format => 'pve-configid',
+});
PVE::JSONSchema::register_format('pve-groupid', \&verify_groupname);
sub verify_groupname {
@@ -614,15 +616,28 @@
my $et = shift @data;
if ($et eq 'user') {
- my ($user, $enabled) = @data;
+ my ($user, $enabled, $expire, $domid, $name, $comment) = @data;
if (!verify_username($user, 1)) {
warn "user config - ignore user '$user' - invalid characters in user name\n";
next;
}
-
+
+ if ($domid && !PVE::JSONSchema::pve_verify_configid($domid, 1)) {
+ warn "user config - ignore user '$user' - (illegal characters in domain '$domid')\n";
+ next;
+ }
+
$enabled = $enabled ? 1 : 0;
+ $expire = 0 if !$expire;
+
+ if ($expire !~ m/^\d+$/) {
+ warn "user config - ignore user '$user' - (illegal characters in expire '$expire')\n";
+ next;
+ }
+ $expire = int($expire);
+
#if (!verify_groupname ($group, 1)) {
# warn "user config - ignore user '$user' - invalid characters in group name\n";
# next;
@@ -632,6 +647,10 @@
enabled => $enabled,
# group => $group,
};
+ $cfg->{users}->{$user}->{domid} = $domid ? $domid : 'pve';
+ $cfg->{users}->{$user}->{name} = decode_text($name) if $name;
+ $cfg->{users}->{$user}->{comment} = decode_text($comment) if $comment;
+ $cfg->{users}->{$user}->{expire} = $expire;
#$cfg->{users}->{$user}->{groups}->{$group} = 1;
#$cfg->{groups}->{$group}->{$user} = 1;
@@ -751,8 +770,7 @@
sub parse_domains {
my ($filename, $raw) = @_;
- my $connlist = [];
- my $ad;
+ my $cfg = {};
$raw = "" if !defined($raw);
@@ -762,24 +780,21 @@
next if $line =~ m/^\#/; # skip comment lines
next if $line =~ m/^\s*$/; # skip empty lines
- if ($line =~ m/^(\S+):\s*(.+)\s*$/) {
+ if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
+ my $domid = $2;
my $type = lc($1);
- my $domains = $2;
+
my $ignore = 0;
+ my $entry;
- if (($type ne "ad") && ($type ne "ldap") && ($type ne "ldaps")) {
+ if (!PVE::JSONSchema::pve_verify_configid($domid, 1)) {
$ignore = 1;
- warn "ignoring domains '$domains' - (unsupported authentication type '$type')\n";
+ warn "ignoring domain '$domid' - (illegal characters)\n";
+ } elsif (($type ne "ad") && ($type ne "ldap") && ($type ne "ldaps")) {
+ $ignore = 1;
+ warn "ignoring domain '$domid' - (unsupported authentication type '$type')\n";
} else {
- $ad = { type => $type, domains => [] };
-
- foreach my $domain (split_list($domains)) {
- if (!parse_domain_name ($domain, 1)) {
- warn "ignoring domain '$domain' - (invalid form)\n";
- } else {
- push @{$ad->{domains}}, $domain;
- }
- }
+ $entry = { type => $type };
}
while ($raw =~ s/^(.*)\n//) {
@@ -794,8 +809,8 @@
my ($k, $v) = (lc($1), $3);
if ($valid_attributes->{$k}) {
if ($v =~ m/^$valid_attributes->{$k}$/) {
- if (!defined($ad->{$k})) {
- $ad->{$k} = $v;
+ if (!defined($entry->{$k})) {
+ $entry->{$k} = $v;
} else {
warn "ignoring duplicate attribute '$k $v'\n";
}
@@ -809,24 +824,32 @@
warn "ignore config line: $line\n";
}
}
- if (!$ad->{server}) {
- warn "ignoring domain '$domains' - missing server attribute\n";
- } elsif ((($ad->{type} eq "ldap") || ($ad->{type} eq "ldaps")) && (!$ad->{user_attr})) {
- warn "ignoring domain '$domains' - missing user attribute\n";
- } elsif ((($ad->{type} eq "ldap") || ($ad->{type} eq "ldaps")) && (!$ad->{base_dn})) {
- warn "ignoring domain '$domains' - missing base_dn attribute\n";
+
+ if ($entry->{server2} && !$entry->{server1}) {
+ $entry->{server1} = $entry->{server2};
+ delete $entry->{server2};
+ }
+
+ if ($ignore) {
+ # do nothing
+ } elsif (!$entry->{server1}) {
+ warn "ignoring domain '$domid' - missing server attribute\n";
+ } elsif ((($entry->{type} eq "ldap") || ($entry->{type} eq "ldaps")) &&
+ (!$entry->{user_attr})) {
+ warn "ignoring domain '$domid' - missing user attribute\n";
+ } elsif ((($entry->{type} eq "ldap") || ($entry->{type} eq "ldaps")) &&
+ (!$entry->{base_dn})) {
+ warn "ignoring domain '$domid' - missing base_dn attribute\n";
} else {
- push(@$connlist, $ad) if !$ignore;
+ $cfg->{$domid} = $entry;
}
- $ad = undef
} else {
warn "ignore config line: $line\n";
-
}
}
- return $connlist;
+ return $cfg;
}
sub parse_domain_name {
@@ -859,7 +882,12 @@
next if $user eq 'root';
my $d = $cfg->{users}->{$user};
- $data .= "user:$user:$d->{enabled}:\n";
+ my $domid = $d->{domid} || 'pve';
+ my $name = $d->{name} ? encode_text($d->{name}) : '';
+ my $comment = $d->{comment} ? encode_text($d->{comment}) : '';
+ my $expire = int($d->{expire}) || 0;
+ my $enabled = $d->{enabled} ? 1 : 0;
+ $data .= "user:$user:$enabled:$expire:$domid:$name:$comment:\n";
}
$data .= "\n";
Modified: pve-access-control/trunk/README
===================================================================
--- pve-access-control/trunk/README 2011-02-17 06:04:47 UTC (rev 5557)
+++ pve-access-control/trunk/README 2011-02-17 11:06:18 UTC (rev 5558)
@@ -12,30 +12,34 @@
User Authentication
===================
-Users are identified by there email address. The domain part of the
-email determines how a user gets authenticated. The file
+User names need to be unique (else logging gets complicated). So we
+suggest to use email addresses. Each user has an associated
+authentication domain, which references an entry in the file
+'/etc/pve/priv/domain.cfg'. The file associates domain IDs with
+authentication servers.
-/etc/pve/auth/domains.cfg
-
-associates domains with authentication servers.
-
----example domains.cfg ------------------
-AD: proxmox.com,maurer-it.com
- server 10.10.10.1
+# an active directory server
+AD: mycompany
+ server1 10.10.10.1
+ server2 10.10.10.2
...
+# an LDAP server
LDAP: example.com
- server 10.10.10.2
+ server1 10.10.10.2
....
------------------------------------------
-Users without domains get authenticated using our own password file.
+There are 2 special authentication domains name 'pve' and 'pam':
-User with 'localhost' as domain ("<user>@localhost") use PAM for authentication.
+ * pve: stores paswords to "/etc/pve/priv/shadow.cfg" (SHA256 crypt);
+ * pam: use unix 'pam'
+
Proposed user database fields:
==============================
@@ -43,20 +47,18 @@
login_name: email address (user at domain)
enabled: 1 = TRUE, 0 = FALSE
+ expire: <integer> (account expiration date)
+ domid: reference to authentication domain
+ name: full user name
+ comment: arbitrary comment
- # account type: pam, ldap, shadow, ident (how to verify password)
- # group: primary group name
- # real_name: full user name
- # comment: arbitrary comment
special user root: The root user has full administrative privileges
- encrypted passwords (SHA256 crypt) are stored in separate shadow file: /etc/pve/auth/shadow.cfg
-
group:
group_name: the name of the group
- description: a more verbose description
+ comment: a more verbose description
user_list: list of login names
special group root: group root has full administrative privileges
Modified: pve-access-control/trunk/control.in
===================================================================
--- pve-access-control/trunk/control.in 2011-02-17 06:04:47 UTC (rev 5557)
+++ pve-access-control/trunk/control.in 2011-02-17 11:06:18 UTC (rev 5558)
@@ -3,7 +3,7 @@
Section: perl
Priority: optional
Architecture: @@ARCH@@
-Depends: libc6 (>= 2.3), perl (>= 5.6.0-16), libcrypt-openssl-rsa-perl, libcrypt-openssl-random-perl, libjson-xs-perl, libjson-perl, libterm-readline-gnu-perl,libnet-ldap-perl, libpve-common-perl, pve-cluster
+Depends: libc6 (>= 2.3), perl (>= 5.6.0-16), libcrypt-openssl-rsa-perl, libcrypt-openssl-random-perl, libjson-xs-perl, libjson-perl, libterm-readline-gnu-perl,libnet-ldap-perl, libpve-common-perl, pve-cluster, liburi-perl
Maintainer: Proxmox Support Team <support at proxmox.com>
Description: Proxmox VE access control library
This package contains the role based user management and access
More information about the pve-devel
mailing list