//
// System.Security.AccessControl.RawAcl implementation
//
-// Author:
+// Authors:
// Dick Porter <dick@ximian.com>
+// Atsushi Enomoto <atsushi@ximian.com>
+// Kenneth Bell
//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if NET_2_0
+using System.Collections.Generic;
+using System.Text;
namespace System.Security.AccessControl {
public sealed class RawAcl : GenericAcl
{
+ private byte revision;
+ private List<GenericAce> list;
+
public RawAcl (byte revision, int capacity)
{
+ this.revision = revision;
+ list = new List<GenericAce> (capacity);
+ }
+
+ public RawAcl (byte [] binaryForm, int offset)
+ {
+ if (binaryForm == null)
+ throw new ArgumentNullException("binaryForm");
+
+ if (offset < 0 || offset > binaryForm.Length - 8)
+ throw new ArgumentOutOfRangeException("offset", offset, "Offset out of range");
+
+ revision = binaryForm[offset];
+ if (revision != AclRevision && revision != AclRevisionDS)
+ throw new ArgumentException("Invalid ACL - unknown revision", "binaryForm");
+
+ int binaryLength = ReadUShort(binaryForm, offset + 2);
+ if (offset > binaryForm.Length - binaryLength)
+ throw new ArgumentException("Invalid ACL - truncated", "binaryForm");
+
+ int pos = offset + 8;
+ int numAces = ReadUShort(binaryForm, offset + 4);
+ list = new List<GenericAce>(numAces);
+ for (int i = 0; i < numAces; ++i) {
+ GenericAce newAce = GenericAce.CreateFromBinaryForm(binaryForm, pos);
+ list.Add(newAce);
+ pos += newAce.BinaryLength;
+ }
}
- public RawAcl (byte[] binaryForm, int offset)
+ internal RawAcl(byte revision, List<GenericAce> aces)
{
+ this.revision = revision;
+ this.list = aces;
}
public override int BinaryLength
{
get {
- throw new NotImplementedException ();
+ int len = 8;
+ foreach(var ace in list)
+ {
+ len += ace.BinaryLength;
+ }
+ return len;
}
}
- public override int Count
+ public override int Count {
+ get { return list.Count; }
+ }
+
+ public override GenericAce this [int index]
{
- get {
- throw new NotImplementedException ();
+ get { return list [index]; }
+ set { list [index] = value; }
+ }
+
+ public override byte Revision {
+ get { return revision; }
+ }
+
+ public override void GetBinaryForm (byte[] binaryForm,
+ int offset)
+ {
+ if(binaryForm == null)
+ throw new ArgumentNullException("binaryForm");
+
+ if(offset < 0
+ || offset > binaryForm.Length - BinaryLength)
+ throw new ArgumentException("Offset out of range", "offset");
+
+ binaryForm[offset] = Revision;
+ binaryForm[offset + 1] = 0;
+ WriteUShort((ushort)BinaryLength, binaryForm,
+ offset + 2);
+ WriteUShort((ushort)list.Count, binaryForm,
+ offset + 4);
+ WriteUShort(0, binaryForm, offset + 6);
+
+ int pos = offset + 8;
+ foreach(var ace in list)
+ {
+ ace.GetBinaryForm(binaryForm, pos);
+ pos += ace.BinaryLength;
}
}
- public override GenericAce this[int index]
+ public void InsertAce (int index, GenericAce ace)
{
- get {
- throw new NotImplementedException ();
+ if (ace == null)
+ throw new ArgumentNullException ("ace");
+ list.Insert (index, ace);
+ }
+
+ public void RemoveAce (int index)
+ {
+ list.RemoveAt (index);
+ }
+
+ internal override string GetSddlForm(ControlFlags sdFlags,
+ bool isDacl)
+ {
+ StringBuilder result = new StringBuilder();
+
+ if(isDacl) {
+ if((sdFlags & ControlFlags.DiscretionaryAclProtected) != 0)
+ result.Append("P");
+ if((sdFlags & ControlFlags.DiscretionaryAclAutoInheritRequired) != 0)
+ result.Append("AR");
+ if((sdFlags & ControlFlags.DiscretionaryAclAutoInherited) != 0)
+ result.Append("AI");
+ } else {
+ if((sdFlags & ControlFlags.SystemAclProtected) != 0)
+ result.Append("P");
+ if((sdFlags & ControlFlags.SystemAclAutoInheritRequired) != 0)
+ result.Append("AR");
+ if((sdFlags & ControlFlags.SystemAclAutoInherited) != 0)
+ result.Append("AI");
}
- set {
- throw new NotImplementedException ();
+
+ foreach(var ace in list)
+ {
+ result.Append(ace.GetSddlForm());
}
+
+ return result.ToString();
}
-
- public override byte Revision
+
+ internal static RawAcl ParseSddlForm(string sddlForm,
+ bool isDacl,
+ ref ControlFlags sdFlags,
+ ref int pos)
{
- get {
- throw new NotImplementedException ();
+ ParseFlags(sddlForm, isDacl, ref sdFlags, ref pos);
+
+ byte revision = GenericAcl.AclRevision;
+ List<GenericAce> aces = new List<GenericAce>();
+ while(pos < sddlForm.Length && sddlForm[pos] == '(') {
+ GenericAce ace = GenericAce.CreateFromSddlForm(
+ sddlForm, ref pos);
+ if ((ace as ObjectAce) != null)
+ revision = GenericAcl.AclRevisionDS;
+ aces.Add(ace);
}
+
+
+ return new RawAcl(revision, aces);
}
- public override void GetBinaryForm (byte[] binaryForm,
- int offset)
+ private static void ParseFlags(string sddlForm,
+ bool isDacl,
+ ref ControlFlags sdFlags,
+ ref int pos)
{
- throw new NotImplementedException ();
+ char ch = Char.ToUpperInvariant(sddlForm[pos]);
+ while(ch == 'P' || ch == 'A') {
+ if(ch == 'P') {
+ if (isDacl)
+ sdFlags |= ControlFlags.DiscretionaryAclProtected;
+ else
+ sdFlags |= ControlFlags.SystemAclProtected;
+ pos++;
+ } else if(sddlForm.Length > pos + 1) {
+ ch = Char.ToUpperInvariant(sddlForm[pos + 1]);
+ if(ch == 'R') {
+ if (isDacl)
+ sdFlags |= ControlFlags.DiscretionaryAclAutoInheritRequired;
+ else
+ sdFlags |= ControlFlags.SystemAclAutoInheritRequired;
+ pos += 2;
+ } else if (ch == 'I') {
+ if (isDacl)
+ sdFlags |= ControlFlags.DiscretionaryAclAutoInherited;
+ else
+ sdFlags |= ControlFlags.SystemAclAutoInherited;
+ pos += 2;
+ } else {
+ throw new ArgumentException("Invalid SDDL string.", "sddlForm");
+ }
+ } else {
+ throw new ArgumentException("Invalid SDDL string.", "sddlForm");
+ }
+
+ ch = Char.ToUpperInvariant(sddlForm[pos]);
+ }
+
}
-
- public void InsertAce (int index, GenericAce ace)
+
+ private void WriteUShort (ushort val, byte[] buffer, int offset)
{
- throw new NotImplementedException ();
+ buffer[offset] = (byte)val;
+ buffer[offset + 1] = (byte)(val >> 8);
}
- public void RemoveAce (int index)
+ private ushort ReadUShort (byte[] buffer, int offset)
{
- throw new NotImplementedException ();
+ return (ushort)((((int)buffer[offset + 0]) << 0)
+ | (((int)buffer[offset + 1]) << 8));
}
}
}
-#endif