Exemple #1
0
 public static byte[] ToBytes(this SecurityIdentifier s)
 {
     byte[] b = new byte[s.BinaryLength];
     s.GetBinaryForm(b, 0);
     return(b);
 }
Exemple #2
0
            public unsafe static uint Request(
                SafeFileHandle hPort,
                uint tenantId,
                uint flowId,
                string accountName,
                SecurityIdentifier sid,
                string shareName)
            {
                uint                       HRESULT         = 0;
                uint                       lpBytesReturned = 0;
                UnicodeEncoding            enc             = new UnicodeEncoding();
                OKTOPUS_CREATE_RAP_REQUEST Request         = new OKTOPUS_CREATE_RAP_REQUEST();
                OKTOPUS_CREATE_RAP_REPLY   Reply           = new OKTOPUS_CREATE_RAP_REPLY();

                if (accountName.Length + 1 > OKTO_VM_NAME_MAX_CHARS)
                {
                    throw new ExceptionIoFlow(DecodeOktoResult((uint)RESULTCODES.OKTO_VM_NAME_TOO_LONG));
                }
                if (shareName.Length + 1 > OKTO_SHARE_NAME_MAX_CHARS)
                {
                    throw new ExceptionIoFlow(DecodeOktoResult((uint)RESULTCODES.OKTO_SHARE_NAME_TOO_LONG));
                }
                if (sid.BinaryLength > OKTO_SID_BUFF_BYTE_LEN)
                {
                    throw new ExceptionIoFlow(DecodeOktoResult((uint)RESULTCODES.OKTO_VM_SID_TOO_LONG));
                }

                //
                // Format request buffer.
                //
                Request.OpCode            = (ulong)IOFLOWUSER_OPCODE.OpCodeCreateRap;
                Request.TenantId          = tenantId;
                Request.FlowId            = flowId;
                Request.MaxStatsArraySize = MAX_STATS_ARRAY_SIZE;
                Request.Result            = 0;
                Request.VmNameWCharLen    = ((uint)enc.GetByteCount(accountName) / 2) + 1;
                byte[] encVmNameBuff = new byte[OKTO_VM_NAME_BUFF_WCZ_MAX * 2];
                enc.GetBytes(accountName, 0, accountName.Length, encVmNameBuff, 0);
                for (int i = 0; i < OKTO_VM_NAME_BUFF_WCZ_MAX * 2; i++)
                {
                    Request.VmNameBuff[i] = encVmNameBuff[i];
                }
                Request.ShareNameWCharZLen = ((uint)enc.GetByteCount(shareName) / 2) + 1;
                byte[] encShareNameBuff = new byte[OKTO_SHARE_NAME_BUFF_WCZ_MAX * 2];
                enc.GetBytes(shareName, 0, shareName.Length, encShareNameBuff, 0);
                for (int i = 0; i < OKTO_SHARE_NAME_BUFF_WCZ_MAX * 2; i++)
                {
                    Request.ShareNameBuff[i] = encShareNameBuff[i];
                }
                Request.SidLength = (uint)sid.BinaryLength;
                byte[] sidBuff = new byte[sid.BinaryLength];
                sid.GetBinaryForm(sidBuff, 0);
                for (int i = 0; i < sid.BinaryLength; i++)
                {
                    Request.Sid[i] = sidBuff[i];
                }
                Request.PID     = 0;
                Request.i_index = 0;
                Request.j_index = 0;


                Reply.Result = 0;

                // Pin buffers for duration of synchronous call to FilterSendMessage.
                GCHandle gchRequest = GCHandle.Alloc(Request, GCHandleType.Pinned);
                GCHandle gchReply   = GCHandle.Alloc(Reply, GCHandleType.Pinned);

                // FilterSendMessage() ref http://msdn.microsoft.com/en-us/library/windows/hardware/ff541513(v=vs.85).aspx
                HRESULT = FilterSendMessage(hPort,                           // HANDLE hPort,
                                            gchRequest.AddrOfPinnedObject(), // LPVOID lpInBuffer,
                                            (uint)Marshal.SizeOf(Request),   // DWORD dwInBufferSize,
                                            gchReply.AddrOfPinnedObject(),   // LPVOID lpOutBuffer,
                                            (uint)Marshal.SizeOf(Reply),     // DWORD dwOutBufferSize,
                                            out lpBytesReturned);            // LPDWORD lpBytesReturned

                if (HRESULT != S_OK)
                {
                    Marshal.ThrowExceptionForHR((int)HRESULT);
                }

                if (Reply.Result != (uint)RESULTCODES.OKTO_RESULT_SUCCESS)
                {
                    throw new ExceptionIoFlow(DecodeOktoResult(Reply.Result));
                }

                gchRequest.Free();
                gchReply.Free();

                return(HRESULT);
            }
Exemple #3
0
        internal static int SetSecurityInfo(
            ResourceType type,
            string name,
            SafeHandle handle,
            SecurityInfos securityInformation,
            SecurityIdentifier owner,
            SecurityIdentifier group,
            GenericAcl sacl,
            GenericAcl dacl)
        {
            int errorCode;
            int Length;

            byte[]    OwnerBinary       = null, GroupBinary = null, SaclBinary = null, DaclBinary = null;
            Privilege securityPrivilege = null;

            //
            // Demand unmanaged code permission
            // The integrator layer is free to assert this permission
            // and, in turn, demand another permission of its caller
            //

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

            if (owner != null)
            {
                Length      = owner.BinaryLength;
                OwnerBinary = new byte[Length];
                owner.GetBinaryForm(OwnerBinary, 0);
            }

            if (@group != null)
            {
                Length      = @group.BinaryLength;
                GroupBinary = new byte[Length];
                @group.GetBinaryForm(GroupBinary, 0);
            }

            if (dacl != null)
            {
                Length     = dacl.BinaryLength;
                DaclBinary = new byte[Length];
                dacl.GetBinaryForm(DaclBinary, 0);
            }

            if (sacl != null)
            {
                Length     = sacl.BinaryLength;
                SaclBinary = new byte[Length];
                sacl.GetBinaryForm(SaclBinary, 0);
            }

            if ((securityInformation & SecurityInfos.SystemAcl) != 0)
            {
                //
                // Enable security privilege if trying to set a SACL.
                // Note: even setting it by handle needs this privilege enabled!
                //

                securityPrivilege = new Privilege(Privilege.Security);
            }

            // Ensure that the finally block will execute
            RuntimeHelpers.PrepareConstrainedRegions();

            try
            {
                if (securityPrivilege != null)
                {
                    try
                    {
                        securityPrivilege.Enable();
                    }
                    catch (PrivilegeNotHeldException)
                    {
                        // we will ignore this exception and press on just in case this is a remote resource
                    }
                }

                if (name != null)
                {
                    errorCode = (int)NativeMethods.SetSecurityInfoByName(name, (uint)type, (uint)securityInformation, OwnerBinary, GroupBinary, DaclBinary, SaclBinary);
                }
                else if (handle != null)
                {
                    if (handle.IsInvalid)
                    {
                        throw new ArgumentException("Invalid safe handle");
                    }
                    else
                    {
                        errorCode = (int)NativeMethods.SetSecurityInfoByHandle(handle, (uint)type, (uint)securityInformation, OwnerBinary, GroupBinary, DaclBinary, SaclBinary);
                    }
                }
                else
                {
                    // both are null, shouldn't happen
                    throw new InvalidProgramException();
                }

                if (errorCode == NativeMethods.ERROR_NOT_ALL_ASSIGNED ||
                    errorCode == NativeMethods.ERROR_PRIVILEGE_NOT_HELD)
                {
                    throw new PrivilegeNotHeldException(Privilege.Security);
                }
                else if (errorCode == NativeMethods.ERROR_ACCESS_DENIED ||
                         errorCode == NativeMethods.ERROR_CANT_OPEN_ANONYMOUS)
                {
                    throw new UnauthorizedAccessException();
                }
                else if (errorCode != NativeMethods.ERROR_SUCCESS)
                {
                    goto Error;
                }
            }
            catch
            {
                // protection against exception filter-based luring attacks
                if (securityPrivilege != null)
                {
                    securityPrivilege.Revert();
                }
                throw;
            }
            finally
            {
                if (securityPrivilege != null)
                {
                    securityPrivilege.Revert();
                }
            }

            return(0);

Error:

            if (errorCode == NativeMethods.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }

            return(errorCode);
        }
        public void ReadEffectivePermissions(string folder, string username, ref AppsClient.AppsResult result)
        {
            ////String UserName = "******";
            //do
            //{
            //    Console.WriteLine("UserName:"******"rbrooks"; // Console.ReadLine();
            //    Console.WriteLine("Path:");
            String Path = folder;       // @"D:\Work\Brooksoft\AppsJS\AppsJSCLI2\AppsDesktop\AppFolders\App49\Software\Software19"; // Console.ReadLine();


            if (System.IO.Directory.Exists(folder))
            {
                IntPtr      pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
                ACCESS_MASK mask = new ACCESS_MASK();
                uint        ret  = GetNamedSecurityInfo(Path,
                                                        SE_OBJECT_TYPE.SE_FILE_OBJECT,
                                                        SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION,
                                                        out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

                IntPtr hManager = IntPtr.Zero;


                bool f = AuthzInitializeResourceManager(1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out hManager);

                NTAccount          ac    = new NTAccount(UserName);
                SecurityIdentifier sid   = (SecurityIdentifier)ac.Translate(typeof(SecurityIdentifier));
                byte[]             bytes = new byte[sid.BinaryLength];
                sid.GetBinaryForm(bytes, 0);
                String _psUserSid = "";
                foreach (byte si in bytes)
                {
                    _psUserSid += si;
                }

                LUID   unusedSid = new LUID();
                IntPtr UserSid   = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, UserSid, bytes.Length);
                IntPtr pClientContext = IntPtr.Zero;

                if (f)
                {
                    f = AuthzInitializeContextFromSid(0, UserSid, hManager, IntPtr.Zero, unusedSid, IntPtr.Zero, out pClientContext);


                    AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
                    request.DesiredAccess        = 0x02000000;
                    request.PrincipalSelfSid     = null;
                    request.ObjectTypeList       = null;
                    request.ObjectTypeListLength = 0;
                    request.OptionalArguments    = IntPtr.Zero;

                    AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
                    reply.GrantedAccessMask     = IntPtr.Zero;
                    reply.ResultListLength      = 0;
                    reply.SaclEvaluationResults = IntPtr.Zero;
                    IntPtr AccessReply = IntPtr.Zero;
                    reply.Error             = Marshal.AllocHGlobal(1020);
                    reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint));
                    reply.ResultListLength  = 1;
                    int i = 0;
                    Dictionary <String, String> rightsmap = new Dictionary <String, String>();
                    List <string> effectivePermissionList = new List <string>();
                    string[]      rights = new string[14] {
                        "Full Control", "Traverse Folder / execute file", "List folder / read data", "Read attributes", "Read extended attributes", "Create files / write files", "Create folders / append data", "Write attributes", "Write extended attributes", "Delete subfolders and files", "Delete", "Read permission", "Change permission", "Take ownership"
                    };
                    rightsmap.Add("FILE_TRAVERSE", "Traverse Folder / execute file");
                    rightsmap.Add("FILE_LIST_DIRECTORY", "List folder / read data");
                    rightsmap.Add("FILE_READ_DATA", "List folder / read data");
                    rightsmap.Add("FILE_READ_ATTRIBUTES", "Read attributes");
                    rightsmap.Add("FILE_READ_EA", "Read extended attributes");
                    rightsmap.Add("FILE_ADD_FILE", "Create files / write files");
                    rightsmap.Add("FILE_WRITE_DATA", "Create files /  write files");
                    rightsmap.Add("FILE_ADD_SUBDIRECTORY", "Create folders / append data");
                    rightsmap.Add("FILE_APPEND_DATA", "Create folders / append data");
                    rightsmap.Add("FILE_WRITE_ATTRIBUTES", "Write attributes");
                    rightsmap.Add("FILE_WRITE_EA", "Write extended attributes");
                    rightsmap.Add("FILE_DELETE_CHILD", "Delete subfolders and files");
                    rightsmap.Add("DELETE", "Delete");
                    rightsmap.Add("READ_CONTROL", "Read permission");
                    rightsmap.Add("WRITE_DAC", "Change permission");
                    rightsmap.Add("WRITE_OWNER", "Take ownership");


                    f = AuthzAccessCheck(0, pClientContext, ref request, IntPtr.Zero, pSecurityDescriptor, null, 0, ref reply, out AccessReply);
                    if (f)
                    {
                        int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);

                        mask = (ACCESS_MASK)granted_access;

                        foreach (ACCESS_MASK item in Enum.GetValues(typeof(ACCESS_MASK)))
                        {
                            if ((mask & item) == item)
                            {
                                effectivePermissionList.Add(rightsmap[item.ToString()]);
                                i++;
                            }
                        }
                    }
                    Marshal.FreeHGlobal(reply.GrantedAccessMask);



                    if (i == 16)
                    {
                        new AppFlows.Publish.Success("All perms satisfied so adding also full control.");
                        effectivePermissionList.Insert(0, "Full Control");
                    }
                    //        Console.WriteLine(".......................");
                    //        foreach (string r in rights)
                    //        {
                    //            if (effectivePermissionList.Contains(r))
                    //            {
                    //                Console.WriteLine(r);
                    //            }
                    //        }

                    //    }
                    //    Console.WriteLine("_________________________________________________\n");
                    //} while (true);

                    //Console.ReadLine();
                    result.Data    = effectivePermissionList;
                    result.Success = true;
                }
            }
            else
            {
                new AppFlows.Publish.Fail("Folder provided was not found.", ref result);
            }
        }
