Click here to Skip to main content
15,896,201 members
Articles / Programming Languages / C#

NT Security Classes for .NET

Rate me:
Please Sign up or sign in to vote.
4.78/5 (33 votes)
19 Feb 2004CPOL2 min read 380.3K   4K   75  
A collection of .NET classes written in Managed C++ that faciliate the manipulation of NT security rights
// mmsseclib.h

#pragma once

using namespace System;
using namespace System::Collections;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Principal;

namespace mmsseclib
{
	class MString
	{
	private:
		LPTSTR sbuf;
		void Free()
		{
			if (sbuf != NULL)
				Marshal::FreeHGlobal((IntPtr)sbuf);
		}
	public:
		MString()
		{
			sbuf = NULL;
		}
		MString(String* s)
		{
			sbuf = NULL;
			*this = s;
		}
		~MString()
		{
			Free();
		}
		operator LPCTSTR() const
		{
			return sbuf;
		}
		MString& operator = (String* s)
		{
			Free();
			if (sizeof(TCHAR) == sizeof(char))
				sbuf = (LPTSTR)Marshal::StringToHGlobalAnsi(s).ToPointer();
			else
				sbuf = (LPTSTR)Marshal::StringToHGlobalUni(s).ToPointer();
			return *this;
		}
	};

	public __value enum SecuredObjectType
	{
		UnknownObjectType = 0,
		FileObject,
		Service,
		Printer,
		RegistryKey,
		LMShare,
		KernelObject,
		WindowObject,
		DSObject,
		DSObjectAll,
		ProviderDefinedObject,
		WMIGuidObject,
		RegistryWOW64_32Key
	};

