public static SecurityDescriptorHandle GetUserObjectSecurity(IntPtr handle, SecurityInformation requested)
        {
            uint length;
            var descriptor = IntPtr.Zero;
            if (!NativeMethods.GetUserObjectSecurity(handle, ref requested, descriptor, 0, out length))
            {
                var errorCode = (SystemErrorCode)Marshal.GetLastWin32Error();
                if (errorCode != SystemErrorCode.ErrorInsufficientBuffer)
                {
                    throw ErrorHelper.GetWin32Exception(errorCode);
                }
            }

            descriptor = Marshal.AllocHGlobal(new IntPtr(length));
            try
            {
                if (!NativeMethods.GetUserObjectSecurity(handle, ref requested, descriptor, length, out length))
                {
                    throw ErrorHelper.GetWin32Exception();
                }
            }
            catch
            {
                Marshal.FreeHGlobal(descriptor);
                throw;
            }

            return new SecurityDescriptorHandle(descriptor);
        }
        public static MessageStatus QuerySecurityInfo(
            SecurityInformation securityInformation,
            bool isByteCountGreater,
            out OutputBuffer outputBuffer
            )
        {
            outputBuffer = new OutputBuffer();
            //SecurityInformation contains any of OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, or DACL_SECURITY_INFORMATION
            if ((securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION ||
                securityInformation == SecurityInformation.GROUP_SECURITY_INFORMATION ||
                securityInformation == SecurityInformation.LABEL_SECURITY_INFORMATION ||
                securityInformation == SecurityInformation.DACL_SECURITY_INFORMATION) &&
                ((gOpenGrantedAccess & FileAccess.READ_CONTROL) == 0))
            {
                Helper.CaptureRequirement(2776, @"[In Server Requests a Query of Security Information,Pseudocode for the operation is as follows:]
                    The operation MUST be failed with STATUS_ACCESS_DENIED under either of the following conditions:
                    SecurityInformation contains any of OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION,
                    or DACL_SECURITY_INFORMATION, and Open.GrantedAccess does not contain READ_CONTROL.");
                return MessageStatus.ACCESS_DENIED;
            }
            //SecurityInformation contains SACL_SECURITY_INFORMATION
            if ((securityInformation == SecurityInformation.SACL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.ACCESS_SYSTEM_SECURITY) == 0))
            {
                Helper.CaptureRequirement(2777, @"[In Server Requests a Query of Security Information,Pseudocode for the operation is as follows:]
                    The operation MUST be failed with STATUS_ACCESS_DENIED under either of the following conditions:
                    SecurityInformation contains SACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain ACCESS_SYSTEM_SECURITY.");
                return MessageStatus.ACCESS_DENIED;
            }
            // If ByteCount is greater than OutputBufferSize
            if (isByteCountGreater)
            {
                Helper.CaptureRequirement(2799, @"[In Server Requests a Query of Security Information,Pseudocode for the operation is as follows:]If ByteCount is greater than OutputBufferSize, the operation MUST be failed with STATUS_BUFFER_OVERFLOW.");
                return MessageStatus.BUFFER_OVERFLOW;
            }

            //The object store MUST set OutputBuffer.Revision equal to 1;
            outputBuffer.Revision = 1;
            Helper.CaptureRequirement(2800, "[In Server Requests a Query of Security Information,Pseudocode for the operation is as follows:]The object store MUST set OutputBuffer.Revision equal to 1.");
            Helper.CaptureRequirement(2769, @"[In Server Requests a Query of Security Information]On completion,
                the object store MUST return:[Status,OutputBuffer,ByteCount].");
            Helper.CaptureRequirement(2832, @"[In Server Requests a Query of Security Information]
                Pseudocode for the operation is as follows:The operation returns STATUS_SUCCESS.");
            return MessageStatus.SUCCESS;
        }
Ejemplo n.º 3
0
 public static extern NtStatus NtSetSecurityObject(
     IntPtr Handle,
     SecurityInformation SecurityInformation,
     void* SecurityDescriptor
     );
Ejemplo n.º 4
0
 internal static extern uint GetNamedSecurityInfo([MarshalAs(UnmanagedType.LPWStr)] string pObjectName, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor);
 internal static MessageStatus WorkaroundSetSecurityInfo(SecurityInformation securityInformation, OwnerSid ownerSidEnum, MessageStatus returnedStatus, ITestSite site)
 {
     if (((securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION || securityInformation == SecurityInformation.GROUP_SECURITY_INFORMATION || securityInformation == SecurityInformation.LABEL_SECURITY_INFORMATION)) || (securityInformation == SecurityInformation.DACL_SECURITY_INFORMATION) || (securityInformation == SecurityInformation.SACL_SECURITY_INFORMATION))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(3239, MessageStatus.ACCESS_DENIED, returnedStatus, site);
     }
     else if ((securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION && ownerSidEnum == OwnerSid.InputBufferOwnerSidNotPresent) || (securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION && ownerSidEnum == OwnerSid.InputBufferOwnerSidNotValid) || (securityInformation != SecurityInformation.OWNER_SECURITY_INFORMATION && ownerSidEnum == OwnerSid.OpenFileSecDesOwnerIsNull))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(3239, MessageStatus.INVALID_OWNER, returnedStatus, site);
     }
     return returnedStatus;
 }
Ejemplo n.º 6
0
 internal static extern uint SetSecurityInfo(SafeHandle handle, ObjectType objectType, SecurityInformation securityInfo, IntPtr psidOwner, IntPtr psidGroup, IntPtr pDacl, IntPtr pSacl);
Ejemplo n.º 7
0
 internal static extern uint SetNamedSecurityInfo([MarshalAs(UnmanagedType.LPWStr)] string pObjectName, ObjectType objectType, SecurityInformation securityInfo, IntPtr pSidOwner, IntPtr pSidGroup, IntPtr pDacl, IntPtr pSacl);
Ejemplo n.º 8
0
 internal static extern uint GetSecurityInfo(SafeHandle handle, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor);
 /// <summary>
 /// Convert security descriptor to SDDL string
 /// </summary>
 /// <param name="security_information">The parts of the security descriptor to return</param>
 /// <returns>The SDDL string</returns>
 public string ToSddl(SecurityInformation security_information)
 {
     return NtSecurity.SecurityDescriptorToSddl(ToByteArray(), security_information);
 }
Ejemplo n.º 10
0
        private SecurityInformation Decrypt(Stream clear, Stream cypher, SecretKey key, DateTime? sealedOn)
        {
            int i;
            bool found;
            StringBuilder algos;
            DateTime date = sealedOn == null ? DateTime.UtcNow : sealedOn.Value;

            trace.TraceEvent(TraceEventType.Information, 0, "Decrypting message for {0} recipient", key == null ? "known" : "unknown");
            try
            {
                SecurityInformation result = new SecurityInformation();
                CmsEnvelopedDataParser cypherData;
                try
                {
                    cypherData = new CmsEnvelopedDataParser(cypher);
                    trace.TraceEvent(TraceEventType.Verbose, 0, "Read the cms header");
                }
                catch (Exception e)
                {
                    trace.TraceEvent(TraceEventType.Error, 0, "The messages isn't encrypted");
                    throw new InvalidMessageException("The message isn't a triple wrapped message", e);
                }
                RecipientInformationStore recipientInfos = cypherData.GetRecipientInfos();
                trace.TraceEvent(TraceEventType.Verbose, 0, "Got the recipient info of the encrypted message");

                i = 0;
                found = false;
                algos = new StringBuilder();
                string encryptionAlgOid = cypherData.EncryptionAlgOid;
                while (!found && i < EteeActiveConfig.Unseal.EncryptionAlgorithms.Count)
                {
                    Oid algo = EteeActiveConfig.Unseal.EncryptionAlgorithms[i++];
                    algos.Append(algo.Value + " (" + algo.FriendlyName + ") ");
                    found = algo.Value == encryptionAlgOid;
                }
                if (!found)
                {
                    result.securityViolations.Add(SecurityViolation.NotAllowedEncryptionAlgorithm);
                    trace.TraceEvent(TraceEventType.Warning, 0, "The encryption algorithm {0} isn't allowed, only {1} are", encryptionAlgOid, algos);
                }
                trace.TraceEvent(TraceEventType.Verbose, 0, "The encryption algorithm is verified: {0}", encryptionAlgOid);

                //Key size of the message should not be checked, size is determined by the algorithm

                //Get recipient, should be receiver.
                RecipientInformation recipientInfo;
                ICipherParameters recipientKey;
                if (key == null)
                {
                    if (encCertStore != null)
                    {
                        //Find find a matching receiver
                        ICollection recipients = recipientInfos.GetRecipients(); //recipients in the message
                        IList<KeyValuePair<RecipientInformation, IList>> allMatches = new List<KeyValuePair<RecipientInformation, IList>>();
                        foreach (RecipientInformation recipient in recipients)
                        {
                            trace.TraceEvent(TraceEventType.Verbose, 0, "The message is addressed to {0} ({1})", recipient.RecipientID.SerialNumber, recipient.RecipientID.Issuer);
                            if (recipient is KeyTransRecipientInformation) {
                                IList matches = (IList) encCertStore.GetMatches(recipient.RecipientID);
                                if (matches.Count > 0)
                                {
                                    allMatches.Add(new KeyValuePair<RecipientInformation, IList>(recipient, matches));
                                }
                            }
                        }

                        //Did we find a receiver?
                        if (allMatches.Count == 0)
                        {
                            trace.TraceEvent(TraceEventType.Error, 0, "The recipients doe not contain any of your your encryption certificates");
                            throw new InvalidMessageException("The message isn't a message that is addressed to you.  Or it is an unaddressed message or it is addressed to somebody else");
                        }

                        //check with encryption cert matches where valid at creation time
                        IList<KeyValuePair<RecipientInformation, IList>> validMatches = new List<KeyValuePair<RecipientInformation, IList>>();
                        foreach (KeyValuePair<RecipientInformation, IList> match in allMatches)
                        {
                            IList validCertificate = new List<X509Certificate2>();
                            foreach (X509Certificate2 cert in match.Value)
                            {
                                //Validate the description cert, providing minimal info to force minimal validation.
                                CertificateSecurityInformation certVerRes = CertVerifier.VerifyEnc(DotNetUtilities.FromX509Certificate(cert), null, date, null, false);
                                trace.TraceEvent(TraceEventType.Verbose, 0, "Validated potential decryption certificate ({0}) : Validation Status = {1}, Trust Status = {2}",
                                    cert.Subject, certVerRes.ValidationStatus, certVerRes.TrustStatus);
                                if (certVerRes.SecurityViolations.Count == 0)
                                {
                                    validCertificate.Add(cert);
                                }
                            }

                            if (validCertificate.Count > 0)
                            {
                                validMatches.Add(new KeyValuePair<RecipientInformation, IList>(match.Key, validCertificate));
                            }
                        }

                        //If we have a valid encCert use that one, otherwise use an invalid one (at least we can read it, but should not use it)
                        X509Certificate2 selectedCert;
                        if (validMatches.Count > 0)
                        {
                            selectedCert = (X509Certificate2)validMatches[0].Value[0];
                            recipientInfo = validMatches[0].Key;
                            trace.TraceEvent(TraceEventType.Information, 0, "Found valid decryption certificate ({0}) that matches one the the recipients", selectedCert.Subject);
                        }
                        else
                        {
                            selectedCert = (X509Certificate2)allMatches[0].Value[0];
                            recipientInfo = allMatches[0].Key;
                            trace.TraceEvent(TraceEventType.Warning, 0, "Found *invalid* decryption certificate ({0}) that matches one the the recipients", selectedCert.Subject);
                        }
                        recipientKey = DotNetUtilities.GetKeyPair(selectedCert.PrivateKey).Private;

                        //we validate the selected certificate again to inform the caller
                        result.Subject = CertVerifier.VerifyEnc(DotNetUtilities.FromX509Certificate(selectedCert),  null, date, null, false);
                    }
                    else
                    {
                        trace.TraceEvent(TraceEventType.Error, 0, "The unsealer does not have an decryption certificate and no symmetric key was provided");
                        throw new InvalidOperationException("There should be an receiver (=yourself) and/or a key provided");
                    }
                }
                else
                {
                    trace.TraceEvent(TraceEventType.Verbose, 0, "Found symmetric key: {0}", key.IdString);

                    RecipientID recipientId = new RecipientID();
                    recipientId.KeyIdentifier = key.Id;
                    recipientInfo = recipientInfos.GetFirstRecipient(recipientId);
                    if (recipientInfo == null)
                    {
                        trace.TraceEvent(TraceEventType.Error, 0, "The symmetric key was not found in this cms message");
                        throw new InvalidMessageException("The key isn't for this unaddressed message");
                    }
                    trace.TraceEvent(TraceEventType.Verbose, 0, "Found symmetric key in recipients of the cms message");

                    //Get receivers key
                    recipientKey = key.BCKey;

                    //Validate the unaddressed key
                    if ((((KeyParameter)recipientKey).GetKey().Length * 8) < EteeActiveConfig.Unseal.MinimumEncryptionKeySize.SymmetricRecipientKey)
                    {
                        result.securityViolations.Add(SecurityViolation.NotAllowedEncryptionKeySize);
                        trace.TraceEvent(TraceEventType.Warning, 0, "The symmetric key was only {0} bits while it should be at least {0}",
                            ((KeyParameter)recipientKey).GetKey().Length * 8,  EteeActiveConfig.Unseal.MinimumEncryptionKeySize.SymmetricRecipientKey);
                    }
                }

                //check if key encryption algorithm is allowed
                i = 0;
                found = false;
                algos = new StringBuilder();
                while (!found && i < EteeActiveConfig.Unseal.KeyEncryptionAlgorithms.Count)
                {
                    Oid algo = EteeActiveConfig.Unseal.KeyEncryptionAlgorithms[i++];
                    algos.Append(algo.Value + " (" + algo.FriendlyName + ") ");
                    found = algo.Value == recipientInfo.KeyEncryptionAlgOid;
                }
                if (!found)
                {
                    result.securityViolations.Add(SecurityViolation.NotAllowedKeyEncryptionAlgorithm);
                    trace.TraceEvent(TraceEventType.Warning, 0, "Encryption algorithm is {0} while it should be one of the following {1}",
                        recipientInfo.KeyEncryptionAlgOid, algos);
                }
                trace.TraceEvent(TraceEventType.Verbose, 0, "Finished verifying the encryption algorithm: {0}", recipientInfo.KeyEncryptionAlgOid);

                //Decrypt!
                CmsTypedStream clearStream = recipientInfo.GetContentStream(recipientKey);
                trace.TraceEvent(TraceEventType.Verbose, 0, "Accessed the encrypted content");

                try
                {
                    clearStream.ContentStream.CopyTo(clear);
                    trace.TraceEvent(TraceEventType.Verbose, 0, "Decrypted the content");
                }
                finally
                {
                    clearStream.ContentStream.Close();
                }

                return result;
            }
            catch (CmsException cmse)
            {
                trace.TraceEvent(TraceEventType.Error, 0, "The message isn't a CMS message");
                throw new InvalidMessageException("The message isn't a triple wrapped message", cmse);
            }
        }
 public static extern bool GetUserObjectSecurity(IntPtr handle, ref SecurityInformation siRequested, IntPtr sd, uint length, out uint lengthNeeded);
Ejemplo n.º 12
0
 public static extern NtStatus NtSetSecurityObject(
     SafeHandle Handle,
     SecurityInformation SecurityInformation,
     SafeBuffer SecurityDescriptor
     );
Ejemplo n.º 13
0
 public void SetSecurity(SecurityInformation providedInformation, byte[] binarySecurityDescriptor)
 {
 }
Ejemplo n.º 14
0
		internal static int SetNamedSecurityInfo(string pObjectName, SeObjectType ObjectType, SecurityInformation SecurityInfo, IntPtr psidOwner, IntPtr psidGroup, IntPtr pDacl, IntPtr pSacl) {
			return 0;
		}
		private void GetFileSecurityDescriptor(string path, SecurityInformation requestedInformation, out IntPtr securityDescriptor)
		{
			securityDescriptor = new IntPtr(0); 
			int size = 0; 
			int sizeNeeded = 0; 
			
			// call once to get the size needed
			GetFileSecurity(path, requestedInformation, securityDescriptor, 0, ref sizeNeeded);

			// Allocate the memory required for the security descriptor.
			securityDescriptor = Marshal.AllocHGlobal(sizeNeeded);
			size = sizeNeeded;

			// call again to get the security descriptor
			if (!GetFileSecurity(path, requestedInformation, securityDescriptor, size, ref sizeNeeded))
				// Free the memory we allocated.
				Marshal.FreeHGlobal(securityDescriptor);			
		}
Ejemplo n.º 16
0
		internal static int GetNamedSecurityInfo(string pObjectName, SeObjectType ObjectType, SecurityInformation SecurityInfo, out IntPtr ppsidOwner, out IntPtr ppsidGroup, out IntPtr ppDacl, out IntPtr ppSacl, out IntPtr ppSecurityDescriptor)
		{
			ppsidOwner = IntPtr.Zero;
			ppsidGroup = IntPtr.Zero;
			ppDacl = IntPtr.Zero;
			ppSacl = IntPtr.Zero;
			ppSecurityDescriptor = IntPtr.Zero;
			return 0;
		}
 public static extern NtStatus NtSetSecurityObject(
     SafeHandle Handle,
     SecurityInformation SecurityInformation,
     [In] byte[] SecurityDescriptor
     );
 public void GetSecurity(SecurityInformation RequestedInformation, out IntPtr ppSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] bool fDefault)
 {
     byte[] raw_sd = _handle.GetSecurityDescriptorBytes(RequestedInformation);
     IntPtr ret = LocalAlloc(0, new IntPtr(raw_sd.Length));
     Marshal.Copy(raw_sd, 0, ret, raw_sd.Length);
     ppSecurityDescriptor = ret;
 }