Exemple #5
0
 static void SerializeSid(SecurityIdentifier sid, SctClaimDictionary dictionary, XmlDictionaryWriter writer)
 {
     byte[] sidBytes = new byte[sid.BinaryLength];
     sid.GetBinaryForm(sidBytes, 0);
     writer.WriteBase64(sidBytes, 0, sidBytes.Length);
 }
Exemple #6
0
 public void WriteTo(byte[] buffer, int offset)
 {
     Sid.GetBinaryForm(buffer, offset);
 }
Exemple #7
0
 /// <summary>Initializes a new instance of the <see cref="PinnedSid"/> class.</summary>
 /// <param name="sid">The sid.</param>
 public PinnedSid(SecurityIdentifier sid)
 {
     bytes = new byte[sid.BinaryLength];
     sid.GetBinaryForm(bytes, 0);
     SetObject(bytes);
 }
Exemple #8
0
        private static void ShareFolder(string path, string name)
        {
            // Create a ManagementClass object
            ManagementClass managementClass = new ManagementClass("Win32_Share");

            // Create ManagementBaseObjects for in and out parameters
            ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");

            ManagementBaseObject outParams;

            // Set the input parameters
//			    inParams["Description"] = description;
            inParams["Name"] = name;
            inParams["Path"] = path;
            inParams["Type"] = 0x0;                 // Disk Drive

            //Another Type:
            // DISK_DRIVE = 0x0
            // PRINT_QUEUE = 0x1
            // DEVICE = 0x2
            // IPC = 0x3
            // DISK_DRIVE_ADMIN = 0x80000000
            // PRINT_QUEUE_ADMIN = 0x80000001
            // DEVICE_ADMIN = 0x80000002
            // IPC_ADMIN = 0x8000003

            //inParams["MaximumAllowed"] = int maxConnectionsNum;


            SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, WindowsIdentity.GetCurrent().User.AccountDomainSid);

            byte[] sidArray = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidArray, 0);

            ManagementObject everyoneTrustee = new ManagementClass("Win32_Trustee");

            everyoneTrustee["Domain"] = null;
            everyoneTrustee["Name"]   = "Everyone";
            everyoneTrustee["SID"]    = sidArray;

            ManagementObject userACE = new ManagementClass("Win32_Ace");

            userACE["AccessMask"] = 2032127;                     //Full access
            userACE["AceFlags"]   = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
            userACE["AceType"]    = AceType.AccessAllowed;
            userACE["Trustee"]    = everyoneTrustee;

            ManagementObject securityDescriptor = new ManagementClass("Win32_SecurityDescriptor");

            securityDescriptor["ControlFlags"] = 4;                     //SE_DACL_PRESENT
            securityDescriptor["DACL"]         = new object[] { userACE };

            inParams["Access"] = securityDescriptor;



            // Invoke the method on the ManagementClass object
            outParams = managementClass.InvokeMethod("Create", inParams, null);

            // Check to see if the method invocation was successful
//			    if ((uint) (outParams.Properties["ReturnValue"].Value) != 0)
//			    {
//			        throw new Exception("Unable to share directory.");
//			    }
        }
Exemple #9
0
        private int ShareFolder(string FolderPath, string ShareName, string Description)
        {
            try
            {
                // Create a ManagementClass object
                ManagementClass managementClass = new ManagementClass("Win32_Share");

                // Create ManagementBaseObjects for in and out parameters
                ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
                ManagementBaseObject outParams;

                // Set the input parameters
                inParams["Description"] = Description;
                inParams["Name"]        = ShareName;
                inParams["Path"]        = FolderPath;
                inParams["Type"]        = 0x0; // Disk Drive
                //Another Type:
                //        DISK_DRIVE = 0x0
                //        PRINT_QUEUE = 0x1
                //        DEVICE = 0x2
                //        IPC = 0x3
                //        DISK_DRIVE_ADMIN = 0x80000000
                //        PRINT_QUEUE_ADMIN = 0x80000001
                //        DEVICE_ADMIN = 0x80000002
                //        IPC_ADMIN = 0x8000003
                inParams["MaximumAllowed"] = null;
                inParams["Password"]       = null;
                inParams["Access"]         = null; // Make Everyone has full control access.
                //inParams["MaximumAllowed"] = int maxConnectionsNum;

                // Invoke the method on the ManagementClass object
                outParams = managementClass.InvokeMethod("Create", inParams, null);
                // Check to see if the method invocation was successful

                Console.WriteLine("Creation of calculator process returned: " + outParams["returnValue"]);

                //0
                //Success
                //2
                //Access Denied
                //8
                //Unknown Failure
                //9
                //Invalid Name
                //10
                //Invalid Level
                //21
                //Invalid Parameter
                //22
                //Duplicate Share
                //23
                //Redirected Path
                //24
                //Unknown Device or Directory
                //25
                //Net Name Not Found

                if ((uint)(outParams.Properties["ReturnValue"].Value) == 22)
                {
                    // share already exits
                }

                if (((uint)(outParams.Properties["ReturnValue"].Value) != 0) && ((uint)(outParams.Properties["ReturnValue"].Value) != 22))
                {
                    LogError(LogErrorLevel.A, "Error sharing MMS folders. Please make sure you run as Administrator. Error:" + outParams.Properties["ReturnValue"].Value);
                    return(1);
                }

                //user selection
                NTAccount ntAccount = new NTAccount("Everyone");

                //SID
                SecurityIdentifier userSID        = (SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier));
                byte[]             utenteSIDArray = new byte[userSID.BinaryLength];
                userSID.GetBinaryForm(utenteSIDArray, 0);

                //Trustee
                ManagementObject userTrustee = new ManagementClass(new ManagementPath("Win32_Trustee"), null);
                userTrustee["Name"] = "Everyone";
                userTrustee["SID"]  = utenteSIDArray;

                //ACE
                ManagementObject userACE = new ManagementClass(new ManagementPath("Win32_Ace"), null);
                userACE["AccessMask"] = 2032127;                                 //Full access
                userACE["AceFlags"]   = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
                userACE["AceType"]    = AceType.AccessAllowed;
                userACE["Trustee"]    = userTrustee;

                ManagementObject userSecurityDescriptor = new ManagementClass(new ManagementPath("Win32_SecurityDescriptor"), null);
                userSecurityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
                userSecurityDescriptor["DACL"]         = new object[] { userACE };
                //can declare share either way, where "ShareName" is the name used to share the folder
                //ManagementPath path = new ManagementPath("Win32_Share.Name='" + ShareName + "'");
                //ManagementObject share = new ManagementObject(path);
                ManagementObject share = new ManagementObject(managementClass.Path + ".Name='" + ShareName + "'");

                share.InvokeMethod("SetShareInfo", new object[] { Int32.MaxValue, Description, userSecurityDescriptor });
            }
            catch (Exception ex)
            {
                LogError(LogErrorLevel.A, "Error sharing folders. Please make sure you run as Administrator. ERROR: " + ex.Message);
                return(1);
            }

            return(0);
        }
