2023-01-24 15:29:31 +01:00
|
|
|
/* Copyright (c) Cloud Software Group, Inc.
|
2013-06-24 13:41:48 +02:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms,
|
|
|
|
* with or without modification, are permitted provided
|
|
|
|
* that the following conditions are met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above
|
|
|
|
* copyright notice, this list of conditions and the
|
|
|
|
* following disclaimer.
|
|
|
|
* * Redistributions in binary form must reproduce the above
|
|
|
|
* copyright notice, this list of conditions and the
|
|
|
|
* following disclaimer in the documentation and/or other
|
|
|
|
* materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Windows.Forms;
|
|
|
|
using XenAPI;
|
|
|
|
using XenAdmin.Actions;
|
|
|
|
using XenAdmin.Network;
|
|
|
|
using XenAdmin.Core;
|
|
|
|
|
|
|
|
|
|
|
|
namespace XenAdmin.Dialogs
|
|
|
|
{
|
|
|
|
public partial class RoleElevationDialog : XenDialogBase
|
|
|
|
{
|
|
|
|
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
2019-08-08 14:05:40 +02:00
|
|
|
|
|
|
|
public Session elevatedSession;
|
2013-06-24 13:41:48 +02:00
|
|
|
public string elevatedPassword;
|
|
|
|
public string elevatedUsername;
|
|
|
|
|
|
|
|
private List<Role> authorizedRoles;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Displays a dialog informing the user they need a different role to complete the task, and offers the chance to switch user. Optionally logs
|
|
|
|
/// out the elevated session. If successful exposes the elevated session, password and username as fields.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="connection">The current server connection with the role information</param>
|
|
|
|
/// <param name="session">The session on which we have been denied access</param>
|
|
|
|
/// <param name="authorizedRoles">A list of roles that are able to complete the task</param>
|
|
|
|
/// <param name="actionTitle">A description of the current action, if null or empty will not be displayed</param>
|
|
|
|
public RoleElevationDialog(IXenConnection connection, Session session, List<Role> authorizedRoles, string actionTitle)
|
2019-10-10 18:15:16 +02:00
|
|
|
:base(connection)
|
2013-06-24 13:41:48 +02:00
|
|
|
{
|
|
|
|
InitializeComponent();
|
|
|
|
UserDetails ud = session.CurrentUserDetails;
|
2023-03-22 23:10:52 +01:00
|
|
|
labelCurrentUserValue.Text = ud?.UserDisplayName ?? ud?.UserName ?? Messages.UNKNOWN_AD_USER;
|
2023-08-02 12:44:05 +02:00
|
|
|
labelCurrentRoleValue.Text = Role.FriendlyCsvRoleList(session.Roles);
|
2013-06-24 13:41:48 +02:00
|
|
|
authorizedRoles.Sort((r1, r2) => r2.CompareTo(r1));
|
2023-08-02 12:44:05 +02:00
|
|
|
labelRequiredRoleValue.Text = Role.FriendlyCsvRoleList(authorizedRoles);
|
2013-06-24 13:41:48 +02:00
|
|
|
labelServerValue.Text = Helpers.GetName(connection);
|
|
|
|
labelServer.Text = Helpers.IsPool(connection) ? Messages.POOL_COLON : Messages.SERVER_COLON;
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(actionTitle))
|
|
|
|
{
|
|
|
|
labelCurrentAction.Visible = false;
|
|
|
|
labelCurrentActionValue.Visible = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
labelCurrentActionValue.Text = actionTitle;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.authorizedRoles = authorizedRoles;
|
|
|
|
}
|
|
|
|
|
2021-03-16 02:50:45 +01:00
|
|
|
protected override void OnLoad(EventArgs e)
|
|
|
|
{
|
|
|
|
base.OnLoad(e);
|
|
|
|
Text = BrandManager.BrandConsole;
|
|
|
|
}
|
|
|
|
|
2013-06-24 13:41:48 +02:00
|
|
|
private void buttonAuthorize_Click(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Exception delegateException = null;
|
|
|
|
log.Debug("Testing logging in with the new credentials");
|
2023-04-28 11:11:31 +02:00
|
|
|
var loginAction = new DelegatedAsyncAction(connection,
|
2013-06-24 13:41:48 +02:00
|
|
|
Messages.AUTHORIZING_USER,
|
|
|
|
Messages.CREDENTIALS_CHECKING,
|
|
|
|
Messages.CREDENTIALS_CHECK_COMPLETE,
|
|
|
|
delegate
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
elevatedSession = connection.ElevatedSession(TextBoxUsername.Text.Trim(), TextBoxPassword.Text);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
delegateException = ex;
|
|
|
|
}
|
2023-04-28 11:11:31 +02:00
|
|
|
}, true);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
2021-09-23 14:13:07 +02:00
|
|
|
using (var dlg = new ActionProgressDialog(loginAction, ProgressBarStyle.Marquee) {ShowTryAgainMessage = false})
|
2016-06-20 14:17:42 +02:00
|
|
|
dlg.ShowDialog(this);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
// The exception would have been handled by the action progress dialog, just return the user to the sudo dialog
|
|
|
|
if (loginAction.Exception != null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(HandledAnyDelegateException(delegateException))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (elevatedSession.IsLocalSuperuser || SessionAuthorized(elevatedSession))
|
|
|
|
{
|
|
|
|
elevatedUsername = TextBoxUsername.Text.Trim();
|
|
|
|
elevatedPassword = TextBoxPassword.Text;
|
|
|
|
DialogResult = DialogResult.OK;
|
|
|
|
Close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ShowNotAuthorisedDialog();
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
log.DebugFormat("Exception when attempting to sudo action: {0} ", ex);
|
2021-03-16 02:50:45 +01:00
|
|
|
using (var dlg = new ErrorDialog(string.Format(Messages.USER_AUTHORIZATION_FAILED, BrandManager.BrandConsole, TextBoxUsername.Text)))
|
2016-06-20 11:49:12 +02:00
|
|
|
dlg.ShowDialog(Parent);
|
2019-08-08 14:05:40 +02:00
|
|
|
|
|
|
|
TextBoxPassword.Focus();
|
|
|
|
TextBoxPassword.SelectAll();
|
2013-06-24 13:41:48 +02:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
// Check whether we have a successful elevated session and whether we have been asked to log it out
|
|
|
|
// If non successful (most likely the new subject is not authorized) then log it out anyway.
|
|
|
|
if (elevatedSession != null && DialogResult != DialogResult.OK)
|
|
|
|
{
|
|
|
|
elevatedSession.Connection.Logout(elevatedSession);
|
|
|
|
elevatedSession = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool HandledAnyDelegateException(Exception delegateException)
|
|
|
|
{
|
|
|
|
if (delegateException != null)
|
|
|
|
{
|
|
|
|
Failure f = delegateException as Failure;
|
|
|
|
if (f != null && f.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
|
|
|
|
{
|
|
|
|
ShowNotAuthorisedDialog();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
throw delegateException;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowNotAuthorisedDialog()
|
|
|
|
{
|
2020-04-22 15:47:03 +02:00
|
|
|
using (var dlg = new ErrorDialog(Messages.USER_NOT_AUTHORIZED)
|
|
|
|
{WindowTitle = Messages.PERMISSION_DENIED})
|
2016-06-20 11:49:12 +02:00
|
|
|
{
|
|
|
|
dlg.ShowDialog(this);
|
|
|
|
}
|
2019-08-08 14:05:40 +02:00
|
|
|
|
|
|
|
TextBoxPassword.Focus();
|
|
|
|
TextBoxPassword.SelectAll();
|
2013-06-24 13:41:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private bool SessionAuthorized(Session s)
|
|
|
|
{
|
|
|
|
UserDetails ud = s.CurrentUserDetails;
|
|
|
|
foreach (Role r in s.Roles)
|
|
|
|
{
|
|
|
|
if (authorizedRoles.Contains(r))
|
|
|
|
{
|
|
|
|
|
|
|
|
log.DebugFormat("Subject '{0}' is authorized to complete the action", ud.UserDisplayName ?? ud.UserName ?? ud.UserSid);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.DebugFormat("Subject '{0}' is not authorized to complete the action", ud.UserDisplayName ?? ud.UserName ?? ud.UserSid);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void buttonCancel_Click(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
DialogResult = DialogResult.Cancel;
|
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UpdateButtons()
|
|
|
|
{
|
|
|
|
buttonAuthorize.Enabled = TextBoxUsername.Text.Trim() != "" && TextBoxPassword.Text != "";
|
|
|
|
}
|
|
|
|
|
|
|
|
private void TextBoxUsername_TextChanged(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
UpdateButtons();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void TextBoxPassword_TextChanged(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
UpdateButtons();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|