Ejemplo n.º 19
0
 public static extern NtStatus SamQuerySecurityObject(
     [In] IntPtr ObjectHandle,
     [In] SecurityInformation SecurityInformation,
     [Out] out IntPtr SecurityDescriptor // SecurityDescriptor**
     );
Ejemplo n.º 20
0
 static extern bool QueryServiceObjectSecurity(SafeServiceHandle hService,
                                               SecurityInformation dwSecurityInformation,
                                               [Out] byte[] lpSecurityDescriptor,
                                               int cbBufSize,
                                               out int pcbBytesNeeded);
Ejemplo n.º 21
0
 private extern static bool ConvertSecurityDescriptorToStringSecurityDescriptor(byte[] sd, uint rev, SecurityInformation secinfo, out IntPtr str, out int length);
Ejemplo n.º 22
0
 internal static extern bool ConvertSecurityDescriptorToStringSecurityDescriptor(
     SafeBuffer SecurityDescriptor,
     int RequestedStringSDRevision,
     SecurityInformation SecurityInformation,
     out SafeLocalAllocBuffer StringSecurityDescriptor,
     out int StringSecurityDescriptorLen);
 /// <summary>
 /// Set the object's security descriptor
 /// </summary>
 /// <param name="security_desc">The security descriptor to set.</param>
 /// <param name="security_information">What parts of the security descriptor to set</param>
 public void SetSecurityDescriptor(SecurityDescriptor security_desc, SecurityInformation security_information)
 {
     SetSecurityDescriptor(security_desc, security_information, true);
 }
 /// <summary>
 /// Set the security descriptor for a service.
 /// </summary>
 /// <param name="name">The name of the service.</param>
 /// <param name="security_descriptor">The security descriptor to set.</param>
 /// <param name="security_information">The security information to set.</param>
 public static void SetServiceSecurityDescriptor(string name, SecurityDescriptor security_descriptor,
                                                 SecurityInformation security_information)
 {
     SetServiceSecurityDescriptor(name, security_descriptor, security_information, true);
 }