Exemple #10
0
        static public void ShareFolderPermission(string FolderPath, string ShareName,
                                                 string machine, string Username, string Password)
        {
            try
            {
                Console.WriteLine("ShareFolderPermission:" +
                                  FolderPath + "|" + ShareName
                                  + "|" + machine
                                  + "|" + Username
                                  + "|" + Password);

                ConnectionOptions connection = new ConnectionOptions();
                connection.Username  = Username;
                connection.Password  = Password;
                connection.Authority = "ntlmdomain:";

                ManagementScope scope = new ManagementScope(
                    "\\\\" + machine + "\\root\\CIMV2", connection);
                scope.Connect();

                // Calling Win32_Share class to create a shared folder

                ManagementClass managementClass = new ManagementClass(scope, new ManagementPath("Win32_Share"), new ObjectGetOptions());
                // Get the parameter for the Create Method for the folder
                ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
                ManagementBaseObject outParams;
                // Assigning the values to the parameters
                inParams["Description"] = "Root Shared";
                inParams["Name"]        = ShareName;
                inParams["Path"]        = FolderPath;
                inParams["Type"]        = 0x0;
                //////////////////////////
                inParams["Password"] = null;

                NTAccount          everyoneAccount = new NTAccount(null, "EVERYONE");
                SecurityIdentifier sid             = (SecurityIdentifier)everyoneAccount.Translate(typeof(SecurityIdentifier));
                byte[]             sidArray        = new byte[sid.BinaryLength];
                sid.GetBinaryForm(sidArray, 0);

                ManagementObject everyone = new ManagementClass("Win32_Trustee");
                everyone["Domain"] = null;
                everyone["Name"]   = "EVERYONE";
                everyone["SID"]    = sidArray;

                ManagementObject dacl = new ManagementClass("Win32_Ace");
                dacl["AccessMask"] = 2032127;
                dacl["AceFlags"]   = 3;
                dacl["AceType"]    = 0;
                dacl["Trustee"]    = everyone;

                ManagementObject securityDescriptor = new ManagementClass("Win32_SecurityDescriptor");
                securityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
                securityDescriptor["DACL"]         = new object[] { dacl };

                inParams["Access"] = securityDescriptor;
                //////////////////////////
                // Finally Invoke the Create Method to do the process
                outParams = managementClass.InvokeMethod("Create", inParams, null);
                // Validation done here to check sharing is done or not
                if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
                {
                    Console.WriteLine("Folder might be already in share or unable to share the directory");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
 internal static NtStatus SamOpenDomain(SafeSamHandle serverHandle, SamDomainAccessMask desiredAccess, SecurityIdentifier domainSid, out SafeSamHandle domainHandle)
 {
     byte[] binarySid = domainSid.GetBinaryForm();
     return(SamOpenDomain(serverHandle, desiredAccess, binarySid, out domainHandle));
 }
Exemple #12
0
        private static object[] ObjectAce_CreateTestData(int intFlags, int intQualifier, int accessMask, string stringsid, int intObjectAceFlags, string stringType, string stringInheritedType, bool isCallback, int opaqueLength, int offset)
        {
            AceFlags           aceFlags  = (AceFlags)intFlags;
            AceQualifier       qualifier = (AceQualifier)intQualifier;
            SecurityIdentifier sid       = new SecurityIdentifier(stringsid);
            ObjectAceFlags     flags     = (ObjectAceFlags)intObjectAceFlags;
            Guid type          = new Guid(stringType);
            Guid inheritedType = new Guid(stringInheritedType);

            byte[] opaque = new byte[opaqueLength];

            ObjectAce ace = new ObjectAce(aceFlags, qualifier, accessMask, sid, flags, type, inheritedType, isCallback, opaque);

            VerifyObjectAce(ace, aceFlags, qualifier, accessMask, sid, flags, type, inheritedType, isCallback, opaque);

            byte[] binaryForm = new byte[ace.BinaryLength + offset];
            switch (qualifier)
            {
            case AceQualifier.AccessAllowed:
                binaryForm[offset + 0] = isCallback ? (byte)AceType.AccessAllowedCallbackObject : (byte)AceType.AccessAllowedObject;
                break;

            case AceQualifier.AccessDenied:
                binaryForm[offset + 0] = isCallback ? (byte)AceType.AccessDeniedCallbackObject : (byte)AceType.AccessDeniedObject;
                break;

            case AceQualifier.SystemAudit:
                binaryForm[offset + 0] = isCallback ? (byte)AceType.SystemAuditCallbackObject : (byte)AceType.SystemAuditObject;
                break;

            case AceQualifier.SystemAlarm:
                binaryForm[offset + 0] = isCallback ? (byte)AceType.SystemAlarmCallbackObject : (byte)AceType.SystemAlarmObject;
                break;

            default:
                return(null);
            }
            binaryForm[offset + 1] = (byte)aceFlags;
            binaryForm[offset + 2] = (byte)(ace.BinaryLength >> 0);
            binaryForm[offset + 3] = (byte)(ace.BinaryLength >> 8);

            int baseOffset  = offset + 4;
            int offsetLocal = 0;

            unchecked
            {
                binaryForm[baseOffset + 0] = (byte)(accessMask >> 0);
                binaryForm[baseOffset + 1] = (byte)(accessMask >> 8);
                binaryForm[baseOffset + 2] = (byte)(accessMask >> 16);
                binaryForm[baseOffset + 3] = (byte)(accessMask >> 24);
            }
            offsetLocal += 4;

            binaryForm[baseOffset + offsetLocal + 0] = (byte)(((uint)flags) >> 0);
            binaryForm[baseOffset + offsetLocal + 1] = (byte)(((uint)flags) >> 8);
            binaryForm[baseOffset + offsetLocal + 2] = (byte)(((uint)flags) >> 16);
            binaryForm[baseOffset + offsetLocal + 3] = (byte)(((uint)flags) >> 24);

            offsetLocal += 4;

            if ((flags & ObjectAceFlags.ObjectAceTypePresent) != 0)
            {
                type.ToByteArray().CopyTo(binaryForm, baseOffset + offsetLocal);
                offsetLocal += 16;
            }

            if ((flags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0)
            {
                inheritedType.ToByteArray().CopyTo(binaryForm, baseOffset + offsetLocal);
                offsetLocal += 16;
            }

            sid.GetBinaryForm(binaryForm, baseOffset + offsetLocal);
            offsetLocal += sid.BinaryLength;
            opaque.CopyTo(binaryForm, baseOffset + offsetLocal);

            return(new object[] { ace, binaryForm, offset });
        }
Exemple #13
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Please specify a SID.");
            }

            var sidString = args[0];

            var success = Authz.AuthzInitializeResourceManager(Authz.AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT, null, null, null, "", out var rm);

            if (!success)
            {
                ReportLastError("AuthzInitializeResourceManager");
                return;
            }

            var sid      = new SecurityIdentifier(sidString);
            var sidBytes = new byte[sid.BinaryLength];

            sid.GetBinaryForm(sidBytes, 0);
            var psid = new SafePSID(sidBytes);

            success = Authz.AuthzInitializeContextFromSid(Authz.AuthzContextFlags.DEFAULT, psid, rm, IntPtr.Zero, new LUID(), IntPtr.Zero, out var context);
            if (!success)
            {
                ReportLastError("AuthzInitializeContextFromSid");
                Authz.AuthzFreeResourceManager(rm);
                return;
            }

            success = Authz.AuthzGetInformationFromContext(context, Authz.AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids, 0, out var sizeRequired, IntPtr.Zero);
            if (!success && Win32Error.GetLastError() != Win32Error.ERROR_INSUFFICIENT_BUFFER)
            {
                ReportLastError("AuthzGetInformationFromContext part 1");
                Authz.AuthzFreeContext(context);
                Authz.AuthzFreeResourceManager(rm);
                return;
            }

            if (sizeRequired == 0)
            {
                Console.WriteLine("No context information available?");
                Authz.AuthzFreeContext(context);
                Authz.AuthzFreeResourceManager(rm);
                return;
            }

            uint size   = sizeRequired;
            var  buffer = new SafeHGlobalHandle(size);

            success = Authz.AuthzGetInformationFromContext(context, Authz.AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids, size, out sizeRequired, buffer);
            if (!success)
            {
                ReportLastError("AuthzGetInformationFromContext part 2");
                Authz.AuthzFreeContext(context);
                Authz.AuthzFreeResourceManager(rm);
                return;
            }

            var tokenGroups = buffer.ToArray <TOKEN_GROUPS>(1);

            for (var i = 0; i < tokenGroups[0].GroupCount; i++)
            {
                var    tokenGroup  = tokenGroups[0].Groups[i];
                var    thisSid     = new SecurityIdentifier(tokenGroup.Sid.GetBinaryForm(), 0);
                string accountName = null;
                try
                {
                    accountName = thisSid.Translate(typeof(NTAccount)).Value;
                }
                catch
                { }
                Console.WriteLine($"{thisSid} {accountName ?? tokenGroup.ToString()}");
            }
        }
Exemple #14
0
		internal override Principal FindPrincipalByIdentRef(Type principalType, string urnScheme, string urnValue, DateTime referenceDate)
		{
			Principal principal;
			if (urnScheme != "ms-sid")
			{
				if (urnScheme == "ms-nt4account" || urnScheme == "ms-name")
				{
					object obj = this.FindNativeByNT4IdentRef(principalType, urnValue);
					if (obj != null)
					{
						return this.GetAsPrincipal(obj, null);
					}
					else
					{
						return null;
					}
				}
				else
				{
					if (urnScheme != null)
					{
						throw new ArgumentException(StringResources.StoreCtxUnsupportedIdentityClaimForQuery);
					}
					else
					{
						object obj1 = null;
						object obj2 = null;
						byte[] numArray = null;
						try
						{
							SecurityIdentifier securityIdentifier = new SecurityIdentifier(urnValue);
							numArray = new byte[securityIdentifier.BinaryLength];
							securityIdentifier.GetBinaryForm(numArray, 0);
						}
						catch (ArgumentException argumentException)
						{
						}
						if (numArray != null)
						{
							if (principalType == typeof(Principal) || principalType == typeof(GroupPrincipal) || principalType.IsSubclassOf(typeof(GroupPrincipal)))
							{
								IntPtr zero = IntPtr.Zero;
								try
								{
									zero = Utils.ConvertByteArrayToIntPtr(numArray);
									if (UnsafeNativeMethods.IsValidSid(zero) && Utils.ClassifySID(zero) == SidType.FakeObject)
									{
										principal = this.ConstructFakePrincipalFromSID(numArray);
										return principal;
									}
								}
								finally
								{
									if (zero != IntPtr.Zero)
									{
										Marshal.FreeHGlobal(zero);
									}
								}
							}
							obj1 = this.FindNativeBySIDIdentRef(principalType, numArray);
						}
						try
						{
							obj2 = this.FindNativeByNT4IdentRef(principalType, urnValue);
						}
						catch (ArgumentException argumentException1)
						{
						}
						if (obj1 == null || obj2 == null)
						{
							if (obj1 != null)
							{
								return this.GetAsPrincipal(obj1, null);
							}
							else
							{
								if (obj2 != null)
								{
									return this.GetAsPrincipal(obj2, null);
								}
								else
								{
									return null;
								}
							}
						}
						else
						{
							throw new MultipleMatchesException(StringResources.MultipleMatchingPrincipals);
						}
					}
				}
			}
			else
			{
				SecurityIdentifier securityIdentifier1 = new SecurityIdentifier(urnValue);
				byte[] numArray1 = new byte[securityIdentifier1.BinaryLength];
				securityIdentifier1.GetBinaryForm(numArray1, 0);
				if (numArray1 != null)
				{
					IntPtr intPtr = IntPtr.Zero;
					try
					{
						intPtr = Utils.ConvertByteArrayToIntPtr(numArray1);
						if (UnsafeNativeMethods.IsValidSid(intPtr) && Utils.ClassifySID(intPtr) == SidType.FakeObject)
						{
							principal = this.ConstructFakePrincipalFromSID(numArray1);
							return principal;
						}
					}
					finally
					{
						if (intPtr != IntPtr.Zero)
						{
							Marshal.FreeHGlobal(intPtr);
						}
					}
					object obj3 = this.FindNativeBySIDIdentRef(principalType, numArray1);
					if (obj3 != null)
					{
						return this.GetAsPrincipal(obj3, null);
					}
					else
					{
						return null;
					}
				}
				else
				{
					throw new ArgumentException(StringResources.StoreCtxSecurityIdentityClaimBadFormat);
				}
			}
			return principal;
		}
Exemple #15
0
        // Get groups of which p is a direct member
        internal override ResultSet GetGroupsMemberOf(Principal p)
        {
            // Enforced by the methods that call us
            Debug.Assert(p.unpersisted == false);

            if (!p.fakePrincipal)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf: is real principal");

                // No nested groups or computers as members of groups in SAM
                if (!(p is UserPrincipal))
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "GetGroupsMemberOf: not a user, returning empty set");
                    return(new EmptySet());
                }

                Debug.Assert(p.UnderlyingObject != null);

                DirectoryEntry userDE = (DirectoryEntry)p.UnderlyingObject;

                UnsafeNativeMethods.IADsMembers iadsMembers = (UnsafeNativeMethods.IADsMembers)userDE.Invoke("Groups");

                ResultSet resultSet = new SAMGroupsSet(iadsMembers, this, _ctxBase);
                return(resultSet);
            }
            else
            {
                // ADSI's IADsGroups doesn't work for fake principals like NT AUTHORITY\NETWORK SERVICE

                // We use the same SAMQuery set that we use for query-by-example, but with a different
                // SAMMatcher class to match groups which contain the specified principal as a member

                // Get the entries we'll iterate over.  Write access to Children is controlled through the
                // ctxBaseLock, but we don't want to have to hold that lock while we're iterating over all
                // the child entries.  So we have to clone the ctxBase --- not ideal, but it prevents
                // multithreading issues.
                DirectoryEntries entries = SDSUtils.BuildDirectoryEntry(_ctxBase.Path, _credentials, _authTypes).Children;
                Debug.Assert(entries != null);

                // The SAMQuerySet will use this to restrict the types of DirectoryEntry objects returned.
                List <string> schemaTypes = GetSchemaFilter(typeof(GroupPrincipal));

                SecurityIdentifier principalSid = p.Sid;
                byte[]             SidB         = new byte[principalSid.BinaryLength];
                principalSid.GetBinaryForm(SidB, 0);

                if (principalSid == null)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "SAMStoreCtx", "GetGroupsMemberOf: bad SID IC");
                    throw new InvalidOperationException(SR.StoreCtxNeedValueSecurityIdentityClaimToQuery);
                }

                // Create the ResultSet that will perform the client-side filtering
                SAMQuerySet resultSet = new SAMQuerySet(
                    schemaTypes,
                    entries,
                    _ctxBase,
                    -1,                                             // no size limit
                    this,
                    new GroupMemberMatcher(SidB));

                return(resultSet);
            }
        }
Exemple #16
0
        public void UnsafeLogEvent(TraceEventType type, ushort eventLogCategory, uint eventId, bool shouldTrace, params string[] values)
        {
            if (EventLogger.logCountForPT < 5)
            {
                try
                {
                    int      length    = 0;
                    string[] strArrays = new string[(int)values.Length + 2];
                    for (int i = 0; i < (int)values.Length; i++)
                    {
                        string str = values[i];
                        str          = (string.IsNullOrEmpty(str) ? string.Empty : EventLogger.NormalizeEventLogParameter(str));
                        strArrays[i] = str;
                        length       = length + str.Length + 1;
                    }
                    string str1 = EventLogger.NormalizeEventLogParameter(EventLogger.UnsafeGetProcessName());
                    strArrays[(int)strArrays.Length - 2] = str1;
                    length = length + str1.Length + 1;
                    string str2 = EventLogger.UnsafeGetProcessId().ToString(CultureInfo.InvariantCulture);
                    strArrays[(int)strArrays.Length - 1] = str2;
                    length = length + str2.Length + 1;
                    if (length > 25600)
                    {
                        int num = 25600 / (int)strArrays.Length - 1;
                        for (int j = 0; j < (int)strArrays.Length; j++)
                        {
                            if (strArrays[j].Length > num)
                            {
                                strArrays[j] = strArrays[j].Substring(0, num);
                            }
                        }
                    }
                    SecurityIdentifier user     = WindowsIdentity.GetCurrent().User;
                    byte[]             numArray = new byte[user.BinaryLength];
                    user.GetBinaryForm(numArray, 0);
                    IntPtr[]   intPtrArray   = new IntPtr[(int)strArrays.Length];
                    GCHandle   gCHandle      = new GCHandle();
                    GCHandle[] gCHandleArray = null;
                    try
                    {
                        gCHandle      = GCHandle.Alloc(intPtrArray, GCHandleType.Pinned);
                        gCHandleArray = new GCHandle[(int)strArrays.Length];
                        for (int k = 0; k < (int)strArrays.Length; k++)
                        {
                            gCHandleArray[k] = GCHandle.Alloc(strArrays[k], GCHandleType.Pinned);
                            intPtrArray[k]   = gCHandleArray[k].AddrOfPinnedObject();
                        }
                        this.UnsafeWriteEventLog(type, eventLogCategory, eventId, strArrays, numArray, gCHandle);
                    }
                    finally
                    {
                        if (gCHandle.AddrOfPinnedObject() != IntPtr.Zero)
                        {
                            gCHandle.Free();
                        }
                        if (gCHandleArray != null)
                        {
                            GCHandle[] gCHandleArray1 = gCHandleArray;
                            for (int l = 0; l < (int)gCHandleArray1.Length; l++)
                            {
                                gCHandleArray1[l].Free();
                            }
                        }
                    }
                    if (shouldTrace && this.diagnosticTrace != null && (TraceCore.TraceCodeEventLogCriticalIsEnabled(this.diagnosticTrace) || TraceCore.TraceCodeEventLogVerboseIsEnabled(this.diagnosticTrace) || TraceCore.TraceCodeEventLogInfoIsEnabled(this.diagnosticTrace) || TraceCore.TraceCodeEventLogWarningIsEnabled(this.diagnosticTrace) || TraceCore.TraceCodeEventLogErrorIsEnabled(this.diagnosticTrace)))
                    {
                        Dictionary <string, string> strs = new Dictionary <string, string>((int)strArrays.Length + 4);
                        strs["CategoryID.Name"]  = "EventLogCategory";
                        strs["CategoryID.Value"] = eventLogCategory.ToString(CultureInfo.InvariantCulture);
                        strs["InstanceID.Name"]  = "EventId";
                        strs["InstanceID.Value"] = eventId.ToString(CultureInfo.InvariantCulture);
                        for (int m = 0; m < (int)values.Length; m++)
                        {
                            strs.Add(string.Concat("Value", m.ToString(CultureInfo.InvariantCulture)), (values[m] == null ? string.Empty : DiagnosticTrace.XmlEncode(values[m])));
                        }
                        TraceRecord    dictionaryTraceRecord = new DictionaryTraceRecord(strs);
                        TraceEventType traceEventType        = type;
                        switch (traceEventType)
                        {
                        case TraceEventType.Critical:
                        {
                            TraceCore.TraceCodeEventLogCritical(this.diagnosticTrace, dictionaryTraceRecord);
                            break;
                        }

                        case TraceEventType.Error:
                        {
                            TraceCore.TraceCodeEventLogError(this.diagnosticTrace, dictionaryTraceRecord);
                            break;
                        }

                        case TraceEventType.Critical | TraceEventType.Error:
                        {
                            break;
                        }

                        case TraceEventType.Warning:
                        {
                            TraceCore.TraceCodeEventLogWarning(this.diagnosticTrace, dictionaryTraceRecord);
                            break;
                        }

                        default:
                        {
                            if (traceEventType == TraceEventType.Information)
                            {
                                TraceCore.TraceCodeEventLogInfo(this.diagnosticTrace, dictionaryTraceRecord);
                                break;
                            }
                            else if (traceEventType == TraceEventType.Verbose)
                            {
                                TraceCore.TraceCodeEventLogVerbose(this.diagnosticTrace, dictionaryTraceRecord);
                                break;
                            }
                            else
                            {
                                break;
                            }
                        }
                        }
                    }
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }
                }
                if (this.isInPartialTrust)
                {
                    EventLogger.logCountForPT = EventLogger.logCountForPT + 1;
                }
            }
        }
