diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm index e8af7aa2..ad40638d 100644 --- a/PVE/API2/Cluster.pm +++ b/PVE/API2/Cluster.pm @@ -106,7 +106,7 @@ __PACKAGE__->register_method({ my $max = $param->{max} || 0; my $user = $rpcenv->get_user(); - my $admin = $rpcenv->check($user, "/", [ 'Sys.Syslog' ]); + my $admin = $rpcenv->check($user, "/", [ 'Sys.Syslog' ], 1); my $loguser = $admin ? '' : $user; @@ -162,7 +162,7 @@ __PACKAGE__->register_method({ my $data = $idlist->{$vmid}; - next if !$rpcenv->check($user, "/vms/$vmid", [ 'VM.Audit' ]); + next if !$rpcenv->check($user, "/vms/$vmid", [ 'VM.Audit' ], 1); my $entry = { id => "$data->{type}/$vmid", @@ -221,7 +221,7 @@ __PACKAGE__->register_method({ foreach my $storeid (@sids) { my $scfg = PVE::Storage::storage_config($cfg, $storeid); - next if !$rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Audit' ]); + next if !$rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Audit' ], 1); # we create a entry for each node foreach my $node (@$nodelist) { next if !PVE::Storage::storage_check_enabled($cfg, $storeid, $node, 1); @@ -276,7 +276,7 @@ __PACKAGE__->register_method({ return $res if !$tlist; - my $all = $rpcenv->check($user, "/", [ 'Sys.Audit' ]); + my $all = $rpcenv->check($user, "/", [ 'Sys.Audit' ], 1); foreach my $task (@$tlist) { push @$res, $task if $all || ($task->{user} eq $user); diff --git a/PVE/API2/Tasks.pm b/PVE/API2/Tasks.pm index 43244f4b..79070df4 100644 --- a/PVE/API2/Tasks.pm +++ b/PVE/API2/Tasks.pm @@ -75,7 +75,7 @@ __PACKAGE__->register_method({ my $count = 0; my $line; - my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]); + my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ], 1); my $parse_line = sub { if ($line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/) { @@ -175,9 +175,9 @@ __PACKAGE__->register_method({ my $user = $rpcenv->get_user(); my $node = $param->{node}; - my $sysadmin = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Console' ]); - die "Permission check failed\n" - if !($sysadmin || $user eq $task->{user}); + if ($user ne $task->{user}) { + $rpcenv->check($user, "/nodes/$node", [ 'Sys.Console' ]); + } PVE::RPCEnvironment::check_worker($param->{upid}, 1); @@ -237,9 +237,9 @@ __PACKAGE__->register_method({ my $user = $rpcenv->get_user(); my $node = $param->{node}; - my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]); - die "Permission check failed\n" - if !($auditor || $user eq $task->{user}); + if ($user ne $task->{user}) { + $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]); + } my $fh = IO::File->new($filename, "r"); raise_param_exc({ upid => "no such task - unable to open file - $!" }) if !$fh; @@ -309,9 +309,9 @@ __PACKAGE__->register_method({ my $user = $rpcenv->get_user(); my $node = $param->{node}; - my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]); - die "Permission check failed\n" - if !($auditor || $user eq $task->{user}); + if ($user ne $task->{user}) { + $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]); + } my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid}); $task->{status} = ($pstart && ($pstart == $task->{pstart})) ? diff --git a/PVE/REST.pm b/PVE/REST.pm index 402ccb22..2a9c1ceb 100644 --- a/PVE/REST.pm +++ b/PVE/REST.pm @@ -15,6 +15,7 @@ use LWP::UserAgent; use HTTP::Request::Common; use HTTP::Status qw(:constants :is status_message); use HTML::Entities; +use PVE::Exception qw(raise raise_perm_exc); use PVE::JSONSchema; use PVE::AccessControl; use PVE::RPCEnvironment; @@ -275,11 +276,11 @@ my $check_permissions = sub { return 1 if !$username && $perm->{user} eq 'world'; - return 0 if !$username; + raise_perm_exc("user != null") if !$username; return 1 if $username eq 'root@pam'; - die "permission check failed (user != root)\n" if !$perm; + raise_perm_exc('user != root@pam') if !$perm; return 1 if $perm->{user} && $perm->{user} eq 'all'; @@ -288,14 +289,11 @@ my $check_permissions = sub { if ($perm->{path} && $perm->{privs}) { my $path = PVE::Tools::template_replace($perm->{path}, $param); - if (!$rpcenv->check($username, $path, $perm->{privs})) { - my $privstr = join(',', @{$perm->{privs}}); - die "Permission check failed ($path, $privstr)\n"; - } + $rpcenv->check($username, $path, $perm->{privs}); return 1; } - die "Permission check failed\n"; + raise_perm_exc(); }; sub rest_handler { @@ -332,7 +330,7 @@ sub rest_handler { my ($node, $storeid) = ($1, $2); my $perm = { path => "/storage/$storeid", - privs => [ 'abc' ], + privs => [ 'Datastore.AllocateSpace' ], }; &$check_permissions($rpcenv, $perm, $username, {}); $isUpload = 1; @@ -347,7 +345,7 @@ sub rest_handler { if (my $err = $@) { return { status => HTTP_UNAUTHORIZED, - message => $err, + message => "$err", # always convert exception to string }; } } @@ -392,7 +390,7 @@ sub rest_handler { if (my $err = $@) { return { status => HTTP_FORBIDDEN, - message => $err, + message => "$err", # always convert exception to string }; } @@ -411,7 +409,7 @@ sub rest_handler { if (my $err = $@) { return { status => HTTP_INTERNAL_SERVER_ERROR, - message => $err, + message => "$err", # always convert exception to string }; } if ($remip) { @@ -446,11 +444,11 @@ sub rest_handler { if ($err) { if (ref($err) eq "PVE::Exception") { $resp->{status} = $err->{code} || HTTP_INTERNAL_SERVER_ERROR; - $resp->{message} = $err->{msg} || $@; $resp->{errors} = $err->{errors} if $err->{errors}; + $resp->{message} = $err->{msg}; } else { $resp->{status} = HTTP_INTERNAL_SERVER_ERROR; - $resp->{message} = $@; + $resp->{message} = "$err"; } } diff --git a/www/manager/dc/ACLView.js b/www/manager/dc/ACLView.js index 7b1a787e..442cfb55 100644 --- a/www/manager/dc/ACLView.js +++ b/www/manager/dc/ACLView.js @@ -178,6 +178,8 @@ Ext.define('PVE.dc.ACLView', { } }); + PVE.Utils.monStoreErrors(me, store); + Ext.apply(me, { store: store, selModel: sm, diff --git a/www/manager/dc/GroupView.js b/www/manager/dc/GroupView.js index c2a687ea..6950a46a 100644 --- a/www/manager/dc/GroupView.js +++ b/www/manager/dc/GroupView.js @@ -75,6 +75,8 @@ Ext.define('PVE.dc.GroupView', { edit_btn, remove_btn ]; + PVE.Utils.monStoreErrors(me, store); + Ext.apply(me, { store: store, selModel: sm, diff --git a/www/manager/dc/RoleView.js b/www/manager/dc/RoleView.js index 94b19caf..cbfe82d2 100644 --- a/www/manager/dc/RoleView.js +++ b/www/manager/dc/RoleView.js @@ -26,6 +26,8 @@ Ext.define('PVE.dc.RoleView', { return value.replace(/\,/g, ' '); }; + PVE.Utils.monStoreErrors(me, store); + Ext.apply(me, { store: store, stateful: false, diff --git a/www/manager/dc/UserEdit.js b/www/manager/dc/UserEdit.js index 8799dedc..eb7ce65e 100644 --- a/www/manager/dc/UserEdit.js +++ b/www/manager/dc/UserEdit.js @@ -136,9 +136,7 @@ Ext.define('PVE.dc.UserEdit', { }, submitValue: false }); - } else { - update_passwd_field(me.userid.match(/@([^@]+)$/)[1]); - } + } var ipanel = Ext.create('PVE.panel.InputPanel', { column1: column1, diff --git a/www/manager/dc/UserView.js b/www/manager/dc/UserView.js index 76437f0c..9b242ee7 100644 --- a/www/manager/dc/UserView.js +++ b/www/manager/dc/UserView.js @@ -1,3 +1,53 @@ +Ext.define('PVE.window.PasswordEdit', { + extend: 'PVE.window.Edit', + + initComponent : function() { + var me = this; + + if (!me.userid) { + throw "no userid specified"; + } + + var validate_pw = function() { + if (verifypw.getValue() !== pwfield.getValue()) { + return gettext("Passwords does not match"); + } + return true; + }; + + var verifypw = Ext.createWidget('textfield', { + inputType: 'password', + fieldLabel: gettext('Verify Password'), + name: 'verifypassword', + submitValue: false, + validator: validate_pw + }); + + var pwfield = Ext.createWidget('textfield', { + inputType: 'password', + fieldLabel: gettext('Password'), + minLength: 5, + name: 'password', + validator: validate_pw + }); + + Ext.apply(me, { + subject: gettext('Password'), + url: '/api2/extjs/access/password', + items: [ + pwfield, verifypw, + { + xtype: 'hiddenfield', + name: 'userid', + value: me.userid, + } + ] + }); + + me.callParent(); + } +}); + Ext.define('PVE.dc.UserView', { extend: 'Ext.grid.GridPanel', @@ -69,6 +119,19 @@ Ext.define('PVE.dc.UserView', { handler: run_editor }); + var pwchange_btn = new PVE.button.Button({ + text: gettext('Password'), + disabled: true, + selModel: sm, + handler: function(btn, event, rec) { + var win = Ext.create('PVE.window.PasswordEdit',{ + userid: rec.data.userid + }); + win.on('destroy', reload); + win.show(); + } + }); + var tbar = [ { text: gettext('Create'), @@ -79,7 +142,7 @@ Ext.define('PVE.dc.UserView', { win.show(); } }, - edit_btn, remove_btn + edit_btn, remove_btn, pwchange_btn ]; var render_full_name = function(firstname, metaData, record) { diff --git a/www/manager/window/NotesEdit.js b/www/manager/window/NotesEdit.js index 868a46df..650b196b 100644 --- a/www/manager/window/NotesEdit.js +++ b/www/manager/window/NotesEdit.js @@ -5,7 +5,7 @@ Ext.define('PVE.window.NotesEdit', { var me = this; Ext.apply(me, { - title: "Notes", + title: gettext('Notes'), width: 600, layout: 'fit', items: {