Ejemplo n.º 25
0
        public NTStatus GetSecurityInformation(out SecurityDescriptor result, object handle, SecurityInformation securityInformation)
        {
            result = null;
            QueryInfoRequest request = new QueryInfoRequest();

            request.InfoType            = InfoType.Security;
            request.SecurityInformation = securityInformation;
            request.OutputBufferLength  = 4096;
            request.FileId = (FileID)handle;

            TrySendCommand(request);
            SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);

            if (response != null)
            {
                if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
                {
                    result = ((QueryInfoResponse)response).GetSecurityInformation();
                }
                return(response.Header.Status);
            }

            return(NTStatus.STATUS_INVALID_SMB);
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Get the security descriptor specifying which parts to retrieve
 /// </summary>
 /// <param name="security_information">What parts of the security descriptor to retrieve</param>
 /// <returns>The security descriptor</returns>
 public SecurityDescriptor GetSecurityDescriptor(SecurityInformation security_information)
 {
     return(new SecurityDescriptor(GetSecurityDescriptorBytes(security_information)));
 }
Ejemplo n.º 27
0
 public static extern NtStatus NtSetSecurityObject(
     IntPtr Handle,
     SecurityInformation SecurityInformation,
     void *SecurityDescriptor
     );
Ejemplo n.º 28
0
 /// <summary>
 /// Set the object's security descriptor
 /// </summary>
 /// <param name="security_desc">The security descriptor to set.</param>
 /// <param name="security_information">What parts of the security descriptor to set</param>
 public void SetSecurityDescriptor(SecurityDescriptor security_desc, SecurityInformation security_information)
 {
     SetSecurityDescriptor(security_desc.ToByteArray(), security_information);
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Set the object's security descriptor
 /// </summary>
 /// <param name="security_desc">The security descriptor to set.</param>
 /// <param name="security_information">What parts of the security descriptor to set</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The NT status code.</returns>
 public NtStatus SetSecurityDescriptor(SecurityDescriptor security_desc, SecurityInformation security_information, bool throw_on_error)
 {
     return(SetSecurityDescriptor(security_desc.ToByteArray(), security_information, throw_on_error));
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Set the object's security descriptor
 /// </summary>
 /// <param name="security_desc">The security descriptor to set.</param>
 /// <param name="security_information">What parts of the security descriptor to set</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <return>The NT status result.</return>
 public NtStatus SetSecurityDescriptor(byte[] security_desc, SecurityInformation security_information, bool throw_on_error)
 {
     return(NtSystemCalls.NtSetSecurityObject(Handle, security_information, security_desc).ToNtException(throw_on_error));
 }
 internal static extern NtStatus SamQuerySecurityObject(
     SafeSamHandle ObjectHandle,
     SecurityInformation SecurityInformation,
     out SafeSamMemoryBuffer SecurityDescriptor
     );
 internal static extern NtStatus SamSetSecurityObject(
     SafeSamHandle ObjectHandle,
     SecurityInformation SecurityInformation,
     SafeBuffer SecurityDescriptor
     );
 /// <summary>
 /// Sets the security descriptor of a kernel object.
 /// </summary>
 /// <param name="handle">A handle to a kernel object.</param>
 /// <param name="securityInformation">The information to modify.</param>
 /// <param name="securityDescriptor">The security descriptor.</param>
 public static void SetSecurity(IntPtr handle, SecurityInformation securityInformation, SecurityDescriptor securityDescriptor)
 {
     Win32.NtSetSecurityObject(
         handle,
         securityInformation,
         securityDescriptor
         ).ThrowIf();
 }
Ejemplo n.º 34
0
 public static extern bool RtlValidRelativeSecurityDescriptor(SafeBuffer SecurityDescriptorInput, int SecurityDescriptorLength, SecurityInformation RequiredInformation);
Ejemplo n.º 35
0
            public byte[] GetSecurity(SecurityInformation requestedInformation, bool wantDefault)
            {
                //FileSecurity fsec= new FileSecurity(@"c:\Test1\test.txt",~AccessControlSections.Audit);
                //return fsec.GetSecurityDescriptorBinaryForm();
                WindowsIdentity user = WindowsIdentity.GetCurrent();
                if (user != null)
                {
                    int length = 0;
                    IntPtr token = user.Token;
                    GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenDefaultDacl, IntPtr.Zero, 0, out length);
                    IntPtr TokenInformation = Marshal.AllocHGlobal((int) length);
                    bool Result = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenDefaultDacl, TokenInformation, (uint) length,
                                                      out length);
                    TOKEN_DEFAULT_DACL dacl =
                        (TOKEN_DEFAULT_DACL) Marshal.PtrToStructure(TokenInformation, typeof (TOKEN_DEFAULT_DACL));
                    ACL acl = (ACL) Marshal.PtrToStructure(dacl.DefaultDacl, typeof (ACL));

                    byte[] aceArr = new byte[acl.AclSize];
                    Marshal.Copy(dacl.DefaultDacl, aceArr, 0, acl.AclSize);

                    RawAcl rawAcl = new RawAcl(aceArr, 0);

                    Marshal.FreeHGlobal(TokenInformation);
                    GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenOwner, IntPtr.Zero, 0, out length);
                    TokenInformation = Marshal.AllocHGlobal((int) length);
                    GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenOwner, TokenInformation, (uint)length,
                                                      out length);
                    TOKEN_OWNER tokOwner = (TOKEN_OWNER) Marshal.PtrToStructure(TokenInformation, typeof (TOKEN_OWNER));
                    SecurityIdentifier ownerSID= new SecurityIdentifier(tokOwner.Owner);

                    Marshal.FreeHGlobal(TokenInformation);
                    GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenPrimaryGroup, IntPtr.Zero, 0, out length);
                    TokenInformation = Marshal.AllocHGlobal((int)length);
                    GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenPrimaryGroup, TokenInformation, (uint)length,
                                                      out length);
                    TOKEN_PRIMARY_GROUP tokGroup= (TOKEN_PRIMARY_GROUP)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_PRIMARY_GROUP));
                    SecurityIdentifier groupSID = new SecurityIdentifier(tokGroup.PrimaryGroup);

                    RawSecurityDescriptor rawDesc = new RawSecurityDescriptor(ControlFlags.DiscretionaryAclPresent, ownerSID, groupSID, null, rawAcl);
                    byte[] ret = new byte[rawDesc.BinaryLength];
                    rawDesc.GetBinaryForm(ret, 0);
                    return ret;

                }
                return null;
            }
 public void SetSecurity(SecurityInformation SecurityInformation, IntPtr pSecurityDescriptor)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 37