Exemple #17
0
            static uint GetEffectiveRights(SE_OBJECT_TYPE type, String name, String sidString)
            {
                SecurityIdentifier sid = new SecurityIdentifier(sidString);

                IntPtr pOwner = IntPtr.Zero; // pSID
                IntPtr pGroup = IntPtr.Zero; // pSID
                IntPtr pSacl = IntPtr.Zero;
                IntPtr pDacl = IntPtr.Zero;
                IntPtr pSD = IntPtr.Zero; // pSECURITY_DESCRIPTOR
                uint result = GetNamedSecurityInfo(name, type, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out pOwner,
                           out pGroup, out pDacl, out pSacl, out pSD);
                if (result != 0) {
                throw new System.ComponentModel.Win32Exception((int)result);
                }

                byte[] sidBuffer = new byte[sid.BinaryLength];
                sid.GetBinaryForm(sidBuffer, 0);

                TRUSTEE t = new TRUSTEE();
                BuildTrusteeWithSid(ref t, sidBuffer);

                uint access = 0;
                uint hr = GetEffectiveRightsFromAcl(pDacl, ref t, ref access);
                int i = Marshal.Release(t.ptstrName);

                return access;
            }
Exemple #18
0
        public void UnsafeLogEvent(TraceEventType type, ushort eventLogCategory, uint eventId, bool shouldTrace, params string[] values)
        {
            if (logCountForPT < MaxEventLogsInPT)
            {
                try
                {
                    // Vista introduces a new limitation:  a much smaller max
                    // event log entry size that we need to track.  All strings cannot
                    // exceed 31839 characters in length when totalled together.
                    // Choose a max length of 25600 characters (25k) to allow for
                    // buffer since this max length may be reduced without warning.
                    const int MaxEventLogEntryLength = 25600;

                    int eventLogEntryLength = 0;

                    string[] logValues = new string[values.Length + 2];
                    for (int i = 0; i < values.Length; ++i)
                    {
                        string stringValue = values[i];
                        if (!string.IsNullOrEmpty(stringValue))
                        {
                            stringValue = NormalizeEventLogParameter(stringValue);
                        }
                        else
                        {
                            stringValue = String.Empty;
                        }

                        logValues[i]         = stringValue;
                        eventLogEntryLength += stringValue.Length + 1;
                    }

                    string normalizedProcessName = NormalizeEventLogParameter(UnsafeGetProcessName());
                    logValues[logValues.Length - 2] = normalizedProcessName;
                    eventLogEntryLength            += (normalizedProcessName.Length + 1);

                    string invariantProcessId = UnsafeGetProcessId().ToString(CultureInfo.InvariantCulture);
                    logValues[logValues.Length - 1] = invariantProcessId;
                    eventLogEntryLength            += (invariantProcessId.Length + 1);

                    // If current event log entry length is greater than max length
                    // need to truncate to max length.  This probably means that we
                    // have a very long exception and stack trace in our parameter
                    // strings.  Truncate each string by MaxEventLogEntryLength
                    // divided by number of strings in the entry.
                    // Truncation algorithm is overly aggressive by design to
                    // simplify the code change due to Product Cycle timing.
                    if (eventLogEntryLength > MaxEventLogEntryLength)
                    {
                        // logValues.Length is always > 0 (minimum value = 2)
                        // Subtract one to insure string ends in '\0'
                        int truncationLength = (MaxEventLogEntryLength / logValues.Length) - 1;

                        for (int i = 0; i < logValues.Length; i++)
                        {
                            if (logValues[i].Length > truncationLength)
                            {
                                logValues[i] = logValues[i].Substring(0, truncationLength);
                            }
                        }
                    }

                    SecurityIdentifier sid   = WindowsIdentity.GetCurrent().User;
                    byte[]             sidBA = new byte[sid.BinaryLength];
                    sid.GetBinaryForm(sidBA, 0);
                    IntPtr[]   stringRoots       = new IntPtr[logValues.Length];
                    GCHandle   stringsRootHandle = new GCHandle();
                    GCHandle[] stringHandles     = null;

                    try
                    {
                        stringsRootHandle = GCHandle.Alloc(stringRoots, GCHandleType.Pinned);
                        stringHandles     = new GCHandle[logValues.Length];
                        for (int strIndex = 0; strIndex < logValues.Length; strIndex++)
                        {
                            stringHandles[strIndex] = GCHandle.Alloc(logValues[strIndex], GCHandleType.Pinned);
                            stringRoots[strIndex]   = stringHandles[strIndex].AddrOfPinnedObject();
                        }
                        UnsafeWriteEventLog(type, eventLogCategory, eventId, logValues, sidBA, stringsRootHandle);
                    }
                    finally
                    {
                        if (stringsRootHandle.AddrOfPinnedObject() != IntPtr.Zero)
                        {
                            stringsRootHandle.Free();
                        }
                        if (stringHandles != null)
                        {
                            foreach (GCHandle gcHandle in stringHandles)
                            {
                                if (gcHandle != null)
                                {
                                    gcHandle.Free();
                                }
                            }
                        }
                    }

                    /*
                     * if (shouldTrace && this.diagnosticTrace != null
                     *  && (TraceCore.TraceCodeEventLogCriticalIsEnabled(this.diagnosticTrace)
                     || TraceCore.TraceCodeEventLogVerboseIsEnabled(this.diagnosticTrace)
                     || TraceCore.TraceCodeEventLogInfoIsEnabled(this.diagnosticTrace)
                     || TraceCore.TraceCodeEventLogWarningIsEnabled(this.diagnosticTrace)
                     || TraceCore.TraceCodeEventLogErrorIsEnabled(this.diagnosticTrace)))
                     ||{
                     || const int RequiredValueCount = 4;
                     || Dictionary<string, string> eventValues = new Dictionary<string, string>(logValues.Length + RequiredValueCount);
                     || eventValues["CategoryID.Name"] = "EventLogCategory";
                     || eventValues["CategoryID.Value"] = eventLogCategory.ToString(CultureInfo.InvariantCulture);
                     || eventValues["InstanceID.Name"] = "EventId";
                     || eventValues["InstanceID.Value"] = eventId.ToString(CultureInfo.InvariantCulture);
                     || for (int i = 0; i < values.Length; ++i)
                     || {
                     ||     eventValues.Add("Value" + i.ToString(CultureInfo.InvariantCulture), values[i] == null ? string.Empty : DiagnosticTrace.XmlEncode(values[i]));
                     || }
                     ||
                     || TraceRecord traceRecord = new DictionaryTraceRecord((eventValues));
                     || switch(type)
                     || {
                     ||     case TraceEventType.Critical:
                     ||             TraceCore.TraceCodeEventLogCritical(this.diagnosticTrace, traceRecord);
                     ||             break;
                     ||
                     ||     case TraceEventType.Verbose:
                     ||             TraceCore.TraceCodeEventLogVerbose(this.diagnosticTrace, traceRecord);
                     ||             break;
                     ||
                     ||     case TraceEventType.Information:
                     ||             TraceCore.TraceCodeEventLogInfo(this.diagnosticTrace, traceRecord);
                     ||             break;
                     ||
                     ||     case TraceEventType.Warning:
                     ||             TraceCore.TraceCodeEventLogWarning(this.diagnosticTrace, traceRecord);
                     ||             break;
                     ||
                     ||     case TraceEventType.Error:
                     ||             TraceCore.TraceCodeEventLogError(this.diagnosticTrace, traceRecord);
                     ||             break;
                     || }
                     ||}
                     */
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }
                    // If not fatal, just eat the exception
                }
                // In PT, we only limit 5 event logging per session
                if (this.isInPartialTrust)
                {
                    logCountForPT++;
                }
            }
        }
Exemple #19
0
 private static byte[] SidToArray(SecurityIdentifier sid)
 {
     byte[] ret = new byte[sid.BinaryLength];
     sid.GetBinaryForm(ret, 0);
     return(ret);
 }
Exemple #20
0
        public static Int32 SetSecurityInfo(ResourceType type, [NotNull] String name, SecurityInfos securityInformation,
                                            [CanBeNull] SecurityIdentifier owner, [CanBeNull] SecurityIdentifier group, [CanBeNull] GenericAcl sacl, [CanBeNull] GenericAcl dacl)
        {
            name = name.ThrowIfBlank();

            if (!Enum.IsDefined(enumType: typeof(ResourceType), type))
            {
                throw new InvalidEnumArgumentException(argumentName: nameof(type), invalidValue: ( Int32 )type, enumClass: typeof(ResourceType));
            }

            if (!Enum.IsDefined(enumType: typeof(SecurityInfos), securityInformation))
            {
                throw new InvalidEnumArgumentException(argumentName: nameof(securityInformation), invalidValue: ( Int32 )securityInformation,
                                                       enumClass: typeof(SecurityInfos));
            }

            Int32 errorCode;
            Int32 Length;

            Byte[]    OwnerBinary       = null, GroupBinary = null, SaclBinary = null, DaclBinary = null;
            Privilege securityPrivilege = null;

            // Demand unmanaged code permission
            // The integrator layer is free to assert this permission and, in turn, demand another permission of its caller

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

            if (owner != null)
            {
                Length      = owner.BinaryLength;
                OwnerBinary = new Byte[Length];
                owner.GetBinaryForm(OwnerBinary, 0);
            }

            if (group != null)
            {
                Length      = group.BinaryLength;
                GroupBinary = new Byte[Length];
                group.GetBinaryForm(GroupBinary, 0);
            }

            if (dacl != null)
            {
                Length     = dacl.BinaryLength;
                DaclBinary = new Byte[Length];
                dacl.GetBinaryForm(DaclBinary, 0);
            }

            if (sacl != null)
            {
                Length     = sacl.BinaryLength;
                SaclBinary = new Byte[Length];
                sacl.GetBinaryForm(SaclBinary, 0);
            }

            if ((securityInformation & SecurityInfos.SystemAcl) != 0)
            {
                // Enable security privilege if trying to set a SACL.
                // Note: even setting it by handle needs this privilege enabled!

                securityPrivilege = new Privilege(Privilege.Security);
            }

            // Ensure that the finally block will execute
            RuntimeHelpers.PrepareConstrainedRegions();

            try {
                if (securityPrivilege != null)
                {
                    try {
                        securityPrivilege.Enable();
                    }
                    catch (PrivilegeNotHeldException) {
                        // we will ignore this exception and press on just in case this is a remote resource
                    }
                }

                errorCode = ( Int32 )NativeMethods.SetSecurityInfoByName(name, ( UInt32 )type, ( UInt32 )securityInformation, OwnerBinary, GroupBinary, DaclBinary,
                                                                         SaclBinary);

                switch (errorCode)
                {
                case NativeMethods.ERROR_NOT_ALL_ASSIGNED:
                case NativeMethods.ERROR_PRIVILEGE_NOT_HELD:

                    throw new PrivilegeNotHeldException(Privilege.Security);

                case NativeMethods.ERROR_ACCESS_DENIED:
                case NativeMethods.ERROR_CANT_OPEN_ANONYMOUS:

                    throw new UnauthorizedAccessException();
                }

                if (errorCode != NativeMethods.ERROR_SUCCESS)
                {
                    goto Error;
                }
            }
            catch {
                // protection against exception filter-based luring attacks
                securityPrivilege?.Revert();

                throw;
            }
            finally {
                securityPrivilege?.Revert();
            }

            return(0);

Error:

            if (errorCode == NativeMethods.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }

            return(errorCode);
        }