	public __gc class WindowsUser : public ICloneable
	{
	public private:
		ATL::CSid __nogc * m_psid;
		WindowsUser(const CSid& sid)
		{
			m_psid = new ATL::CSid(sid);
		}

		WindowsUser(const SID_IDENTIFIER_AUTHORITY &sidIdentifierAuthority, long subAuthority1)
		{
			m_psid = new ATL::CSid(sidIdentifierAuthority, 1, subAuthority1);
		}

		WindowsUser(const SID_IDENTIFIER_AUTHORITY &sidIdentifierAuthority, long subAuthority1, long subAuthority2)
		{
			m_psid = new ATL::CSid(sidIdentifierAuthority, 2, subAuthority1, subAuthority2);
		}

		~WindowsUser()
		{
			delete m_psid;
			//m_psid->~CSid();
		}

	public:
		WindowsUser() : m_psid(0) {}

		WindowsUser(String* accountName)
		{
			MString s(accountName);
			m_psid = new ATL::CSid(s);
		}

		WindowsUser(String* accountName, String* system)
		{
			MString s(accountName), s2(system);
			m_psid = new ATL::CSid(s, s2);
		}

		virtual Object * Clone()
		{
			WindowsUser* wu = new WindowsUser();
			wu->m_psid = m_psid;
			return wu;
		}

		__property String* get_AccountName()
		{
			if (!m_psid)
				throw new NotSupportedException(S"Object does not represent a valid user");
			return m_psid->AccountName();
		}

		__property String* get_Domain()
		{
			if (!m_psid)
				throw new NotSupportedException(S"Object does not represent a valid user");
			return m_psid->Domain();
		}

		__property String* get_SidString()
		{
			LPTSTR szSid = NULL;
			if (::ConvertSidToStringSid((PSID)m_psid->GetPSID(), &szSid))
			{
				String* s = new String(szSid);
				::LocalFree(szSid);
				return s;
			}
			return NULL;
		}

		String* ToString()
		{
			if (!m_psid)
				return S"";
			if (AccountName->StartsWith(Domain))
				return AccountName;
			return String::Concat(m_psid->Domain(), S"\\", m_psid->AccountName());
		}

	private:

	public:
		__gc class WellKnownIds
		{
		public:
			static WindowsUser* Null = new WindowsUser(ATL::Sids::SecurityNullSidAuthority, SECURITY_NULL_RID);
			static WindowsUser* World = new WindowsUser(ATL::Sids::SecurityWorldSidAuthority, SECURITY_WORLD_RID);
			static WindowsUser* Local = new WindowsUser(ATL::Sids::SecurityLocalSidAuthority, SECURITY_LOCAL_RID);
			static WindowsUser* CreatorOwner = new WindowsUser(ATL::Sids::SecurityCreatorSidAuthority, SECURITY_CREATOR_OWNER_RID);
			static WindowsUser* CreatorGroup = new WindowsUser(ATL::Sids::SecurityCreatorSidAuthority, SECURITY_CREATOR_GROUP_RID);
			static WindowsUser* CreatorOwnerServer = new WindowsUser(ATL::Sids::SecurityCreatorSidAuthority, SECURITY_CREATOR_OWNER_SERVER_RID);
			static WindowsUser* CreatorGroupServer = new WindowsUser(ATL::Sids::SecurityCreatorSidAuthority, SECURITY_CREATOR_GROUP_SERVER_RID);
			static WindowsUser* Dialup = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_DIALUP_RID);
			static WindowsUser* Network = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_NETWORK_RID);
			static WindowsUser* Batch = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BATCH_RID);
			static WindowsUser* Interactive = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_INTERACTIVE_RID);
			static WindowsUser* Service = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_SERVICE_RID);
			static WindowsUser* AnonymousLogon = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_ANONYMOUS_LOGON_RID);
			static WindowsUser* Proxy = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_PROXY_RID);
			static WindowsUser* ServerLogon = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_SERVER_LOGON_RID);
			static WindowsUser* Self = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_PRINCIPAL_SELF_RID);
			static WindowsUser* AuthenticatedUser = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_AUTHENTICATED_USER_RID);
			static WindowsUser* RestrictedCode = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_RESTRICTED_CODE_RID);
			static WindowsUser* TerminalServer = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_TERMINAL_SERVER_RID);
			static WindowsUser* System = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_LOCAL_SYSTEM_RID);
			static WindowsUser* Admins = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS);
			static WindowsUser* Users = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS);
			static WindowsUser* Guests = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS);
			static WindowsUser* PowerUsers = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS);
			static WindowsUser* AccountOps = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS);
			static WindowsUser* SystemOps = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS);
			static WindowsUser* PrintOps = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS);
			static WindowsUser* BackupOps = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS);
			static WindowsUser* Replicator = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR);
			static WindowsUser* RasServers = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_RAS_SERVERS);
			static WindowsUser* PreW2KAccess = new WindowsUser(ATL::Sids::SecurityNTAuthority, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS);
		};
	};

	[System::FlagsAttribute]
	public __value enum AccessRights : System::UInt32
	{
		FileAllAccess = FILE_ALL_ACCESS,
		FileGenericRead = FILE_GENERIC_READ,
		FileGenericWrite = FILE_GENERIC_WRITE,
		FileGenericExecute = FILE_GENERIC_EXECUTE,
		FileGenericReadExecute = (FILE_GENERIC_READ | FILE_GENERIC_EXECUTE),
		FileGenericModify = (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE),
		/*FileListDirectory = FILE_LIST_DIRECTORY,
		FileAddFile = FILE_ADD_FILE,
		FileAddSubdirectory = FILE_ADD_SUBDIRECTORY,*/

		KeyAllAccess = KEY_ALL_ACCESS,
		KeyRead = KEY_READ,
		KeyWrite = KEY_WRITE,
		KeyExecute = KEY_EXECUTE,
		/*
		DsReadProp = ADS_RIGHT_DS_READ_PROP,
		DsWriteProp = ADS_RIGHT_DS_WRITE_PROP,
		DsCreateChild = ADS_RIGHT_DS_CREATE_CHILD,
		DsDeleteChild = ADS_RIGHT_DS_DELETE_CHILD,
		DsList = ADS_RIGHT_DS_LIST,
		DsSelf = ADS_RIGHT_DS_SELF,
		DsListObject = ADS_RIGHT_DS_LIST_OBJECT,
		DsDeleteTree = ADS_RIGHT_DS_DELETE_TREE,
		DsControlAccess = ADS_RIGHT_DS_CONTROL_ACCESS,
		*/
		GenericRead = GENERIC_READ,
		GenericWrite = GENERIC_WRITE,
		GenericExecute = GENERIC_EXECUTE,
		GenericAll = GENERIC_ALL,

		Delete = DELETE,
		ReadControl = READ_CONTROL,
		WriteDac = WRITE_DAC,
		WriteOwner = WRITE_OWNER,
		Synchronize = SYNCHRONIZE,
	};

	public __value enum AceType : System::Byte
	{
		AccessAllowed = ACCESS_ALLOWED_ACE_TYPE,
		AccessDenied = ACCESS_DENIED_ACE_TYPE,
		SystemAudit = SYSTEM_AUDIT_ACE_TYPE,
		SystemAlarm = SYSTEM_ALARM_ACE_TYPE,
//		AccessAllowedCompound = 0x4,
		AccessAllowedObject = ACCESS_ALLOWED_OBJECT_ACE_TYPE,
		AccessDeniedObject = ACCESS_DENIED_OBJECT_ACE_TYPE,
		SystemAuditObject = SYSTEM_AUDIT_OBJECT_ACE_TYPE,
		SystemAlarmObject = SYSTEM_ALARM_OBJECT_ACE_TYPE,
//		AccessAllowedCallback = 0x9,
//		AccessDeniedCallback = 0xA,
//		AccessAllowedCallbackObject = 0xB,
//		AccessDeniedCallbackObject = 0xC,
//		SystemAuditCallback = 0xD,
//		SystemAlarmCallback = 0xE,
//		SystemAuditCallbackObject = 0xF,
//		SystemAlarmCallbackObject = 0x10,
	};

	[System::FlagsAttribute]
	public __value enum AceInheritanceFlags : System::Byte
	{
		ObjectInherit = OBJECT_INHERIT_ACE,
		ContainerInherit = CONTAINER_INHERIT_ACE,
		NoPropagateInherit = NO_PROPAGATE_INHERIT_ACE,
		InheritOnly = INHERIT_ONLY_ACE,
		Inherited = INHERITED_ACE,
		SuccessfulAccess = SUCCESSFUL_ACCESS_ACE_FLAG,
		FailedAccess = FAILED_ACCESS_ACE_FLAG,
	};

	public __gc class Permission
	{
	public private:
		CSid __nogc * pSid;
		ACCESS_MASK mask;
		BYTE acetype;
		BYTE flags;
		GUID __nogc * pObjectType;
		GUID __nogc * pInheritedObjectType;

		Permission(const CAcl& acl, int nIndex)
		{
			ACCESS_MASK lmask;
			BYTE lacetype, lflags;
			pSid = new CSid();
			((CAcl*)(&acl))->GetAclEntry(nIndex, pSid, &lmask, &lacetype, &lflags, pObjectType, pInheritedObjectType);
			mask = lmask;
			acetype = lacetype;
			flags = lflags;
		}

		virtual ~Permission()
		{
			delete pSid;
		}

	public:
		Permission(WindowsUser* trustee, AccessRights rights, AceInheritanceFlags inheritance, AceType type)
		{
			pSid = new CSid(*trustee->m_psid);
			mask = (DWORD)rights;
			acetype = (BYTE)type;
			flags = (BYTE)inheritance;
			pObjectType = NULL;
			pInheritedObjectType = NULL;
		}

		bool Equals(Object* value)
		{
			if (value->GetType() == __typeof(Permission))
			{
				Permission* p = static_cast<Permission*>(value);
				if (*pSid != *p->pSid) return false;
				if (mask != p->mask) return false;
				if (acetype != p->acetype) return false;
				if (flags != p->flags) return false;
				return true;
			}
			return false;
		}

		__property WindowsUser* get_Trustee()
		{
			return new WindowsUser(*pSid);
		}

		__property AccessRights get_Rights()
		{
			return (AccessRights)mask;
		}

		__property AceType get_Type()
		{
			return (AceType)acetype;
		}

		__property AceInheritanceFlags get_Inheritance()
		{
			return (AceInheritanceFlags)flags;
		}

		String* ToString()
		{
			return String::Concat(String::Format(S"{0}\\{1}:({2})", new String(pSid->Domain()), new String(pSid->AccountName()), __box(Inheritance)), __box(this->Rights));
		}
	};

	__delegate void AclChangeHandler(ATL::CAcl __nogc * pAcl, bool bDacl);

	[System::Reflection::DefaultMemberAttribute("Perm")]
	public __gc class PermissionList : public ICloneable, public IList
	{
	private:
	public private:
		AclChangeHandler* OnAclChange;
		ATL::CAcl __nogc * m_pAcl;
		bool isDacl, batch;

		PermissionList(ATL::CDacl __nogc * pDacl) : batch(false), m_pAcl(NULL)
		{
			Assign(pDacl);
		}

		PermissionList(ATL::CSacl __nogc * pSacl) : batch(false), m_pAcl(NULL)
		{
			Assign(pSacl);
		}
		
		void Assign(ATL::CDacl __nogc * pDacl)
		{
			isDacl = true;
			m_pAcl = pDacl;
		}

		void Assign(ATL::CSacl __nogc * pSacl)
		{
			isDacl = false;
			m_pAcl = pSacl;
		}

		virtual ~PermissionList()
		{
			if (m_pAcl)
			{
				if (isDacl)
					delete static_cast<CDacl*>(m_pAcl);
				else
					delete static_cast<CSacl*>(m_pAcl);
			}
		}

		void Commit()
		{
			if (!batch && OnAclChange != NULL)
				OnAclChange(m_pAcl, isDacl);
		}

		__gc class Enumerator : public IEnumerator
		{
		private:
			ATL::CAcl __nogc * m_pAcl;
			int cur;
		public private:
			Enumerator(ATL::CAcl* pAcl)
			{
				cur = -1;
				m_pAcl = pAcl;
			}
		public:
			__property Object* get_Current()
			{
				if (cur == -1)
					return NULL;
				return new Permission(*m_pAcl, cur);
			}

			bool MoveNext()
			{
				return (++cur < (int)m_pAcl->GetAceCount());
			}

			void Reset()
			{
				cur = -1;
			}
		};
	public:
		void BeginUpdate()
		{
			batch = true;
		}

		void EndUpdate()
		{
			batch = false;
			Commit();
		}

		virtual Object * Clone()
		{
			if (isDacl)
				return new PermissionList(static_cast<ATL::CDacl*>(m_pAcl));
			else
				return new PermissionList(static_cast<ATL::CSacl*>(m_pAcl));
		}

		virtual IEnumerator* GetEnumerator()
		{
			return new Enumerator(m_pAcl);
		}

		virtual void CopyTo(Array* array, int index)
		{
			if (array == NULL)
				throw new ArgumentNullException(S"array");
			if ((array->Length-index) < this->Count)
				throw new ArgumentException(S"Not enough space in destination array to perform Copy");
			if (array->Rank != 1)
				throw new ArgumentException(S"Cannot Copy into multidimensional array.");
			if (index < 0)
				throw new ArgumentOutOfRangeException(S"index");

			for (int i = 0; i < this->Count; i++)
				array->set_Item(i+index, new Permission(*m_pAcl, i));
		}

		__property virtual int get_Count()
		{
			return m_pAcl->GetAceCount();
		}

		__property virtual bool get_IsSynchronized()
		{
			return false;
		}

		__property virtual Object* get_SyncRoot()
		{
			throw new NotImplementedException();
			return NULL;
		}

		virtual int Add(Permission* value)
		{
			// See if this user has an entry
			for (int i = 0; i < this->Count; i++)
			{
				Permission* p = new Permission(*m_pAcl, i);
				if (value->acetype == p->acetype)
				{
					if (*value->pSid == *p->pSid)
					{
						if (value->flags == p->flags)
						{
							if ((value->mask & p->mask) == value->mask)
								return i;

							// Merge masks and apply
							value->mask |= p->mask;
							m_pAcl->RemoveAce(i);
							break;
						}
						else
						{
							if (value->mask == p->mask)
							{
								// Merge flags and apply
								value->flags |= p->flags;
								m_pAcl->RemoveAce(i);
								break;
							}
						}
					}
				}
			}

			bool ret = false;
			switch (value->Type)
			{
			case AceType::AccessAllowed:
				if (!isDacl) throw new ArgumentException(S"An access allowed permission can only be added to Permissions");
				ret = ((ATL::CDacl*)m_pAcl)->AddAllowedAce(*value->pSid, value->mask, value->flags);
				break;
			case AceType::AccessDenied:
				if (!isDacl) throw new ArgumentException(S"An access denied permission can only be added to Permissions");
				ret = ((ATL::CDacl*)m_pAcl)->AddDeniedAce(*value->pSid, value->mask, value->flags);
				break;
			case AceType::AccessAllowedObject:
				if (!isDacl) throw new ArgumentException(S"An access allowed permission can only be added to Permissions");
				ret = ((ATL::CDacl*)m_pAcl)->AddAllowedAce(*value->pSid, value->mask, value->flags, value->pObjectType, value->pInheritedObjectType);
				break;
			case AceType::AccessDeniedObject:
				if (!isDacl) throw new ArgumentException(S"An access denied permission can only be added to Permissions");
				ret = ((ATL::CDacl*)m_pAcl)->AddDeniedAce(*value->pSid, value->mask, value->flags, value->pObjectType, value->pInheritedObjectType);
				break;
			case AceType::SystemAudit:
				if (isDacl) throw new ArgumentException(S"A system audit permission can only be added to Permissions");
				ret = ((ATL::CSacl*)m_pAcl)->AddAuditAce(*value->pSid, value->mask, true, true, value->flags);
				break;
			case AceType::SystemAuditObject:
				if (isDacl) throw new ArgumentException(S"A system audit permission can only be added to Permissions");
				ret = ((ATL::CSacl*)m_pAcl)->AddAuditAce(*value->pSid, value->mask, true, true, value->flags, value->pObjectType, value->pInheritedObjectType);
				break;
			}
			Commit();
			if (ret)
				return get_Count();
			throw new Exception(S"Unable to add permission");
		}

		virtual void Clear()
		{
			m_pAcl->SetEmpty();
			Commit();
		}

		virtual bool Contains(Permission* value)
		{
			return (-1 < IndexOf(value));
		}

		__property virtual bool get_IsFixedSize()
		{
			return false;
		}

		__property virtual bool get_IsReadOnly()
		{
			return false;
		}

		__property Permission* get_Perm(int index)
		{
			return new Permission(*m_pAcl, index);
		}

		__property void set_Perm(int index, Permission* value)
		{
			Remove(value);
			Add(value);
		}

		virtual int IndexOf(Permission* value)
		{
			for (int i = 0; i < this->Count; i++)
				if (value->Equals(new Permission(*m_pAcl, i))) return i;
			return -1;
		}

		virtual void Remove(Permission* value)
		{
			int i = IndexOf(value);
			if (i != -1)
			{
				m_pAcl->RemoveAce(i);
				Commit();
			}
			else
				throw new ArgumentException(S"Specified permission not found");
		}

	private:
		virtual int IList::Add(Object* value)
		{
			if (value->GetType() == __typeof(Permission))
				return Add(static_cast<Permission*>(value));
			return -1;
		}

		virtual bool IList::Contains(Object* value)
		{
			if (value->GetType() == __typeof(Permission))
				return Contains(static_cast<Permission*>(value));
			return false;
		}

		__property __sealed virtual Object* IList::get_Item(int index)
		{
			return new Permission(*m_pAcl, index);
		}

		__property __sealed virtual void IList::set_Item(int index, Object* value)
		{
			throw new NotImplementedException();
		}

		virtual int IList::IndexOf(Object* value)
		{
			if (value->GetType() == __typeof(Permission))
				return IndexOf(static_cast<Permission*>(value));
			return -1;
		}

		virtual void IList::Insert(int index, Object* value)
		{
			throw new NotImplementedException();
		}

		virtual void IList::RemoveAt(int index)
		{
			throw new NotImplementedException();
		}

		virtual void IList::Remove(Object* value)
		{
			if (value->GetType() == __typeof(Permission))
				Remove(static_cast<Permission*>(value));
		}
	};

	public __gc class SecuredObject : public ICloneable
	{
	public private:
		String* objName;
		IntPtr objHandle;
		SecuredObjectType objType;
		PermissionList* perms;
		PermissionList* audit;

	public:
		SecuredObject(String* ObjectName, SecuredObjectType ObjectType)
		{
			objName = ObjectName;
			objType = ObjectType;
		}

		SecuredObject(IntPtr hObject, SecuredObjectType ObjectType)
		{
			objHandle = hObject;
			objType = ObjectType;
		}

		virtual Object * Clone()
		{
			SecuredObject* so;
			if (objHandle == IntPtr::Zero)
				so = new SecuredObject(objName, objType);
			else
				so = new SecuredObject(objHandle, objType);
			return so;
		}

		__property WindowsUser* get_Owner()
		{
			CSid* pSid = new CSid();
			bool ret = true;
			SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
			if (objHandle == IntPtr::Zero)
				ret = ATL::AtlGetOwnerSid((LPCTSTR)MString(objName), seot, pSid);
			else
				ret = ATL::AtlGetOwnerSid(objHandle.ToPointer(), seot, pSid);
			if (!ret)
				throw new Exception(S"Unable to get the owner for this object");
			return new WindowsUser(*pSid);
		}

		__property void set_Owner(WindowsUser* value)
		{
			CSid* pSid = new CSid(*value->m_psid);
			bool ret = true;
			SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
			if (objHandle == IntPtr::Zero)
				ret = ATL::AtlSetOwnerSid((LPCTSTR)MString(objName), seot, *pSid);
			else
				ret = ATL::AtlSetOwnerSid(objHandle.ToPointer(), seot, *pSid);
			if (!ret)
				throw new Exception(S"Unable to set the owner for this object");
		}

		__property WindowsUser* get_Group()
		{
			CSid* pSid = new CSid();
			bool ret = true;
			SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
			if (objHandle == IntPtr::Zero)
				ret = ATL::AtlGetGroupSid((LPCTSTR)MString(objName), seot, pSid);
			else
				ret = ATL::AtlGetGroupSid(objHandle.ToPointer(), seot, pSid);
			if (!ret)
				throw new Exception(S"Unable to get the group for this object");
			return new WindowsUser(*pSid);
		}

		__property void set_Group(WindowsUser* value)
		{
			CSid* pSid = new CSid(*value->m_psid);
			bool ret = true;
			SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
			if (objHandle == IntPtr::Zero)
				ret = ATL::AtlSetGroupSid((LPCTSTR)MString(objName), seot, *pSid);
			else
				ret = ATL::AtlSetGroupSid(objHandle.ToPointer(), seot, *pSid);
			if (!ret)
				throw new Exception(S"Unable to set the group for this object");
		}

		__property PermissionList* get_Permissions()
		{
			if (perms == NULL)
			{
				ATL::CDacl __nogc * pAcl = new ATL::CDacl();
				bool ret = true;
				SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
				if (objHandle == IntPtr::Zero)
					ret = ATL::AtlGetDacl((LPCTSTR)MString(objName), seot, pAcl);
				else
					ret = ATL::AtlGetDacl(objHandle.ToPointer(), seot, pAcl);
				if (!ret)
					throw new Exception(S"Unable to get the permissions for this object");
				perms = new PermissionList(pAcl);
				perms->OnAclChange = new AclChangeHandler(this,&SecuredObject::AclChanged);
			}
			return perms;
		}

		__property PermissionList* get_Auditing()
		{
			if (audit == NULL)
			{
				ATL::CSacl __nogc * pAcl = new ATL::CSacl();
				bool ret = true;
				SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
				if (objHandle == IntPtr::Zero)
					ret = ATL::AtlGetSacl((LPCTSTR)MString(objName), seot, pAcl);
				else
					ret = ATL::AtlGetSacl(objHandle.ToPointer(), seot, pAcl);
				if (!ret)
					throw new Exception(S"Unable to get the auditing for this object");
				audit = new PermissionList(pAcl);
				audit->OnAclChange = new AclChangeHandler(this,&SecuredObject::AclChanged);
			}
			return audit;
		}

	private:
		void AclChanged(ATL::CAcl __nogc * pAcl, bool bDacl)
		{
			bool ret = false;
			SE_OBJECT_TYPE seot = (SE_OBJECT_TYPE)objType;
			if (bDacl)
			{
				if (objHandle == IntPtr::Zero)
					ret = ATL::AtlSetDacl((LPCTSTR)MString(objName), seot, *static_cast<ATL::CDacl*>(pAcl));
				else
					ret = ATL::AtlSetDacl(objHandle.ToPointer(), seot, *static_cast<ATL::CDacl*>(pAcl));
			}
			else
			{
				if (objHandle == IntPtr::Zero)
					ret = ATL::AtlSetSacl((LPCTSTR)MString(objName), seot, *static_cast<ATL::CSacl*>(pAcl));
				else
					ret = ATL::AtlSetSacl(objHandle.ToPointer(), seot, *static_cast<ATL::CSacl*>(pAcl));
			}
		}
	};
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
I have been a Windows software developer since 1991. Most of what I create fills the need for some aspect of bigger projects that I consult on.

Comments and Discussions