0
 public static void SetSecurity(IntPtr handle, SecurityInformation securityInformation, SecurityDescriptor securityDescriptor)
 {
     NtStatus status;
     if ((status = Win32.NtSetSecurityObject(
         handle,
         securityInformation,
         securityDescriptor
         )) >= NtStatus.Error)
         Win32.ThrowLastError(status);
 }
 static extern int RegGetKeySecurity(
     IntPtr hKey,
     SecurityInformation si,
     IntPtr psid,
     ref int iSize
     );
Ejemplo n.º 39
0
 public NTStatus SetSecurityInformation(object handle, SecurityInformation securityInformation, SecurityDescriptor securityDescriptor)
 {
     return(NTStatus.STATUS_NOT_SUPPORTED);
 }
Ejemplo n.º 40
0
 /// <summary>
 /// Get the security descriptor specifying which parts to retrieve
 /// </summary>
 /// <param name="security_information">What parts of the security descriptor to retrieve</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The security descriptor</returns>
 public NtResult <SecurityDescriptor> GetSecurityDescriptor(SecurityInformation security_information, bool throw_on_error)
 {
     return(GetSecurityDescriptorBytes(security_information, throw_on_error).Map(sd => new SecurityDescriptor(sd, NtType)));
 }
 /// <summary>
 /// Get security descriptor as a byte array
 /// </summary>
 /// <param name="security_information">What parts of the security descriptor to retrieve</param>
 /// <returns>The security descriptor</returns>
 public byte[] GetSecurityDescriptorBytes(SecurityInformation security_information)
 {
     return(GetSecurityDescriptorBytes(security_information, true).Result);
 }