Exemple #21
0
        public static void HandleCreateTask(Packets.ServerPackets.DoCreateTask command, Client client)
        {
            if (WindowsAccountHelper.GetAccountType() != "Admin")
            {
                new Packets.ClientPackets.SetStatus("Failed to create task: must be administrator.").Execute(client);
                return;
            }

            var          name    = new StringBuilder();
            var          cchName = (uint)name.Capacity;
            var          referencedDomainName    = new StringBuilder();
            var          cchReferencedDomainName = (uint)referencedDomainName.Capacity;
            SID_NAME_USE sidUse;

            var sid     = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
            var sidBuff = new byte[sid.BinaryLength];

            sid.GetBinaryForm(sidBuff, 0);

            if (!LookupAccountSid(null, sidBuff, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))
            {
                var err = Marshal.GetLastWin32Error();
                if (err == 122 /* ERROR_INSUFFICIENT_BUFFER */)
                {
                    name.EnsureCapacity((int)cchName);
                    referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
                    if (!LookupAccountSid(null, sidBuff, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))
                    {
                        new Packets.ClientPackets.SetStatus(string.Format("Failed to create task with code: {0}.", Marshal.GetLastWin32Error())).Execute(client);
                        return;
                    }
                }
            }

            try
            {
                // If we're on Windows XP we need to use the Task Scheduler 1.0 interface
                if (PlatformHelper.XpOrHigher && !PlatformHelper.VistaOrHigher)
                {
                    var sched = new LegacyTS.CTaskScheduler() as LegacyTS.ITaskScheduler;

                    if (sched == null)
                    {
                        new Packets.ClientPackets.SetStatus("Failed to create task.").Execute(client);
                        return;
                    }

                    var    taskGuid  = Marshal.GenerateGuidForType(typeof(LegacyTS.ITask));
                    var    cTaskGuid = Marshal.GenerateGuidForType(typeof(LegacyTS.CTask));
                    object taskObj;
                    sched.NewWorkItem(command.TaskName, ref cTaskGuid, ref taskGuid, out taskObj);
                    var task = (LegacyTS.ITask)taskObj;

                    task.SetApplicationName(
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Tasks") +
                        "\\sys.bat");
                    task.SetParameters(command.Arguments ?? "");
                    task.SetComment("");
                    task.SetCreator(name.ToString());
                    task.SetWorkingDirectory("");

                    var pwd = Marshal.StringToCoTaskMemUni(null);
                    task.SetAccountInformation("", pwd);
                    Marshal.FreeCoTaskMem(pwd);
                    task.SetIdleWait(10, 20);
                    task.SetMaxRunTime((uint)new TimeSpan(1, 0, 0).TotalMilliseconds);
                    task.SetPriority((uint)ProcessPriorityClass.High);

                    ushort triggerIdx;
                    LegacyTS.ITaskTrigger iTrigger;
                    task.CreateTrigger(out triggerIdx, out iTrigger);

                    // Boot trigger
                    var trigger = new LegacyTS.TaskTrigger();
                    iTrigger.GetTrigger(ref trigger);
                    trigger.Type        = LegacyTS.TaskTriggerType.EVENT_TRIGGER_AT_SYSTEMSTART;
                    trigger.TriggerSize = (ushort)Marshal.SizeOf(trigger);
                    trigger.BeginYear   = (ushort)DateTime.Today.Year;
                    trigger.BeginMonth  = (ushort)DateTime.Today.Month;
                    trigger.BeginDay    = (ushort)DateTime.Today.Day;
                    // Remove "Disabled" flag
                    trigger.Flags &= ~(uint)0x4 /* TASK_TRIGGER_FLAG.DISABLED */;

                    iTrigger.SetTrigger(ref trigger);
                    task.CreateTrigger(out triggerIdx, out iTrigger);

                    // Logon trigger
                    trigger = new LegacyTS.TaskTrigger();
                    iTrigger.GetTrigger(ref trigger);
                    trigger.Type        = LegacyTS.TaskTriggerType.EVENT_TRIGGER_AT_LOGON;
                    trigger.TriggerSize = (ushort)Marshal.SizeOf(trigger);
                    trigger.BeginYear   = (ushort)DateTime.Today.Year;
                    trigger.BeginMonth  = (ushort)DateTime.Today.Month;
                    trigger.BeginDay    = (ushort)DateTime.Today.Day;
                    // Remove "Disabled" flag
                    trigger.Flags &= ~(uint)0x4 /* TASK_TRIGGER_FLAG.DISABLED */;

                    iTrigger.SetTrigger(ref trigger);

                    var iFile = (IPersistFile)task;
                    iFile.Save(null, false);

                    // Create a small batch file to delay
                    File.WriteAllText(
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Tasks") +
                        "\\sys.bat",
                        string.Format("ping 127.0.0.1 -n 180 > nul{0}start\"{1}\"", Environment.NewLine, command.Path));
                }
                // Else we use Task Scheduler 2.0
                else if (PlatformHelper.VistaOrHigher)
                {
                    var sched = new TaskScheduler();
                    sched.Connect();

                    if (!sched.Connected)
                    {
                        new Packets.ClientPackets.SetStatus("Failed to create task.").Execute(client);
                        return;
                    }

                    var folder = sched.GetFolder("\\");
                    var task   = sched.NewTask(0);
                    task.RegistrationInfo.Author = "SYSTEM";
                    task.Principal.RunLevel      = TaskRunLevel.Highest;

                    task.Settings.StartWhenAvailable         = true;
                    task.Settings.DisallowStartIfOnBatteries = false;
                    task.Settings.StopIfGoingOnBatteries     = false;
                    task.Settings.ExecutionTimeLimit         = "PT0S";
                    task.Settings.Hidden = true;

                    task.Principal.UserId = name.ToString();

                    task.Triggers.Create(TaskTriggerType.Logon);
                    var bootTrigger = (IBootTrigger)task.Triggers.Create(TaskTriggerType.Boot);
                    var execAction  = (IExecAction)task.Actions.Create(TaskActionType.Execute);

                    bootTrigger.Id    = "AnyLogon";
                    bootTrigger.Delay = "PT1M";
                    bootTrigger.Repetition.Interval          = "PT1M";
                    bootTrigger.Repetition.Duration          = "PT13M";
                    bootTrigger.Repetition.StopAtDurationEnd = true;

                    execAction.Path      = command.Path ?? "";
                    execAction.Arguments = command.Arguments;

                    folder.RegisterTaskDefinition(command.TaskName, task, 6 /* TASK_CREATE_OR_UPDATE */, null, null,
                                                  TaskLogonType.InteractiveTokenOrPassword);
                }
            }
            catch (COMException e)
            {
                new Packets.ClientPackets.SetStatus(string.Format("Failed to create task with code: {0}.", e.ErrorCode))
                .Execute(client);
                return;
            }
            catch
            {
                new Packets.ClientPackets.SetStatus("Failed to create task.").Execute(client);
                return;
            }
            new Packets.ClientPackets.SetStatus("Created task.").Execute(client);
        }
        /// <summary>
        /// Provide access and overriding of accaunt rights in LSA.
        /// </summary>
        /// <param name="sid"></param>
        /// <param name="rights"></param>
        /// <param name="allow"></param>
        private static void AccountRightsController(SecurityIdentifier sid, string rights, bool allow)
        {
            LSA_UNICODE_STRING[] system = null;

            // A pointer to an LSA_OBJECT_ATTRIBUTES structure that specifies the connection attributes.
            // The structure members are not used; initialize them to NULL or zero.
            LSA_OBJECT_ATTRIBUTES lsaAttr = new LSA_OBJECT_ATTRIBUTES()
            {
                RootDirectory            = IntPtr.Zero,
                ObjectName               = IntPtr.Zero,
                Attributes               = 0,
                SecurityDescriptor       = IntPtr.Zero,
                SecurityQualityOfService = IntPtr.Zero,
                Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES))
            };

            // Open access to LSA with access to policy.
            uint ret = NativeMethods.LsaOpenPolicy(system, ref lsaAttr, (int)Access.POLICY_ALL_ACCESS, out IntPtr lsaHandle);

            if (ret == 0)
            {
                // Get SID.
                Byte[] buffer = new Byte[sid.BinaryLength];
                sid.GetBinaryForm(buffer, 0);

                // Allocate memory.
                IntPtr pSid = Marshal.AllocHGlobal(sid.BinaryLength);
                Marshal.Copy(buffer, 0, pSid, sid.BinaryLength);


                LSA_UNICODE_STRING lsaRights = new LSA_UNICODE_STRING
                {
                    Buffer = rights,
                    Length = (ushort)(rights.Length * sizeof(char))
                };
                lsaRights.MaximumLength = (ushort)(lsaRights.Length + sizeof(char));

                LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
                privileges[0] = lsaRights;

                if (allow)
                {
                    // Add rights.
                    ret = NativeMethods.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
                }
                else
                {
                    // Remove rights.
                    ret = NativeMethods.LsaRemoveAccountRights(lsaHandle, pSid, false, privileges, 1);
                }

                // Close access to LSA.
                NativeMethods.LsaClose(lsaHandle);

                // Free unmanged memory.
                Marshal.FreeHGlobal(pSid);

                if (ret != 0)
                {
                    throw new Win32Exception("LsaAddAccountRights failed with error code: " + ret);
                }
            }
            else
            {
                throw new Win32Exception("LsaOpenPolicy failed with error code: " + ret);
            }
        }
