Пример #1
0
        private void WriteToSecurityLog(int auditId, bool success, params object[] parameters)
        {
            ThrowIfDisposed();

            //
            // Report the event
            //

            IntPtr paramArray = IntPtr.Zero;

            GCHandle[] handleArray = null;

            try
            {
                if (parameters.Length > 0)
                {
                    handleArray = new GCHandle[parameters.Length + 1];
                    int j = 0;
                    handleArray[j] = GCHandle.Alloc(new byte[Marshal.SizeOf(typeof(Win32Native.AUDIT_PARAM)) * parameters.Length], GCHandleType.Pinned);
                    paramArray     = handleArray[j].AddrOfPinnedObject();
                    j++;

                    for (int i = 0; i < parameters.Length; i++)
                    {
                        Win32Native.AUDIT_PARAM paramArrayElement = new Win32Native.AUDIT_PARAM();
                        paramArrayElement.Flags  = 0;
                        paramArrayElement.Length = 0;

                        System.Type type = parameters[i].GetType();

                        if (type == typeof(String))
                        {
                            paramArrayElement.Type  = (uint)AUDIT_PARAM_TYPE.APT_String;
                            handleArray[j]          = GCHandle.Alloc((parameters[i] as string), GCHandleType.Pinned);
                            paramArrayElement.Data0 = handleArray[j].AddrOfPinnedObject();
                            paramArrayElement.Data1 = IntPtr.Zero;
                            j++;
                        }
                        else if (type == typeof(uint) ||
                                 type == typeof(ushort) ||
                                 type == typeof(byte) ||
                                 type == typeof(int) ||
                                 type == typeof(short) ||
                                 type == typeof(sbyte))
                        {
                            paramArrayElement.Type  = (uint)AUDIT_PARAM_TYPE.APT_Ulong;
                            paramArrayElement.Data0 = new IntPtr((int)parameters[i]);
                            paramArrayElement.Data1 = IntPtr.Zero;
                        }

                        /*
                         *                      else if ( type == typeof( SecurityIdentifier ))
                         *                      {
                         *                          SecurityIdentifier sid = parameters[i] as SecurityIdentifier;
                         *                          byte[] binaryForm = new byte[sid.BinaryLength];
                         *                          sid.GetBinaryForm( binaryForm, 0 );
                         *
                         *                          paramArrayElement.Type = ( uint )AUDIT_PARAM_TYPE.APT_Sid;
                         *                          // Can use BinaryForm property if inside of BCL
                         *                          handleArray[j] = GCHandle.Alloc( binaryForm, GCHandleType.Pinned );
                         *                          paramArrayElement.Data0 = handleArray[j].AddrOfPinnedObject();
                         *                          paramArrayElement.Data1 = IntPtr.Zero;
                         *                          j++;
                         *                      }
                         */
                        else if (type == typeof(Guid))
                        {
                            paramArrayElement.Type  = (uint)AUDIT_PARAM_TYPE.APT_Guid;
                            handleArray[j]          = GCHandle.Alloc(((Guid)parameters[i]).ToByteArray(), GCHandleType.Pinned);
                            paramArrayElement.Data0 = handleArray[j].AddrOfPinnedObject();
                            paramArrayElement.Data1 = IntPtr.Zero;
                            j++;
                        }
                        else if (type == typeof(DateTime))
                        {
                            paramArrayElement.Type  = (uint)AUDIT_PARAM_TYPE.APT_Time;
                            paramArrayElement.Data0 = new IntPtr((int)(((DateTime)parameters[i]).ToFileTime() & 0xFFFFFFFF));
                            paramArrayElement.Data1 = new IntPtr((int)((((DateTime)parameters[i]).ToFileTime() >> 32) & 0xFFFFFFFF));
                        }
                        // Add LogonId and Luid support, if necessary
                        else if (type == typeof(Int64) ||
                                 type == typeof(UInt64))
                        {
                            paramArrayElement.Type  = (uint)AUDIT_PARAM_TYPE.APT_Int64;
                            paramArrayElement.Data0 = new IntPtr((int)((uint)parameters[i]) & 0xFFFFFFFF);
                            paramArrayElement.Data1 = new IntPtr((int)(((int)parameters[i] >> 32) & 0xFFFFFFFF));
                        }
                        else
                        {
                            throw new ArgumentException("Type unsuitable for auditing", nameof(parameters));
                        }

                        //
                        // Marshal the structure into the parameters array
                        //

                        Marshal.StructureToPtr(paramArrayElement, new IntPtr(paramArray.ToInt64() + i * Marshal.SizeOf(typeof(Win32Native.AUDIT_PARAM))), false);
                    }
                }

                Win32Native.AUDIT_PARAMS auditParams = new Win32Native.AUDIT_PARAMS();
                auditParams.Length = 0;
                auditParams.Flags  = success ? Win32Native.APF_AuditSuccess : Win32Native.APF_AuditFailure;
                unchecked { auditParams.Count = (ushort)parameters.Length; }
                auditParams.Parameters = paramArray;

                if (false == Win32Native.AuthzReportSecurityEventFromParams(0, this.securityLogHandle, (uint)auditId, null, auditParams))
                {
                    int error = Marshal.GetLastWin32Error();

                    if (error == Win32Native.ERROR_NOT_ENOUGH_MEMORY)
                    {
                        throw new OutOfMemoryException();
                    }
                    else if (error == Win32Native.ERROR_ACCESS_DENIED)
                    {
                        throw new UnauthorizedAccessException();
                    }
                    else if (error == Win32Native.ERROR_INVALID_PARAMETER)
                    {
                        // Marshaling failed!
                        throw new Win32Exception(error);
                    }
                    else
                    {
                        throw new Win32Exception(error);
                    }
                }
            }
            finally
            {
                if (handleArray != null)
                {
                    for (int i = 0; i < handleArray.Length; i++)
                    {
                        if (handleArray[i].IsAllocated)
                        {
                            handleArray[i].Free();
                        }
                    }
                }
            }
        }