Ejemplo n.º 42
0
 public NTTransactQuerySecurityDescriptorRequest(byte[] parameters)
 {
     FID                = LittleEndianConverter.ToUInt16(parameters, 0);
     Reserved           = LittleEndianConverter.ToUInt16(parameters, 2);
     SecurityInfoFields = (SecurityInformation)LittleEndianConverter.ToUInt32(parameters, 4);
 }
 /// <summary>
 /// Get the security descriptor specifying which parts to retrieve
 /// </summary>
 /// <param name="security_information">What parts of the security descriptor to retrieve</param>
 /// <returns>The security descriptor</returns>
 public SecurityDescriptor GetSecurityDescriptor(SecurityInformation security_information)
 {
     return(GetSecurityDescriptor(security_information, true).Result);
 }
 /// <summary>
 /// Set the Auditing Security Descriptor.
 /// </summary>
 /// <param name="security_information">The security information to set.</param>
 /// <param name="security_descriptor">The security descriptor to set.</param>
 /// <returns>The NT status code.</returns>
 public static void SetSecurity(SecurityInformation security_information, SecurityDescriptor security_descriptor)
 {
     SetSecurity(security_information, security_descriptor, true);
 }
Ejemplo n.º 45
0
 public void SetSecurity(SecurityInformation SecurityInformation, IntPtr pSecurityDescriptor)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Query the Auditing Security Descriptor.
 /// </summary>
 /// <param name="security_information">The security information to query.</param>
 /// <returns>The security descriptor.</returns>
 public static SecurityDescriptor QuerySecurity(SecurityInformation security_information)
 {
     return(QuerySecurity(security_information, true).Result);
 }