Exemple #23
0
 internal void UnsafeLogEvent(TraceEventType type, EventLogCategory category, System.ServiceModel.Diagnostics.EventLogEventId eventId, bool shouldTrace, params string[] values)
 {
     if (logCountForPT < 5)
     {
         try
         {
             int      num       = 0;
             string[] logValues = new string[values.Length + 2];
             for (int i = 0; i < values.Length; i++)
             {
                 string str = values[i];
                 if (!string.IsNullOrEmpty(str))
                 {
                     str = NormalizeEventLogParameter(str);
                 }
                 else
                 {
                     str = string.Empty;
                 }
                 logValues[i] = str;
                 num         += str.Length + 1;
             }
             string str2 = NormalizeEventLogParameter(this.UnsafeGetProcessName());
             logValues[logValues.Length - 2] = str2;
             num += str2.Length + 1;
             string str3 = this.UnsafeGetProcessId().ToString(CultureInfo.InvariantCulture);
             logValues[logValues.Length - 1] = str3;
             num += str3.Length + 1;
             if (num > 0x6400)
             {
                 int length = (0x6400 / logValues.Length) - 1;
                 for (int j = 0; j < logValues.Length; j++)
                 {
                     if (logValues[j].Length > length)
                     {
                         logValues[j] = logValues[j].Substring(0, length);
                     }
                 }
             }
             SecurityIdentifier user       = WindowsIdentity.GetCurrent().User;
             byte[]             binaryForm = new byte[user.BinaryLength];
             user.GetBinaryForm(binaryForm, 0);
             IntPtr[]   ptrArray          = new IntPtr[logValues.Length];
             GCHandle   stringsRootHandle = new GCHandle();
             GCHandle[] handleArray       = null;
             try
             {
                 stringsRootHandle = GCHandle.Alloc(ptrArray, GCHandleType.Pinned);
                 handleArray       = new GCHandle[logValues.Length];
                 for (int k = 0; k < logValues.Length; k++)
                 {
                     handleArray[k] = GCHandle.Alloc(logValues[k], GCHandleType.Pinned);
                     ptrArray[k]    = handleArray[k].AddrOfPinnedObject();
                 }
                 this.UnsafeWriteEventLog(type, category, eventId, logValues, binaryForm, stringsRootHandle);
             }
             finally
             {
                 if (stringsRootHandle.AddrOfPinnedObject() != IntPtr.Zero)
                 {
                     stringsRootHandle.Free();
                 }
                 if (handleArray != null)
                 {
                     foreach (GCHandle handle2 in handleArray)
                     {
                         handle2.Free();
                     }
                 }
             }
             if (shouldTrace && (this.diagnosticTrace != null))
             {
                 Dictionary <string, string> dictionary = new Dictionary <string, string>(logValues.Length + 4);
                 dictionary["CategoryID.Name"]  = category.ToString();
                 dictionary["CategoryID.Value"] = ((uint)category).ToString(CultureInfo.InvariantCulture);
                 dictionary["InstanceID.Name"]  = eventId.ToString();
                 dictionary["InstanceID.Value"] = ((uint)eventId).ToString(CultureInfo.InvariantCulture);
                 for (int m = 0; m < values.Length; m++)
                 {
                     dictionary.Add("Value" + m.ToString(CultureInfo.InvariantCulture), (values[m] == null) ? string.Empty : System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(values[m]));
                 }
                 this.diagnosticTrace.TraceEvent(type, 0x20002, System.ServiceModel.Diagnostics.DiagnosticTrace.GenerateMsdnTraceCode("System.ServiceModel.Diagnostics", "EventLog"), TraceSR.GetString("TraceCodeEventLog"), new DictionaryTraceRecord(dictionary), null, null);
             }
         }
         catch (Exception exception)
         {
             if (Fx.IsFatal(exception))
             {
                 throw;
             }
         }
         if (this.isInPatialTrust)
         {
             logCountForPT++;
         }
     }
 }
        internal static int SetSecurityInfo(ResourceType type, string name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
        {
            byte[]    array     = null;
            byte[]    array2    = null;
            byte[]    array3    = null;
            byte[]    array4    = null;
            Privilege privilege = null;

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
            if (owner != null)
            {
                int binaryLength = owner.BinaryLength;
                array = new byte[binaryLength];
                owner.GetBinaryForm(array, 0);
            }
            if (group != null)
            {
                int binaryLength = group.BinaryLength;
                array2 = new byte[binaryLength];
                group.GetBinaryForm(array2, 0);
            }
            if (dacl != null)
            {
                int binaryLength = dacl.BinaryLength;
                array4 = new byte[binaryLength];
                dacl.GetBinaryForm(array4, 0);
            }
            if (sacl != null)
            {
                int binaryLength = sacl.BinaryLength;
                array3 = new byte[binaryLength];
                sacl.GetBinaryForm(array3, 0);
            }
            if ((securityInformation & SecurityInfos.SystemAcl) != (SecurityInfos)0)
            {
                privilege = new Privilege("SeSecurityPrivilege");
            }
            RuntimeHelpers.PrepareConstrainedRegions();
            int num;

            try
            {
                if (privilege != null)
                {
                    try
                    {
                        privilege.Enable();
                    }
                    catch (PrivilegeNotHeldException)
                    {
                    }
                }
                if (name != null)
                {
                    num = (int)Win32Native.SetSecurityInfoByName(name, (uint)type, (uint)securityInformation, array, array2, array4, array3);
                }
                else
                {
                    if (handle == null)
                    {
                        throw new InvalidProgramException();
                    }
                    if (handle.IsInvalid)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeHandle"), "handle");
                    }
                    num = (int)Win32Native.SetSecurityInfoByHandle(handle, (uint)type, (uint)securityInformation, array, array2, array4, array3);
                }
                if (num == 1300 || num == 1314)
                {
                    throw new PrivilegeNotHeldException("SeSecurityPrivilege");
                }
                if (num == 5 || num == 1347)
                {
                    throw new UnauthorizedAccessException();
                }
                if (num != 0)
                {
                    goto IL_159;
                }
            }
            catch
            {
                if (privilege != null)
                {
                    privilege.Revert();
                }
                throw;
            }
            finally
            {
                if (privilege != null)
                {
                    privilege.Revert();
                }
            }
            return(0);

IL_159:
            if (num == 8)
            {
                throw new OutOfMemoryException();
            }
            return(num);
        }
Exemple #25
0
 static void WriteSidAttribute(SecurityIdentifier sid, SctClaimDictionary dictionary, XmlDictionaryWriter writer)
 {
     byte[] sidBytes = new byte[sid.BinaryLength];
     sid.GetBinaryForm(sidBytes, 0);
     writer.WriteAttributeString(dictionary.Sid, dictionary.EmptyString, Convert.ToBase64String(sidBytes));
 }
        public static string GetUserFromSid(string sidString)
        {
            // stolen wholesale from http://www.pinvoke.net/default.aspx/advapi32.LookupAccountSid

            StringBuilder name    = new StringBuilder();
            uint          cchName = (uint)name.Capacity;
            StringBuilder referencedDomainName    = new StringBuilder();
            uint          cchReferencedDomainName = (uint)referencedDomainName.Capacity;
            SID_NAME_USE  sidUse;
            int           err = 0;

            try
            {
                SecurityIdentifier sidObj   = new SecurityIdentifier(sidString);
                byte[]             sidBytes = new byte[sidObj.BinaryLength];
                sidObj.GetBinaryForm(sidBytes, 0);
                err = NO_ERROR;

                if (!LookupAccountSid(null, sidBytes, name, ref cchName, referencedDomainName,
                                      ref cchReferencedDomainName,
                                      out sidUse))
                {
                    err = Marshal.GetLastWin32Error();
                    if (err == ERROR_INSUFFICIENT_BUFFER)
                    {
                        name.EnsureCapacity((int)cchName);
                        referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
                        err = NO_ERROR;
                        if (!LookupAccountSid(null, sidBytes, name, ref cchName, referencedDomainName,
                                              ref cchReferencedDomainName, out sidUse))
                        {
                            err = Marshal.GetLastWin32Error();
                        }
                    }
                }
            }
            catch (System.ArgumentException)
            {
                return("SID Lookup Failed");
            }

            string lookupResult = "";

            if (err != 0)
            {
                Utility.Output.DebugWrite(@"Error in SID Lookup : " + err + " resolving SID " + sidString + " handing off to well known sids list.");

                try
                {
                    lookupResult = Utility.Sid.GetWellKnownSid(sidString);
                }
                catch (Exception e)
                {
                    lookupResult = "SID Lookup Failed";
                    Utility.Output.DebugWrite(e.ToString());
                }

                return(lookupResult);
            }

            if (referencedDomainName.ToString().Length > 0)
            {
                lookupResult = referencedDomainName.ToString() + "\\" + name.ToString();
            }
            else
            {
                lookupResult = name.ToString();
            }

            return(lookupResult);
        }
Exemple #27
0
        //
        // Wrapper around advapi32.SetNamedSecurityInfoW and advapi32.SetSecurityInfo
        //

        internal static int SetSecurityInfo(
            ResourceType type,
            string name,
            SafeHandle handle,
            SecurityInfos securityInformation,
            SecurityIdentifier owner,
            SecurityIdentifier group,
            GenericAcl sacl,
            GenericAcl dacl)
        {
            int errorCode;
            int Length;

            byte[]    OwnerBinary       = null, GroupBinary = null, SaclBinary = null, DaclBinary = null;
            Privilege securityPrivilege = null;

            if (owner != null)
            {
                Length      = owner.BinaryLength;
                OwnerBinary = new byte[Length];
                owner.GetBinaryForm(OwnerBinary, 0);
            }

            if (group != null)
            {
                Length      = group.BinaryLength;
                GroupBinary = new byte[Length];
                group.GetBinaryForm(GroupBinary, 0);
            }

            if (dacl != null)
            {
                Length     = dacl.BinaryLength;
                DaclBinary = new byte[Length];
                dacl.GetBinaryForm(DaclBinary, 0);
            }

            if (sacl != null)
            {
                Length     = sacl.BinaryLength;
                SaclBinary = new byte[Length];
                sacl.GetBinaryForm(SaclBinary, 0);
            }

            if ((securityInformation & SecurityInfos.SystemAcl) != 0)
            {
                //
                // Enable security privilege if trying to set a SACL.
                // Note: even setting it by handle needs this privilege enabled!
                //

                securityPrivilege = new Privilege(Privilege.Security);
            }

            try
            {
                if (securityPrivilege != null)
                {
                    try
                    {
                        securityPrivilege.Enable();
                    }
                    catch (PrivilegeNotHeldException)
                    {
                        // we will ignore this exception and press on just in case this is a remote resource
                    }
                }

                if (name != null)
                {
                    errorCode = (int)Interop.mincore.SetSecurityInfoByName(name, (uint)type, (uint)securityInformation, OwnerBinary, GroupBinary, DaclBinary, SaclBinary);
                }
                else if (handle != null)
                {
                    if (handle.IsInvalid)
                    {
                        throw new ArgumentException(
                                  SR.Argument_InvalidSafeHandle,
                                  nameof(handle));
                    }
                    else
                    {
                        errorCode = (int)Interop.mincore.SetSecurityInfoByHandle(handle, (uint)type, (uint)securityInformation, OwnerBinary, GroupBinary, DaclBinary, SaclBinary);
                    }
                }
                else
                {
                    // both are null, shouldn't happen
                    Contract.Assert(false, "Internal error: both name and handle are null");
                    throw new ArgumentException();
                }

                if (errorCode == Interop.mincore.Errors.ERROR_NOT_ALL_ASSIGNED ||
                    errorCode == Interop.mincore.Errors.ERROR_PRIVILEGE_NOT_HELD)
                {
                    throw new PrivilegeNotHeldException(Privilege.Security);
                }
                else if (errorCode == Interop.mincore.Errors.ERROR_ACCESS_DENIED ||
                         errorCode == Interop.mincore.Errors.ERROR_CANT_OPEN_ANONYMOUS)
                {
                    throw new UnauthorizedAccessException();
                }
                else if (errorCode != Interop.mincore.Errors.ERROR_SUCCESS)
                {
                    goto Error;
                }
            }
            catch
            {
                // protection against exception filter-based luring attacks
                if (securityPrivilege != null)
                {
                    securityPrivilege.Revert();
                }
                throw;
            }
            finally
            {
                if (securityPrivilege != null)
                {
                    securityPrivilege.Revert();
                }
            }

            return(0);

Error:

            if (errorCode == Interop.mincore.Errors.ERROR_NOT_ENOUGH_MEMORY)
            {
                throw new OutOfMemoryException();
            }

            return(errorCode);
        }
Exemple #28
0
        public static void AdditionalTestCases()
        {
            RawAcl     rAcl = null;
            GenericAce gAce = null;

            byte[] binaryForm = null;

            //Case 1, array binaryForm is null

            Assert.Throws <ArgumentNullException>(() =>
            {
                rAcl = new RawAcl(GenericAcl.AclRevision, 1);
                gAce = new CommonAce(AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null);
                rAcl.InsertAce(0, gAce);
                rAcl.GetBinaryForm(binaryForm, 0);
            });
            //Case 2, offset is negative

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                binaryForm = new byte[100];
                rAcl       = new RawAcl(GenericAcl.AclRevision, 1);
                gAce       = new CommonAce(AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null);
                rAcl.InsertAce(0, gAce);
                rAcl.GetBinaryForm(binaryForm, -1);
            });
            //Case 3, offset is equal to binaryForm length

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                binaryForm = new byte[100];
                rAcl       = new RawAcl(GenericAcl.AclRevision, 1);
                gAce       = new CommonAce(AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null);
                rAcl.InsertAce(0, gAce);
                rAcl.GetBinaryForm(binaryForm, binaryForm.Length);
            });
            //Case , offset is a big possitive number

            rAcl = new RawAcl(GenericAcl.AclRevision, 1);
            gAce = new CommonAce(AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null);
            rAcl.InsertAce(0, gAce);
            gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null);
            rAcl.InsertAce(0, gAce);
            binaryForm = new byte[rAcl.BinaryLength + 10000];
            rAcl.GetBinaryForm(binaryForm, 10000);
            //recreate the RawAcl from BinaryForm
            rAcl = new RawAcl(binaryForm, 10000);
            byte[] verifierBinaryForm = new byte[rAcl.BinaryLength];
            rAcl.GetBinaryForm(verifierBinaryForm, 0);
            Assert.True(Utils.IsBinaryFormEqual(binaryForm, 10000, verifierBinaryForm));

            //Case 4, binaryForm array's size is insufficient

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                binaryForm = new byte[4];
                rAcl       = new RawAcl(GenericAcl.AclRevision, 1);
                gAce       = new CommonAce(AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null);
                rAcl.InsertAce(0, gAce);
                rAcl.GetBinaryForm(binaryForm, 0);
            });

            //Case 5, an empty RawAcl

            binaryForm         = new byte[16];
            verifierBinaryForm = new byte[16];
            for (int i = 0; i < binaryForm.Length; i++)
            {
                binaryForm[i]         = (byte)0;
                verifierBinaryForm[i] = (byte)0;
            }
            rAcl = new RawAcl(GenericAcl.AclRevision, 1);
            rAcl.GetBinaryForm(binaryForm, 0);
            int errorCode;

            if (0 == Utils.Win32AclLayer.InitializeAclNative
                    (verifierBinaryForm, (uint)8, (uint)GenericAcl.AclRevision))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else
            {
                Assert.True(Utils.IsBinaryFormEqual(binaryForm, verifierBinaryForm));
            }
            //Case 6, a RawAcl with huge number of AccessAllowed, AccessDenied, and AuditAce
            SecurityIdentifier sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA"));

            verifierBinaryForm = null;
            byte[] sidBinaryForm = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidBinaryForm, 0);
            rAcl = new RawAcl(GenericAcl.AclRevision, GenericAcl.MaxBinaryLength + 1);
            for (int i = 0; i < 780; i++)
            {
                //three aces binary length together is 24 + 36 + 24 = 84, 780 * 84 = 65520
                gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, i, sid, false, null);
                rAcl.InsertAce(rAcl.Count, gAce);
                gAce = new CommonAce((AceFlags)223, AceQualifier.SystemAudit, i + 1, sid, false, null);
                rAcl.InsertAce(rAcl.Count, gAce);
                gAce = new CommonAce((AceFlags)31, AceQualifier.AccessDenied, i + 2, sid, false, null);
                rAcl.InsertAce(rAcl.Count, gAce);
            }
            binaryForm         = new byte[rAcl.BinaryLength];
            verifierBinaryForm = new byte[rAcl.BinaryLength];
            rAcl.GetBinaryForm(binaryForm, 0);

            if (0 == Utils.Win32AclLayer.InitializeAclNative
                    (verifierBinaryForm, (uint)rAcl.BinaryLength, (uint)GenericAcl.AclRevision))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else
            {
                int i = 0;
                for (i = 0; i < 780; i++)
                {
                    if (0 == Utils.Win32AclLayer.AddAccessAllowedAceExNative
                            (verifierBinaryForm, (uint)GenericAcl.AclRevision, (uint)AceFlags.None, (uint)i, sidBinaryForm))
                    {
                        errorCode = Marshal.GetLastWin32Error();
                        break;
                    }
                    if (0 == Utils.Win32AclLayer.AddAuditAccessAceExNative
                            (verifierBinaryForm, (uint)GenericAcl.AclRevision, (uint)223, (uint)(i + 1), sidBinaryForm, 1, 1))
                    {
                        errorCode = Marshal.GetLastWin32Error();
                        break;
                    }
                    if (0 == Utils.Win32AclLayer.AddAccessDeniedAceExNative
                            (verifierBinaryForm, (uint)GenericAcl.AclRevision, (uint)31, (uint)(i + 2), sidBinaryForm))
                    {
                        errorCode = Marshal.GetLastWin32Error();
                        break;
                    }
                }
                if (i == 780)
                {
                    //the loop finishes
                    Assert.True(Utils.IsBinaryFormEqual(binaryForm, verifierBinaryForm));
                }
                else
                {
                    Utils.PrintBinaryForm(binaryForm);
                    Utils.PrintBinaryForm(verifierBinaryForm);
                }
            }
        }
