using System;
using System.Security.AccessControl;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace NetAccessControl
{
public partial class DACLForm : Form
{
protected RegistrySecurity ppSD;
string ObjectName;
/// <summary>
/// Creates the DACL Form.
/// </summary>
/// <param name="ppSDIn">The Security descriptor that DACLForm will display.</param>
/// <param name="ObjectNameIn">The display name of the registry key to be shown to the user.</param>
public DACLForm(RegistrySecurity ppSDIn, string ObjectNameIn)
{
InitializeComponent();
this.ppSD = ppSDIn;
this.ObjectName = ObjectNameIn;
}
protected void DACLForm_Load(object sender, EventArgs e)
{
/* Fill up the list view with information from the security descriptor */
try
{
this.regKeyLbl.Text = this.ObjectName;
RefreshDataGrid();
CheckAutoInheritBox();
}
catch (System.Exception ex)
{
this.errorLbl.Visible = true;
this.errorLbl.Text = ex.Message;
this.viewInheritButton.Enabled = false;
this.daclLView.Enabled = false;
this.applyButton.Enabled = false;
}
}
protected virtual void CheckAutoInheritBox()
{
this.autoinheritBox.Checked = !ppSD.AreAccessRulesProtected;
this.viewInheritButton.Enabled = this.autoinheritBox.Checked;
}
protected void RefreshDataGrid()
{
int i = 0;
/* clear the old view */
this.daclLView.Rows.Clear();
foreach (AuthorizationRule Entry in GetAuthzRules(false))
{
this.daclLView.Rows.Add();
/* Username */
this.daclLView["userLViewCol", i].Value = Entry.IdentityReference.ToString();
/* Allow/deny */
this.daclLView["typeLViewCol", i].Value = GetAccessType(Entry);
/* Access mask */
uint accessMask = GetAccessRightsFromEntry(Entry);
this.daclLView["permsLViewCol", i].Value = Convert.ToString(accessMask, 16);
/* inheritance */
this.daclLView["inheritLViewCol", i].Tag = Entry;
i++;
}
}
protected virtual AuthorizationRuleCollection GetAuthzRules(bool inheritedOrExplicit)
{
/* true: inherited, false: explicit */
return ppSD.GetAccessRules(!inheritedOrExplicit, inheritedOrExplicit,
typeof(System.Security.Principal.NTAccount));
}
protected virtual uint GetAccessRightsFromEntry(AuthorizationRule Entry)
{
/* This is DACL specific, so virtualize it. */
return (uint)((RegistryAccessRule)(Entry)).RegistryRights;
}
protected virtual string GetAccessType(AuthorizationRule Entry)
{
/* DACL specific again. */
return ((RegistryAccessRule)(Entry)).AccessControlType.ToString();
}
private void cancelButton_Click(object sender, EventArgs e)
{
this.Close();
}
protected virtual void HandleUpdatedData(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 3)
{
/** The user wanted to see the ACE Flags. However, only Form Inheritace <> is
* capable of seeing the ACE Flags, so we must create the Inheritance form passing to it
* the selected access control entry.
**/
RegistryAccessRule inheritFlags = (RegistryAccessRule)
(this.daclLView[e.ColumnIndex, e.RowIndex].Tag);
Inheritance<RegistryAccessRule> childFrm = new Inheritance<RegistryAccessRule>(
inheritFlags);
if (childFrm.ShowDialog(this) == DialogResult.OK)
{
/* Okay, the ACE flag was updated. Reflect the update in this ACE. */
RegistryAccessRule Entry = new RegistryAccessRule((string)(this.daclLView["userLViewCol", e.RowIndex].Value),
(RegistryRights)Convert.ToUInt32((string)
(this.daclLView["permsLViewCol", e.RowIndex].Value), 16),
childFrm.Entryinhers, childFrm.Entryprops, GetAccessFlags(e.RowIndex));
this.daclLView[e.ColumnIndex, e.RowIndex].Tag = Entry;
this.applyButton.Enabled = true;
}
}
else
{
this.applyButton.Enabled = true;
}
}
private AccessControlType GetAccessFlags(int i)
{
/** Since this int.ToAccessControlType converter is used by more than one
* function, I've extracted the method to here.
**/
AccessControlType alloworDeny = AccessControlType.Allow;
switch ((string)(this.daclLView["typeLViewCol", i].Value))
{
default:
case "Allow":
{
alloworDeny = AccessControlType.Allow;
break;
}
case "Deny":
{
alloworDeny = AccessControlType.Deny;
break;
}
}
return alloworDeny;
}
private void remapGenericSelect_CheckedChanged(object sender, EventArgs e)
{
if (this.remapGenericSelect.CheckState == CheckState.Checked)
{
try
{
for (int i = 0; i < this.daclLView.Rows.Count; i++)
{
/* Get the cached access mask */
uint accessMask = Convert.ToUInt32((string)(this.daclLView["permsLViewCol", i].Value), 16);
AccessToken.AccessCheckWrap.GENERIC_MAPPING regGenericMapping = AccessToken.AccessCheckWrap.RegGeneric();
AccessToken.AccessCheckWrap.MapGenericMask(ref accessMask, ref regGenericMapping);
this.daclLView["permsLViewCol", i].Value = Convert.ToString(accessMask, 16);
}
}
catch (System.Exception ex)
{
this.errorLbl.Text = "Error Occurred: " + ex.Message;
this.applyButton.Enabled = false;
}
}
else
{
/* we have no choice but to refill the entire Datagridview with the original data. */
this.RefreshDataGrid();
}
}
protected virtual void applyButton_Click(object sender, EventArgs e)
{
/* Get the contents of the DatagridView */
for (int i = 0; i < this.daclLView.Rows.Count; i++)
{
try
{
string identity = (string)(this.daclLView["userLViewCol", i].Value);
/* Access mask */
RegistryRights accessMask = (RegistryRights)(Convert.ToUInt32
((string)(this.daclLView["permsLViewCol", i].Value), 16));
/* Inheritance flags */
AuthorizationRule inheritEntries =
(AuthorizationRule)(this.daclLView["inheritLViewCol", i].Tag);
/* Now build up an AccessRule from the data. */
RegistryAccessRule newEntry = new RegistryAccessRule(identity, accessMask,
inheritEntries.InheritanceFlags, inheritEntries.PropagationFlags,
this.GetAccessFlags(i));
//AuthorizationRule newEntry2 = new RegistryAuditRule(identity, accessMask,
// inheritEntries.InheritanceFlags, inheritEntries.PropagationFlags,
// (RegistryAuditRule)(this.daclLView["typeLViewCol", i].Value));
/* And apply it. */
this.ppSD.SetAccessRule(newEntry);
}
catch (System.NullReferenceException)
{
/* skip over all empty entries */
}
}
/* Don't forget the auto-inheritance. */
this.ppSD.SetAccessRuleProtection(!this.autoinheritBox.Checked, (bool)(this.autoinheritBox.Tag));
this.Close();
}
protected virtual void viewInheritButton_Click(object sender, EventArgs e)
{
AuthorizationRuleCollection entriesCollection = GetAuthzRules(true);
System.Text.StringBuilder finalString = new System.Text.StringBuilder("", 20 * entriesCollection.Count);
foreach(AuthorizationRule Entry in entriesCollection)
{
uint accessMask = GetAccessRightsFromEntry(Entry);
if(this.remapGenericSelect.CheckState == CheckState.Checked)
{
AccessToken.AccessCheckWrap.GENERIC_MAPPING regGenericMapping = AccessToken.AccessCheckWrap.RegGeneric();
AccessToken.AccessCheckWrap.MapGenericMask(ref accessMask, ref regGenericMapping);
}
finalString.Append(GetAccessType(Entry) + " " + Entry.IdentityReference.ToString() + " to " +
Convert.ToString(accessMask, 16) + ". Propagate: " + Entry.PropagationFlags + ", " +
Entry.InheritanceFlags + "\r\n");
}
MessageBox.Show(finalString.ToString(), "Inherited ACLs", MessageBoxButtons.OK, MessageBoxIcon.None,
MessageBoxDefaultButton.Button1);
}
private void daclLView_CellClick(object sender, DataGridViewCellEventArgs e)
{
this.HandleUpdatedData(sender, e);
}
private void autoinheritBox_CheckedChanged(object sender, EventArgs e)
{
if (this.autoinheritBox.Checked)
{/* Reenable the propagation */
this.viewInheritButton.Enabled = true;
this.autoinheritBox.Tag = true;
}
else
{/* Ask the user how if they want to keep inherited entries (ACLUI style). */
this.viewInheritButton.Enabled = false;
if (this.Visible)
{
switch (MessageBox.Show(this, "Do you want to keep the inherited ACEs? If you choose no, " +
"inherited ACEs will be removed. Cancel will undo the operation.", "Copy Inherited ACEs?",
MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
{
case DialogResult.Yes:
{/* Flag the Tag about the user's choice. applyButton will act on this tag. */
this.autoinheritBox.Tag = false;
break;
}
case DialogResult.No:
{
this.autoinheritBox.Tag = false;
break;
}
default:
case DialogResult.Cancel:
{
this.autoinheritBox.Checked = true;
this.viewInheritButton.Enabled = true;
break;
}
}
}
}
}
}
}