Ejemplo n.º 47
0
 /// <summary>
 /// Convert security descriptor to SDDL string
 /// </summary>
 /// <param name="security_information">The parts of the security descriptor to return</param>
 /// <returns>The SDDL string</returns>
 public string ToSddl(SecurityInformation security_information)
 {
     return(NtSecurity.SecurityDescriptorToSddl(ToByteArray(), security_information));
 }
        public static MessageStatus SetSecurityInfo(
            SecurityInformation securityInformation,
            OwnerSid ownerSidEnum
            )
        {
            //If the object store does not implement security, the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.
            if (!isObjectImplementedFunctionality)
            {
                Helper.CaptureRequirement(3232, @"[In Server Requests Setting of Security Information] If the object store does not implement security,
                    the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.");
                return MessageStatus.INVALID_DEVICE_REQUEST;
            }
            // SecurityInformation contains any of OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION, or LABEL_SECURITY_INFORMATION, and Open.GrantedAccess does not contain WRITE_OWNER.
            if ((securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION || securityInformation == SecurityInformation.GROUP_SECURITY_INFORMATION || securityInformation == SecurityInformation.LABEL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.WRITE_OWNER) == 0))
            {
                Helper.CaptureRequirement(3258, @"[In Server Requests Setting of Security Information]
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:SecurityInformation
                    contains any of LABEL_SECURITY_INFORMATION, and Open.GrantedAccess does not contain WRITE_OWNER.");
                Helper.CaptureRequirement(3256, @"[In Server Requests Setting of Security Information]
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:
                    SecurityInformation contains any of OWNER_SECURITY_INFORMATION,  and Open.GrantedAccess does not contain WRITE_OWNER.");
                Helper.CaptureRequirement(3257, @"[In Server Requests Setting of Security Information]
                     The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:
                     SecurityInformation contains any of GROUP_SECURITY_INFORMATION,, and Open.GrantedAccess does not contain WRITE_OWNER.");
                Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
                return MessageStatus.ACCESS_DENIED;
            }
            // SecurityInformation contains DACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain WRITE_DAC
            if ((securityInformation == SecurityInformation.DACL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.WRITE_DAC) == 0))
            {
                Helper.CaptureRequirement(3243, @"[In Server Requests Setting of Security Information]
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:
                    SecurityInformation contains DACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain WRITE_DAC.");
                Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
                return MessageStatus.ACCESS_DENIED;
            }
            // ? SecurityInformation contains SACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain ACCESS_SYSTEM_SECURITY.
            if ((securityInformation == SecurityInformation.SACL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.ACCESS_SYSTEM_SECURITY) == 0))
            {
                Helper.CaptureRequirement(3244, @"[In Server Requests Setting of Security Information]
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions: SecurityInformation contains SACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain ACCESS_SYSTEM_SECURITY.");
                Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
                return MessageStatus.ACCESS_DENIED;
            }

            // If SecurityInformation contains OWNER_SECURITY_INFORMATION
            if (securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION)
            {
                // If InputBuffer.OwnerSid is not present,
                if (ownerSidEnum == OwnerSid.InputBufferOwnerSidNotPresent)
                {
                    Helper.CaptureRequirement(3251, @"[In Server Requests Setting of Security Information,
                        Pseudocode for the operation is as follows:If SecurityInformation contains OWNER_SECURITY_INFORMATION:]
                        If InputBuffer.OwnerSid is not present, the operation MUST be failed with STATUS_INVALID_OWNER.");
                    Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
                    return MessageStatus.INVALID_OWNER;
                }
                if (ownerSidEnum == OwnerSid.InputBufferOwnerSidNotValid)
                {
                    Helper.CaptureRequirement(4584, @"[In Server Requests Setting of Security Information,
                        Pseudocode for the operation is as follows:If SecurityInformation contains OWNER_SECURITY_INFORMATION:]
                        If InputBuffer.OwnerSid is not a valid owner SID for a file in the object store, as determined in an implementation-specific manner,
                        the object store MUST return STATUS_INVALID_OWNER.");
                    Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
                    return MessageStatus.INVALID_OWNER;
                }
            }
            else
            {
                // If Open.File.SecurityDescriptor.Owner is NULL
                if (ownerSidEnum == OwnerSid.OpenFileSecDesOwnerIsNull)
                {
                    Helper.CaptureRequirement(3252, @"[In Server Requests Setting of Security Information,Pseudocode for the operation is as follows:
                        else If SecurityInformation doesn't contain OWNER_SECURITY_INFORMATION:]If Open.File.SecurityDescriptor.Owner is NULL,
                        the operation MUST be failed with STATUS_INVALID_OWNER.");
                    Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
                    return MessageStatus.INVALID_OWNER;
                }
            }
            Helper.CaptureRequirement(3255, @"[In Server Requests Setting of Security Information,Pseudocode for the operation is as follows:]
                 The operation returns STATUS_SUCCESS.");
            Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion,
                        the object store MUST return:[Status].");
            return MessageStatus.SUCCESS;
        }
Ejemplo n.º 49
0
 public static extern NtStatus SamSetSecurityObject(
     [In] IntPtr ObjectHandle,
     [In] SecurityInformation SecurityInformation,
     [In] IntPtr SecurityDescriptor // SecurityDescriptor*
     );
 /// <summary>
 /// Get the security descriptor for a service.
 /// </summary>
 /// <param name="name">The name of the service.</param>
 /// <param name="security_information">Parts of the security descriptor to return.</param>
 /// <returns>The security descriptor.</returns>
 public static SecurityDescriptor GetServiceSecurityDescriptor(string name,
                                                               SecurityInformation security_information)
 {
     return(GetServiceSecurityDescriptor(name, security_information, true).Result);
 }
        /// <summary>
        /// Sets the security descriptor of an object.
        /// </summary>
        /// <param name="handle">A handle to an object.</param>
        /// <param name="objectType">The type of the object.</param>
        /// <param name="securityInformation">The information to modify.</param>
        /// <param name="securityDescriptor">The security descriptor.</param>
        public static void SetSecurity(IntPtr handle, SeObjectType objectType, SecurityInformation securityInformation, SecurityDescriptor securityDescriptor)
        {
            Win32Error result;
            IntPtr dacl = IntPtr.Zero;
            IntPtr group = IntPtr.Zero;
            IntPtr owner = IntPtr.Zero;
            IntPtr sacl = IntPtr.Zero;

            if (securityInformation.HasFlag(SecurityInformation.Dacl))
                dacl = securityDescriptor.Dacl ?? IntPtr.Zero;
            if (securityInformation.HasFlag(SecurityInformation.Group))
                group = securityDescriptor.Group;
            if (securityInformation.HasFlag(SecurityInformation.Owner))
                owner = securityDescriptor.Owner;
            if (securityInformation.HasFlag(SecurityInformation.Sacl))
                sacl = securityDescriptor.Sacl ?? IntPtr.Zero;

            if ((result = Win32.SetSecurityInfo(
                handle,
                objectType,
                securityInformation,
                owner,
                group,
                dacl,
                sacl
                )) != 0)
                Win32.Throw(result);
        }
Ejemplo n.º 52
0
        public static MessageStatus SetSecurityInfo(
            SecurityInformation securityInformation,
            OwnerSid ownerSidEnum
            )
        {
            //If the object store does not implement security, the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.
            if (!isObjectImplementedFunctionality)
            {
                Helper.CaptureRequirement(3232, @"[In Server Requests Setting of Security Information] If the object store does not implement security, 
                    the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.");
                return(MessageStatus.INVALID_DEVICE_REQUEST);
            }
            // SecurityInformation contains any of OWNER_SECURITY_INFORMATION, GROUP_SECURITY_INFORMATION, or LABEL_SECURITY_INFORMATION, and Open.GrantedAccess does not contain WRITE_OWNER.
            if ((securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION || securityInformation == SecurityInformation.GROUP_SECURITY_INFORMATION || securityInformation == SecurityInformation.LABEL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.WRITE_OWNER) == 0))
            {
                Helper.CaptureRequirement(3258, @"[In Server Requests Setting of Security Information]  
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:SecurityInformation 
                    contains any of LABEL_SECURITY_INFORMATION, and Open.GrantedAccess does not contain WRITE_OWNER.");
                Helper.CaptureRequirement(3256, @"[In Server Requests Setting of Security Information]  
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions: 
                    SecurityInformation contains any of OWNER_SECURITY_INFORMATION,  and Open.GrantedAccess does not contain WRITE_OWNER.");
                Helper.CaptureRequirement(3257, @"[In Server Requests Setting of Security Information]  
                     The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:
                     SecurityInformation contains any of GROUP_SECURITY_INFORMATION,, and Open.GrantedAccess does not contain WRITE_OWNER.");
                Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
                return(MessageStatus.ACCESS_DENIED);
            }
            // SecurityInformation contains DACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain WRITE_DAC
            if ((securityInformation == SecurityInformation.DACL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.WRITE_DAC) == 0))
            {
                Helper.CaptureRequirement(3243, @"[In Server Requests Setting of Security Information]  
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions:
                    SecurityInformation contains DACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain WRITE_DAC.");
                Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
                return(MessageStatus.ACCESS_DENIED);
            }
            // ? SecurityInformation contains SACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain ACCESS_SYSTEM_SECURITY.
            if ((securityInformation == SecurityInformation.SACL_SECURITY_INFORMATION) && ((gOpenGrantedAccess & FileAccess.ACCESS_SYSTEM_SECURITY) == 0))
            {
                Helper.CaptureRequirement(3244, @"[In Server Requests Setting of Security Information]  
                    The operation MUST be failed with STATUS_ACCESS_DENIED under any of the following conditions: SecurityInformation contains SACL_SECURITY_INFORMATION and Open.GrantedAccess does not contain ACCESS_SYSTEM_SECURITY.");
                Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
                return(MessageStatus.ACCESS_DENIED);
            }

            // If SecurityInformation contains OWNER_SECURITY_INFORMATION
            if (securityInformation == SecurityInformation.OWNER_SECURITY_INFORMATION)
            {
                // If InputBuffer.OwnerSid is not present,
                if (ownerSidEnum == OwnerSid.InputBufferOwnerSidNotPresent)
                {
                    Helper.CaptureRequirement(3251, @"[In Server Requests Setting of Security Information, 
                        Pseudocode for the operation is as follows:If SecurityInformation contains OWNER_SECURITY_INFORMATION:]
                        If InputBuffer.OwnerSid is not present, the operation MUST be failed with STATUS_INVALID_OWNER.");
                    Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
                    return(MessageStatus.INVALID_OWNER);
                }
                if (ownerSidEnum == OwnerSid.InputBufferOwnerSidNotValid)
                {
                    Helper.CaptureRequirement(4584, @"[In Server Requests Setting of Security Information, 
                        Pseudocode for the operation is as follows:If SecurityInformation contains OWNER_SECURITY_INFORMATION:]
                        If InputBuffer.OwnerSid is not a valid owner SID for a file in the object store, as determined in an implementation-specific manner, 
                        the object store MUST return STATUS_INVALID_OWNER.");
                    Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
                    return(MessageStatus.INVALID_OWNER);
                }
            }
            else
            {
                // If Open.File.SecurityDescriptor.Owner is NULL
                if (ownerSidEnum == OwnerSid.OpenFileSecDesOwnerIsNull)
                {
                    Helper.CaptureRequirement(3252, @"[In Server Requests Setting of Security Information,Pseudocode for the operation is as follows:
                        else If SecurityInformation doesn't contain OWNER_SECURITY_INFORMATION:]If Open.File.SecurityDescriptor.Owner is NULL, 
                        the operation MUST be failed with STATUS_INVALID_OWNER.");
                    Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
                    return(MessageStatus.INVALID_OWNER);
                }
            }
            Helper.CaptureRequirement(3255, @"[In Server Requests Setting of Security Information,Pseudocode for the operation is as follows:]
                 The operation returns STATUS_SUCCESS.");
            Helper.CaptureRequirement(3239, @"[In Server Requests Setting of Security Information]On completion, 
                        the object store MUST return:[Status].");
            return(MessageStatus.SUCCESS);
        }
Ejemplo n.º 53
-1
        /// <summary>
        /// Gets the security descriptor of a kernel object.
        /// </summary>
        /// <param name="handle">A handle to a kernel object.</param>
        /// <param name="securityInformation">The information to retrieve.</param>
        /// <returns>A security descriptor.</returns>
        public static SecurityDescriptor GetSecurity(IntPtr handle, SecurityInformation securityInformation)
        {
            NtStatus status;
            int retLength;

            using (var data = new MemoryAlloc(0x100))
            {
                status = Win32.NtQuerySecurityObject(
                    handle,
                    securityInformation,
                    data,
                    data.Size,
                    out retLength
                    );

                if (status == NtStatus.BufferTooSmall)
                {
                    data.Resize(retLength);

                    status = Win32.NtQuerySecurityObject(
                        handle,
                        securityInformation,
                        data,
                        data.Size,
                        out retLength
                        );
                }

                if (status >= NtStatus.Error)
                    Win32.ThrowLastError(status);

                return new SecurityDescriptor(data);
            }
        }
Ejemplo n.º 54
-1
        /// <summary>
        /// Gets the security descriptor of an object.
        /// </summary>
        /// <param name="handle">A handle to an object.</param>
        /// <param name="objectType">The type of the object.</param>
        /// <param name="securityInformation">The information to retrieve.</param>
        /// <returns>A security descriptor.</returns>
        public static SecurityDescriptor GetSecurity(IntPtr handle, SeObjectType objectType, SecurityInformation securityInformation)
        {
            Win32Error result;
            IntPtr dummy, securityDescriptor;

            if ((result = Win32.GetSecurityInfo(
                handle,
                objectType,
                securityInformation,
                out dummy, out dummy, out dummy, out dummy,
                out securityDescriptor
                )) != 0)
                Win32.Throw(result);

            return new SecurityDescriptor(new LocalMemoryAlloc(securityDescriptor));
        }
		private static extern bool GetFileSecurity(string lpFileName, SecurityInformation requestedInformation, IntPtr securityDescriptor, int length, ref int lengthNeeded);
Ejemplo n.º 56
-2
        /// <summary>
        /// Gets the security descriptor of a kernel object.
        /// </summary>
        /// <param name="handle">A handle to a kernel object.</param>
        /// <param name="securityInformation">The information to retrieve.</param>
        /// <returns>A security descriptor.</returns>
        public static SecurityDescriptor GetSecurity(IntPtr handle, SecurityInformation securityInformation)
        {
            using (MemoryAlloc data = new MemoryAlloc(0x100))
            {
                int retLength;

                NtStatus status = Win32.NtQuerySecurityObject(
                    handle,
                    securityInformation,
                    data,
                    data.Size,
                    out retLength
                    );

                if (status == NtStatus.BufferTooSmall)
                {
                    data.ResizeNew(retLength);

                    Win32.NtQuerySecurityObject(
                        handle,
                        securityInformation,
                        data,
                        data.Size,
                        out retLength
                        ).ThrowIf();
                }

                status.ThrowIf();

                return new SecurityDescriptor(data);
            }
        }