Exemple #29
0
        int Win32SetHelper(SetSecurityInfoNativeCall nativeCall,
                           AccessControlSections includeSections)
        {
            // SE_REGISTRY_KEY will fail UnauthorizedAccessException without this check.
            if (AccessControlSections.None == includeSections)
            {
                return(0);
            }

            SecurityInfos securityInfos = 0;

            byte[] owner = null, group = null, dacl = null, sacl = null;

            if (0 != (includeSections & AccessControlSections.Owner))
            {
                securityInfos |= SecurityInfos.Owner;
                SecurityIdentifier ownerSid = (SecurityIdentifier)GetOwner(typeof(SecurityIdentifier));
                if (null != ownerSid)
                {
                    owner = new byte[ownerSid.BinaryLength];
                    ownerSid.GetBinaryForm(owner, 0);
                }
            }

            if (0 != (includeSections & AccessControlSections.Group))
            {
                securityInfos |= SecurityInfos.Group;
                SecurityIdentifier groupSid = (SecurityIdentifier)GetGroup(typeof(SecurityIdentifier));
                if (null != groupSid)
                {
                    group = new byte[groupSid.BinaryLength];
                    groupSid.GetBinaryForm(group, 0);
                }
            }

            if (0 != (includeSections & AccessControlSections.Access))
            {
                securityInfos |= SecurityInfos.DiscretionaryAcl;
                if (AreAccessRulesProtected)
                {
                    securityInfos |= unchecked ((SecurityInfos)0x80000000);
                }
                else
                {
                    securityInfos |= (SecurityInfos)0x20000000;
                }
                dacl = new byte[descriptor.DiscretionaryAcl.BinaryLength];
                descriptor.DiscretionaryAcl.GetBinaryForm(dacl, 0);
            }

            if (0 != (includeSections & AccessControlSections.Audit))
            {
                if (null != descriptor.SystemAcl)
                {
                    securityInfos |= SecurityInfos.SystemAcl;
                    if (AreAuditRulesProtected)
                    {
                        securityInfos |= (SecurityInfos)0x40000000;
                    }
                    else
                    {
                        securityInfos |= (SecurityInfos)0x10000000;
                    }
                    sacl = new byte[descriptor.SystemAcl.BinaryLength];
                    descriptor.SystemAcl.GetBinaryForm(sacl, 0);
                }
            }

            return(nativeCall(securityInfos, owner, group, dacl, sacl));
        }
Exemple #30
0
        public static void BasicValidationTestCases()
        {
            RawAcl     rAcl = null;
            GenericAce gAce = null;

            byte[] binaryForm = null;

            //Case 1, a RawAcl with one AccessAllowed Ace
            SecurityIdentifier sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA"));

            byte[] verifierBinaryForm = null;
            byte[] sidBinaryForm      = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidBinaryForm, 0);
            rAcl = new RawAcl(GenericAcl.AclRevision, 1);
            gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null);
            rAcl.InsertAce(0, gAce);
            binaryForm         = new byte[rAcl.BinaryLength];
            verifierBinaryForm = new byte[rAcl.BinaryLength];
            rAcl.GetBinaryForm(binaryForm, 0);

            int errorCode;

            if (0 == Utils.Win32AclLayer.InitializeAclNative
                    (verifierBinaryForm, (uint)rAcl.BinaryLength, (uint)GenericAcl.AclRevision))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else if (0 == Utils.Win32AclLayer.AddAccessAllowedAceExNative
                         (verifierBinaryForm, (uint)GenericAcl.AclRevision, (uint)AceFlags.None, (uint)1, sidBinaryForm))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else
            {
                Assert.True(Utils.IsBinaryFormEqual(binaryForm, verifierBinaryForm));
            }

            //Case 2, a RawAcl with one AccessDenied Ace
            sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA"));
            verifierBinaryForm = null;
            sidBinaryForm      = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidBinaryForm, 0);
            rAcl = new RawAcl(GenericAcl.AclRevision, 1);
            //31 include ObjectInherit, ContainerInherit, NoPropagateInherit, InheritOnly and Inherited
            gAce = new CommonAce((AceFlags)31, AceQualifier.AccessDenied, 1, sid, false, null);
            rAcl.InsertAce(0, gAce);
            binaryForm         = new byte[rAcl.BinaryLength];
            verifierBinaryForm = new byte[rAcl.BinaryLength];
            rAcl.GetBinaryForm(binaryForm, 0);

            if (0 == Utils.Win32AclLayer.InitializeAclNative
                    (verifierBinaryForm, (uint)rAcl.BinaryLength, (uint)GenericAcl.AclRevision))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else if (0 == Utils.Win32AclLayer.AddAccessDeniedAceExNative
                         (verifierBinaryForm, (uint)GenericAcl.AclRevision, (uint)31, (uint)1, sidBinaryForm))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else
            {
                Assert.True(Utils.IsBinaryFormEqual(binaryForm, verifierBinaryForm));
            }

            //Case 3, a RawAcl with one Audit Ace
            sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA"));
            verifierBinaryForm = null;
            sidBinaryForm      = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidBinaryForm, 0);
            rAcl = new RawAcl(GenericAcl.AclRevision, 1);
            //223 include ObjectInherit, ContainerInherit, NoPropagateInherit, InheritOnly, Inherited, SuccessfulAccess and FailedAccess
            gAce = new CommonAce((AceFlags)223, AceQualifier.SystemAudit, 1, sid, false, null);
            rAcl.InsertAce(0, gAce);
            binaryForm         = new byte[rAcl.BinaryLength];
            verifierBinaryForm = new byte[rAcl.BinaryLength];
            rAcl.GetBinaryForm(binaryForm, 0);

            if (0 == Utils.Win32AclLayer.InitializeAclNative
                    (verifierBinaryForm, (uint)rAcl.BinaryLength, (uint)GenericAcl.AclRevision))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else if (0 == Utils.Win32AclLayer.AddAuditAccessAceExNative
                         (verifierBinaryForm, (uint)GenericAcl.AclRevision, (uint)223, (uint)1, sidBinaryForm, 1, 1))
            {
                errorCode = Marshal.GetLastWin32Error();
            }
            else
            {
                Assert.True(Utils.IsBinaryFormEqual(binaryForm, verifierBinaryForm));
            }
        }
