Beispiel #1
0
        public static void EnablePrivilegeOnProcess(Process process, SecurityEntities privilege)
        {
            SafeNativeHandle processToken;

            if (!AdvancedAPI.OpenProcessToken(process.Handle, TokenAccessLevels.AdjustPrivileges,
                                              out processToken))
            {
                throw new Win32Exception();
            }
            using (processToken)
            {
                LUID luid;
                if (!AdvancedAPI.LookupPrivilegeValue(null, privilege.ToString(), out luid))
                {
                    throw new Win32Exception();
                }

                var tkp = new TokenPrivileges(PrivilegeAttributes.Enabled, luid);
                if (
                    !AdvancedAPI.AdjustTokenPrivileges(processToken, false, ref tkp, (uint)Marshal.SizeOf(tkp),
                                                       IntPtr.Zero, IntPtr.Zero) ||
                    Marshal.GetLastWin32Error() != 0)
                {
                    throw new Win32Exception();
                }
            }
        }
Beispiel #2
0
        public static SafeNativeHandle DuplicatePrimaryToken(Process process)
        {
            SafeNativeHandle processToken;

            if (
                !AdvancedAPI.OpenProcessToken(process.Handle, TokenAccessLevels.Duplicate | TokenAccessLevels.Query,
                                              out processToken))
            {
                throw new Win32Exception();
            }
            using (processToken)
            {
                var tokenRights = TokenAccessLevels.Query | TokenAccessLevels.AssignPrimary |
                                  TokenAccessLevels.Duplicate | TokenAccessLevels.AdjustDefault |
                                  TokenAccessLevels.AdjustSessionId;
                SafeNativeHandle token;
                if (
                    !AdvancedAPI.DuplicateTokenEx(processToken, tokenRights, IntPtr.Zero,
                                                  TokenImpersonationLevel.Impersonation, TokenType.TokenPrimary, out token))
                {
                    throw new Win32Exception();
                }
                return(token);
            }
        }
Beispiel #3
0
        /// <summary>
        ///     Returns a <see cref="WindowsIdentity" /> object containing information about the owner of a specific
        ///     <see cref="Process" />
        /// </summary>
        /// <param name="process">
        ///     <see cref="Process" /> to be used for creating the corresponding <see cref="WindowsIdentity" />
        ///     object
        /// </param>
        /// <returns>A newly created <see cref="WindowsIdentity" /> object</returns>
        public static WindowsIdentity GetProcessOwner(Process process)
        {
            SafeNativeHandle token;

            if (
                !AdvancedAPI.OpenProcessToken(process.Handle, TokenAccessLevels.Query | TokenAccessLevels.Duplicate,
                                              out token))
            {
                throw new Win32Exception();
            }
            using (token)
            {
                return(new WindowsIdentity(token.DangerousGetHandle()));
            }
        }
Beispiel #4
0
        public static TokenElevationType GetTokenElevationType(IntPtr token)
        {
            var elevationTypeLength = Marshal.SizeOf(typeof(int));
            var elevationType       = (TokenElevationType)0;

            if (!AdvancedAPI.GetTokenInformation(token,
                                                 TokenInformationClass.TokenElevationType,
                                                 ref elevationType, elevationTypeLength, out elevationTypeLength))
            {
                var exception = new Win32Exception();
                if (exception.NativeErrorCode == 87) // ERROR_INVALID_PARAMETER
                {
                    throw new NotSupportedException();
                }
                throw exception;
            }
            return(elevationType);
        }
Beispiel #5
0
        /// <summary>
        ///     Starts a new <see cref="Process" /> with the start info provided and with the same rights as the mentioned
        ///     <see cref="Process" />
        /// </summary>
        /// <param name="process">The <see cref="Process" /> to copy rights from</param>
        /// <param name="startInfo">Contains the information about the <see cref="Process" /> to be started</param>
        /// <returns>Returns the newly started <see cref="Process" /></returns>
        /// <exception cref="InvalidOperationException">This method needs administrative access rights.-or-UAC is not enable</exception>
        /// <exception cref="NotSupportedException">Current version of Windows does not meets the needs of this method</exception>
        public static Process StartAndCopyProcessPermission(Process process, ProcessStartInfo startInfo)
        {
            if (!string.IsNullOrWhiteSpace(startInfo.UserName))
            {
                throw new InvalidOperationException(Resources.Error_StartWithUsername);
            }

            if (!IsElevated)
            {
                throw new InvalidOperationException(Resources.Error_AccessDenied);
            }

            Tokens.EnablePrivilegeOnProcess(Process.GetCurrentProcess(), SecurityEntities.SeImpersonatePrivilege);
            using (var primaryToken = Tokens.DuplicatePrimaryToken(process))
            {
                var lockTaken = false;
                try
                {
                    Monitor.Enter(startInfo, ref lockTaken);
                    var unicode       = Environment.OSVersion.Platform == PlatformID.Win32NT;
                    var creationFlags = startInfo.CreateNoWindow
                        ? ProcessCreationFlags.CreateNoWindow
                        : ProcessCreationFlags.None;
                    if (unicode)
                    {
                        creationFlags |= ProcessCreationFlags.UnicodeEnvironment;
                    }
                    var commandLine      = IOPath.BuildCommandLine(startInfo.FileName, startInfo.Arguments);
                    var workingDirectory = string.IsNullOrEmpty(startInfo.WorkingDirectory)
                        ? Environment.CurrentDirectory
                        : startInfo.WorkingDirectory;
                    var startupInfo = StartupInfo.GetOne();
                    var gcHandle    = new GCHandle();
                    try
                    {
                        gcHandle =
                            GCHandle.Alloc(
                                IOPath.EnvironmentBlockToByteArray(startInfo.EnvironmentVariables, unicode),
                                GCHandleType.Pinned);
                        var environmentPtr = gcHandle.AddrOfPinnedObject();
                        var logonFlags     = startInfo.LoadUserProfile ? LogonFlags.LogonWithProfile : LogonFlags.None;
                        ProcessInformation processInfo;
                        bool processCreationResult;
                        if (IsUACSupported) // Vista +
                        {
                            processCreationResult = AdvancedAPI.CreateProcessWithTokenW(primaryToken, logonFlags,
                                                                                        null,
                                                                                        commandLine,
                                                                                        creationFlags, environmentPtr, workingDirectory, ref startupInfo, out processInfo);
                        }
                        else
                        {
                            Tokens.EnablePrivilegeOnProcess(Process.GetCurrentProcess(),
                                                            SecurityEntities.SeIncreaseQuotaPrivilege);
                            processCreationResult = AdvancedAPI.CreateProcessAsUserW(primaryToken, null,
                                                                                     commandLine, IntPtr.Zero,
                                                                                     IntPtr.Zero, false, creationFlags, environmentPtr, workingDirectory, ref startupInfo,
                                                                                     out processInfo);
                        }
                        if (!processCreationResult)
                        {
                            throw new Win32Exception();
                        }
                        SafeNativeHandle.CloseHandle(processInfo.Thread);
                        SafeNativeHandle.CloseHandle(processInfo.Process);
                        if (processInfo.ProcessId <= 0)
                        {
                            throw new InvalidOperationException(Resources.Error_Unknown);
                        }
                        return(Process.GetProcessById(processInfo.ProcessId));
                    }
                    catch (EntryPointNotFoundException)
                    {
                        throw new NotSupportedException();
                    }
                    finally
                    {
                        if (gcHandle.IsAllocated)
                        {
                            gcHandle.Free();
                        }
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        Monitor.Exit(startInfo);
                    }
                }
            }
        }