Exemple #31
0
        public ACLTestResult(String InputPath, String InputIdentity)
        {
            Path     = InputPath;
            Identity = InputIdentity;

            IntPtr      pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor;
            ACCESS_MASK mask = new ACCESS_MASK();
            uint        ret  = GetNamedSecurityInfo(InputPath,
                                                    SE_OBJECT_TYPE.SE_FILE_OBJECT,
                                                    SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION,
                                                    out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

            IntPtr hManager = IntPtr.Zero;

            bool f = AuthzInitializeResourceManager(1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out hManager);

            NTAccount          ac  = new NTAccount(InputIdentity);
            SecurityIdentifier sid = (SecurityIdentifier)ac.Translate(typeof(SecurityIdentifier));

            byte[] bytes = new byte[sid.BinaryLength];
            sid.GetBinaryForm(bytes, 0);
            String _psUserSid = "";

            foreach (byte si in bytes)
            {
                _psUserSid += si;
            }

            LUID   unusedSid = new LUID();
            IntPtr UserSid   = Marshal.AllocHGlobal(bytes.Length);

            Marshal.Copy(bytes, 0, UserSid, bytes.Length);
            IntPtr pClientContext = IntPtr.Zero;

            if (f)
            {
                f = AuthzInitializeContextFromSid(0, UserSid, hManager, IntPtr.Zero, unusedSid, IntPtr.Zero, out pClientContext);


                AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
                request.DesiredAccess        = 0x02000000;
                request.PrincipalSelfSid     = null;
                request.ObjectTypeList       = null;
                request.ObjectTypeListLength = 0;
                request.OptionalArguments    = IntPtr.Zero;

                AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
                reply.GrantedAccessMask     = IntPtr.Zero;
                reply.ResultListLength      = 0;
                reply.SaclEvaluationResults = IntPtr.Zero;
                IntPtr AccessReply = IntPtr.Zero;
                reply.Error             = Marshal.AllocHGlobal(1020);
                reply.GrantedAccessMask = Marshal.AllocHGlobal(sizeof(uint));
                reply.ResultListLength  = 1;
                int i = 0;

                f = AuthzAccessCheck(0, pClientContext, ref request, IntPtr.Zero, pSecurityDescriptor, null, 0, ref reply, out AccessReply);
                if (f)
                {
                    int granted_access = Marshal.ReadInt32(reply.GrantedAccessMask);

                    mask = (ACCESS_MASK)granted_access;

                    foreach (ACCESS_MASK item in Enum.GetValues(typeof(ACCESS_MASK)))
                    {
                        if ((mask & item) == item)
                        {
                            switch (item)
                            {
                            case ACCESS_MASK.FILE_TRAVERSE:
                                TraverseFolderAndExecuteFile = true;
                                break;

                            case ACCESS_MASK.FILE_LIST_DIRECTORY:
                                ListFolderAndReadData = true;
                                break;

                            case ACCESS_MASK.FILE_READ_ATTRIBUTES:
                                ReadAttributes = true;
                                break;

                            case ACCESS_MASK.FILE_READ_EA:
                                ReadExtendedAttributes = true;
                                break;

                            case ACCESS_MASK.FILE_ADD_FILE:
                                CreateFilesAndWriteData = true;
                                break;

                            case ACCESS_MASK.FILE_ADD_SUBDIRECTORY:
                                CreateFoldersAndAppendData = true;
                                break;

                            case ACCESS_MASK.FILE_WRITE_ATTRIBUTES:
                                WriteAttributes = true;
                                break;

                            case ACCESS_MASK.FILE_WRITE_EA:
                                WriteExtendedAttributes = true;
                                break;

                            case ACCESS_MASK.FILE_DELETE_CHILD:
                                DeleteSubfoldersAndFiles = true;
                                break;

                            case ACCESS_MASK.DELETE:
                                Delete = true;
                                break;

                            case ACCESS_MASK.READ_CONTROL:
                                ReadPermissions = true;
                                break;

                            case ACCESS_MASK.WRITE_DAC:
                                ChangePermissions = true;
                                break;

                            case ACCESS_MASK.WRITE_OWNER:
                                TakeOwnership = true;
                                break;

                            default:
                                break;
                            }
                            i++;
                        }
                    }
                }
                else
                {
                    Marshal.FreeHGlobal(reply.GrantedAccessMask);
                    throw new UnauthorizedAccessException();
                }
                Marshal.FreeHGlobal(reply.GrantedAccessMask);

                if (i == 16)
                {
                    FullControl = true;
                }
            }
        }
 private static void SerializeSid(SecurityIdentifier sid, SctClaimDictionary dictionary, XmlDictionaryWriter writer)
 {
     byte[] binaryForm = new byte[sid.BinaryLength];
     sid.GetBinaryForm(binaryForm, 0);
     writer.WriteBase64(binaryForm, 0, binaryForm.Length);
 }
        // Performs store-specific resolution of an IdentityReference to a Principal
        // corresponding to the IdentityReference.  Returns null if no matching object found.
        // principalType can be used to scope the search to principals of a specified type, e.g., users or groups.
        // Specify typeof(Principal) to search all principal types.
        internal override Principal FindPrincipalByIdentRef(
                                    Type principalType, string urnScheme, string urnValue, DateTime referenceDate)
        {
            // Perform the appropriate action based on the type of the UrnScheme
            if (urnScheme == UrnScheme.SidScheme)
            {
                // Get the SID from the UrnValue
                SecurityIdentifier sidObj = new SecurityIdentifier(urnValue);
                byte[] sid = new byte[sidObj.BinaryLength];
                sidObj.GetBinaryForm(sid, 0);

                if (sid == null)
                    throw new ArgumentException(StringResources.StoreCtxSecurityIdentityClaimBadFormat);

                // If they're searching by SID for a SID corresponding to a fake group, construct
                // and return the fake group
                IntPtr pSid = IntPtr.Zero;

                try
                {
                    pSid = Utils.ConvertByteArrayToIntPtr(sid);

                    if (UnsafeNativeMethods.IsValidSid(pSid) && (Utils.ClassifySID(pSid) == SidType.FakeObject))
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                                "SAMStoreCtx",
                                                "FindPrincipalByIdentRef: fake principal {0}",
                                                sidObj.ToString());

                        return ConstructFakePrincipalFromSID(sid);
                    }
                }
                finally
                {
                    if (pSid != IntPtr.Zero)
                        Marshal.FreeHGlobal(pSid);
                }

                // Not a fake group.  Search for the real group.            
                object o = FindNativeBySIDIdentRef(principalType, sid);
                return (o != null) ? GetAsPrincipal(o, null) : null;
            }
            else if (urnScheme == UrnScheme.SamAccountScheme || urnScheme == UrnScheme.NameScheme)
            {
                object o = FindNativeByNT4IdentRef(principalType, urnValue);
                return (o != null) ? GetAsPrincipal(o, null) : null;
            }
            else if (urnScheme == null)
            {
                object sidPrincipal = null;
                object nt4Principal = null;

                //
                // Try UrnValue as a SID IdentityClaim
                //

                // Get the SID from the UrnValue
                byte[] sid = null;

                try
                {
                    SecurityIdentifier sidObj = new SecurityIdentifier(urnValue);
                    sid = new byte[sidObj.BinaryLength];
                    sidObj.GetBinaryForm(sid, 0);
                }
                catch (ArgumentException)
                {
                    // must not have been a valid sid claim ignore it.
                }

                // If null, must have been a non-SID UrnValue.  Ignore it, and
                // continue on to try NT4 Account IdentityClaim.
                if (sid != null)
                {
                    // Are they perhaps searching for a fake group?
                    // If they passed in a valid SID for a fake group, construct and return the fake
                    // group.                
                    if (principalType == typeof(Principal) || principalType == typeof(GroupPrincipal) || principalType.IsSubclassOf(typeof(GroupPrincipal)))
                    {
                        // They passed in a hex string, is it a valid SID, and if so, does it correspond to a fake
                        // principal?
                        IntPtr pSid = IntPtr.Zero;

                        try
                        {
                            pSid = Utils.ConvertByteArrayToIntPtr(sid);

                            if (UnsafeNativeMethods.IsValidSid(pSid) && (Utils.ClassifySID(pSid) == SidType.FakeObject))
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                                        "SAMStoreCtx",
                                                        "FindPrincipalByIdentRef: fake principal {0} (scheme==null)",
                                                        Utils.ByteArrayToString(sid));

                                return ConstructFakePrincipalFromSID(sid);
                            }
                        }
                        finally
                        {
                            if (pSid != IntPtr.Zero)
                                Marshal.FreeHGlobal(pSid);
                        }
                    }

                    sidPrincipal = FindNativeBySIDIdentRef(principalType, sid);
                }

                //
                // Try UrnValue as a NT4 IdentityClaim
                //

                try
                {
                    nt4Principal = FindNativeByNT4IdentRef(principalType, urnValue);
                }
                catch (ArgumentException)
                {
                    // Must have been a non-NT4 Account UrnValue.  Ignore it.
                }

                GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                        "SAMStoreCtx",
                                        "FindPrincipalByIdentRef: scheme==null, found nt4={0}, found sid={1}",
                                        (nt4Principal != null),
                                        (sidPrincipal != null));

                // If they both succeeded in finding a match, we have too many matches.
                // Throw an exception.
                if ((sidPrincipal != null) && (nt4Principal != null))
                    throw new MultipleMatchesException(StringResources.MultipleMatchingPrincipals);

                // Return whichever one matched.  If neither matched, this will return null.
                return (sidPrincipal != null) ? GetAsPrincipal(sidPrincipal, null) :
                            ((nt4Principal != null) ? GetAsPrincipal(nt4Principal, null) :
                                null);
            }
            else
            {
                // Unsupported type of IdentityClaim
                throw new ArgumentException(StringResources.StoreCtxUnsupportedIdentityClaimForQuery);
            }
        }
        // Handles all the work required to implement FindPrincipalByIdentRef (and FindPrincipalBySID).
        private Principal FindPrincipalByIdentRefHelper(
                                    Type principalType,
                                    string urnScheme,
                                    string urnValue,
                                    DateTime referenceDate,
                                    bool useSidHistory)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "ADStoreCtx",
                                    "FindPrincipalByIdentRefHelper: type={0}, scheme={1}, value={2}, useSidHistory={3}",
                                    principalType.ToString(),
                                    (urnScheme != null ? urnScheme : "NULL"),
                                    (urnValue != null ? urnValue : "NULL"),
                                    useSidHistory);

            //
            // Set up a DirectorySearcher
            //
            DirectorySearcher ds = new DirectorySearcher(this.ctxBase);
            SearchResultCollection src = null;

            try
            {
                ds.SizeLimit = 2;   // so we can efficiently check for duplicates

                // If we are searching for AuthPrincpal or Principal in the end we will construct the acutal type
                // i.e. if the objects objectClass is User we will construct a UserPrincipal even though they searched for Principal.FindByIdentity
                // At this time we don't know the actual object type so we have to ask AD for all the attributes of the derived types so they are there
                // when we go to load the principal.
                if (principalType == typeof(Principal) || principalType == typeof(AuthenticablePrincipal))
                {
                    BuildPropertySet(typeof(UserPrincipal), ds.PropertiesToLoad);
                    BuildPropertySet(typeof(GroupPrincipal), ds.PropertiesToLoad);
                    BuildPropertySet(typeof(ComputerPrincipal), ds.PropertiesToLoad);

                    if (principalType == typeof(Principal))
                    {
                        BuildPropertySet(typeof(AuthenticablePrincipal), ds.PropertiesToLoad);
                    }
                }

                BuildPropertySet(principalType, ds.PropertiesToLoad);

                //
                // Build an appropriate filter
                //

                StringBuilder ldapFilter = new StringBuilder();

                // Limit the results returned to principalType by specifying the corresponding objectClass/objectCategory
                ldapFilter.Append(GetObjectClassPortion(principalType));

                // Build the rest of the filter based off of the user's specified IdentityReference.
                if (urnScheme != null)
                {
                    // If they're searching by SID for a SID corresponding to a fake group, construct
                    // and return the fake group
                    if ((urnScheme == UrnScheme.SidScheme) &&
                         (principalType == typeof(Principal) || principalType == typeof(GroupPrincipal) || principalType.IsSubclassOf(typeof(GroupPrincipal))))
                    {
                        SecurityIdentifier sid = new SecurityIdentifier(urnValue);
                        byte[] sidb = new byte[sid.BinaryLength];
                        sid.GetBinaryForm(sidb, 0);
                        //                        = Utils.StringToByteArray(urnValue);

                        if (sid == null)
                            throw new ArgumentException(StringResources.StoreCtxSecurityIdentityClaimBadFormat);

                        IntPtr pSid = IntPtr.Zero;

                        try
                        {
                            pSid = Utils.ConvertByteArrayToIntPtr(sidb);

                            if (UnsafeNativeMethods.IsValidSid(pSid) && (Utils.ClassifySID(pSid) == SidType.FakeObject))
                            {
                                GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                                        "ADStoreCtx",
                                                        "FindPrincipalByIdentRefHelper: fake principal, SID Scheme, {0}",
                                                        sid.ToString());

                                return ConstructFakePrincipalFromSID(sidb);
                            }
                        }
                        finally
                        {
                            if (pSid != IntPtr.Zero)
                                Marshal.FreeHGlobal(pSid);
                        }
                    }

                    // This is the simple case --- we got a specific UrnScheme, so we'll just build
                    // a filter for it.

                    // Ignore referenceDate --- all IdentityClaims in AD are forever
                    string innerLdapFilter = null;
                    BuildLdapFilterFromIdentityClaim(urnValue, urnScheme, ref innerLdapFilter, useSidHistory, true);

                    ldapFilter.Append(innerLdapFilter);
                }
                else
                {
                    // Are they perhaps searching for a fake group?
                    // If they passed in a valid SID for a fake group, construct and return the fake
                    // group.                
                    if (principalType == typeof(Principal) || principalType == typeof(GroupPrincipal) || principalType.IsSubclassOf(typeof(GroupPrincipal)))
                    {
                        SecurityIdentifier sid = null;
                        byte[] sidb = null;
                        try
                        {
                            sid = new SecurityIdentifier(urnValue);
                            sidb = new byte[sid.BinaryLength];
                            sid.GetBinaryForm(sidb, 0);
                        }
                        catch (ArgumentException)
                        {
                        }

                        if (sidb != null)
                        {
                            // They passed in a hex string, is it a valid SID, and if so, does it correspond to a fake
                            // principal?
                            IntPtr pSid = IntPtr.Zero;

                            try
                            {
                                pSid = Utils.ConvertByteArrayToIntPtr(sidb);

                                if (UnsafeNativeMethods.IsValidSid(pSid) && (Utils.ClassifySID(pSid) == SidType.FakeObject))
                                {
                                    GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                                            "ADStoreCtx",
                                                            "FindPrincipalByIdentRefHelper: fake principal, null Scheme, {0}",
                                                            sid.ToString());

                                    return ConstructFakePrincipalFromSID(sidb);
                                }
                            }
                            finally
                            {
                                if (pSid != IntPtr.Zero)
                                    Marshal.FreeHGlobal(pSid);
                            }
                        }
                    }

                    // This is the tricky case.  They didn't specify a UrnScheme, so we need to
                    // try all of them.

                    string[] urnSchemesToTry = new string[]
                    {
                        UrnScheme.SamAccountScheme,
                        UrnScheme.UpnScheme,
                        UrnScheme.DistinguishedNameScheme,
                        UrnScheme.SidScheme,
                        UrnScheme.GuidScheme,
                        UrnScheme.NameScheme
                    };

                    StringBuilder innerLdapFilter = new StringBuilder();

                    innerLdapFilter.Append("(|");

                    string filterVal = null;

                    foreach (string urnSchemeToTry in urnSchemesToTry)
                    {
                        if (BuildLdapFilterFromIdentityClaim(urnValue, urnSchemeToTry, ref filterVal, useSidHistory, false))
                            if (null != filterVal)
                                innerLdapFilter.Append(filterVal);
                    }

                    innerLdapFilter.Append(")");

                    ldapFilter.Append(innerLdapFilter.ToString());
                }

                // Wrap off the filter
                ldapFilter.Append(")");

                ds.Filter = ldapFilter.ToString();
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "FindPrincipalByIdentRefHelper: using LDAP filter {0}", ds.Filter);

                //
                // Perform the actual search
                //
                src = ds.FindAll();

                Debug.Assert(src != null);

                if (src == null)
                    return null;

                // Did we find a match?
                int count = src.Count;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "FindPrincipalByIdentRefHelper: found {0} matches", count);

                // Did we find more than one match?
                if (count > 1)
                    throw new MultipleMatchesException(StringResources.MultipleMatchingPrincipals);

                if (count == 0)
                    return null;

                return GetAsPrincipal(src[0], principalType);
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                throw ExceptionHelper.GetExceptionFromCOMException(e);
            }
            finally
            {
                ds.Dispose();
                if (src != null)
                {
                    src.Dispose();
                }
            }
        }