Beispiel #1
0
            protected override void Dispose(bool disposing)
            {
                if (stream != null)
                {
                    stream.Dispose();
                }

                GC.SuppressFinalize(this);

                if (isOriginal == false)
                {
                    return;
                }

                cts.Cancel();
                if (basePtr != null)
                {
                    Win32MemoryMapNativeMethods.UnmapViewOfFile(basePtr);
                }
                if (mmf != IntPtr.Zero)
                {
                    Win32NativeMethods.CloseHandle(mmf);
                }
                if (fileHandle != null)
                {
                    fileHandle.Close();
                }
            }
Beispiel #2
0
        /// <summary>
        /// Uses P/Invoke to start the process using the login token obtained for the user.
        /// </summary>
        /// <param name="token">The login token to use to create the process with.</param>
        private void StartWithCreateProcessAsUser(IntPtr token)
        {
            var  startinfo      = _process.StartInfo;
            var  path           = Path.GetFullPath(startinfo.FileName);
            var  dir            = Path.GetDirectoryName(path);
            bool processCreated = false;

            Win32NativeMethods.PROCESS_INFORMATION pi        = new Win32NativeMethods.PROCESS_INFORMATION();
            Win32NativeMethods.SECURITY_ATTRIBUTES saProcess = new Win32NativeMethods.SECURITY_ATTRIBUTES();
            saProcess.bInheritHandle = true;
            saProcess.nLength        = (uint)Marshal.SizeOf(saProcess);

            Win32NativeMethods.SECURITY_ATTRIBUTES saThread = new Win32NativeMethods.SECURITY_ATTRIBUTES();
            saThread.bInheritHandle = true;
            saThread.nLength        = (uint)Marshal.SizeOf(saThread);

            Win32NativeMethods.STARTUPINFO si = new Win32NativeMethods.STARTUPINFO();
            si.lpDesktop = string.Empty;
            si.cb        = (uint)Marshal.SizeOf(si);

            lock (createProcessLock)
            {
                _pipeServerToClient        = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
                _pipeServerFromClient      = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
                _pipeServerErrorFromClient = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);

                try
                {
                    // although these are separate if statements, in reality all standard streams must be
                    // redirected otherwise it just won't work in SACS.
                    if (startinfo.RedirectStandardInput)
                    {
                        _standardInput           = new StreamWriter(_pipeServerToClient);
                        _standardInput.AutoFlush = true;
                    }

                    if (startinfo.RedirectStandardOutput)
                    {
                        Encoding encoding = (startinfo.StandardOutputEncoding != null) ? startinfo.StandardOutputEncoding : Console.OutputEncoding;
                        _standardOutput = new StreamReader(_pipeServerFromClient);
                    }

                    if (startinfo.RedirectStandardError)
                    {
                        Encoding encoding2 = (startinfo.StandardErrorEncoding != null) ? startinfo.StandardErrorEncoding : Console.OutputEncoding;
                        _standardError = new StreamReader(_pipeServerErrorFromClient);
                    }

                    ArgumentObject["pipeIn"]  = _pipeServerToClient.GetClientHandleAsString();
                    ArgumentObject["pipeOut"] = _pipeServerFromClient.GetClientHandleAsString();
                    ArgumentObject["pipeErr"] = _pipeServerErrorFromClient.GetClientHandleAsString();

                    processCreated = Win32NativeMethods.CreateProcessAsUser(
                        token,
                        path,
                        string.Format("\"{0}\" {1}", startinfo.FileName.Replace("\"", "\"\""), JsonConvert.SerializeObject(this.ArgumentObject)),
                        ref saProcess,
                        ref saThread,
                        true,
                        0,
                        IntPtr.Zero,
                        dir,
                        ref si,
                        out pi);

                    if (!processCreated)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // For the last step, since we're not using the in-build methods to start the process,
                    // we need to replace the now outdated process
                    _process = Process.GetProcessById((int)pi.dwProcessId);
                }
                finally
                {
                    _pipeServerToClient.DisposeLocalCopyOfClientHandle();
                    _pipeServerFromClient.DisposeLocalCopyOfClientHandle();
                    _pipeServerErrorFromClient.DisposeLocalCopyOfClientHandle();

                    if (pi.hProcess != IntPtr.Zero)
                    {
                        Win32NativeMethods.CloseHandle(pi.hProcess);
                    }

                    if (pi.hThread != IntPtr.Zero)
                    {
                        Win32NativeMethods.CloseHandle(pi.hThread);
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Impersonates the specified user account.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="domainName">Name of the domain.</param>
        /// <param name="password">The password. <see cref="System.String"/></param>
        /// <param name="logonType">Type of the logon.</param>
        /// <param name="logonProvider">The logon provider. <see cref="Mit.Sharepoint.WebParts.EventLogQuery.Network.LogonProvider"/></param>
        private void Impersonate(string NetworkLocation, string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
        {
            try
            {
                UndoImpersonation();

                /*
                 * if (userName.Contains("\\") || userName.Contains("/"))
                 * {
                 * string[] tokens = userName.Split(new char[] { '\\', '/' });
                 * if (tokens.Length != 2) throw new Exception("Expected user name to contain at most one / or \\ character.  User name: " + userName);
                 * if (domainName.Trim().Length != 0) throw new Exception("Cannot specify a / or \\ in user name when domain is also given.  User name: " + userName + "  Domain: " + domainName);
                 * domainName = tokens[0];
                 * userName = tokens[1];
                 * }
                 */

                IntPtr logonToken          = IntPtr.Zero;
                IntPtr logonTokenDuplicate = IntPtr.Zero;
                try
                {
                    // revert to the application pool identity, saving the identity of the current requestor
                    _wic = WindowsIdentity.Impersonate(IntPtr.Zero);

                    // do logon & impersonate
                    if (Win32NativeMethods.LogonUser(userName,
                                                     domainName,
                                                     password,
                                                     (int)logonType,
                                                     (int)logonProvider,
                                                     ref logonToken) != 0)
                    {
                        if (Win32NativeMethods.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityImpersonation, ref logonTokenDuplicate) != 0)
                        {
                            var wi = new WindowsIdentity(logonTokenDuplicate);
                            wi.Impersonate(); // discard the returned identity context (which is the context of the application pool)
                        }
                        else
                        {
                            ThrowSpecificException();
                        }
                    }
                    else
                    {
                        ThrowSpecificException();
                    }
                }
                finally
                {
                    if (logonToken != IntPtr.Zero)
                    {
                        Win32NativeMethods.CloseHandle(logonToken);
                    }

                    if (logonTokenDuplicate != IntPtr.Zero)
                    {
                        Win32NativeMethods.CloseHandle(logonTokenDuplicate);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new IOException("Unable to access path:\n" + NetworkLocation + "\nAs username: "******"\nOn domain: " + domainName + "\nError: " + ex.ToString());
            }
        }
Beispiel #4
0
        /// <summary>
        /// Impersonates the specified user account.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="domainName">Name of the domain.</param>
        /// <param name="password">The password. <see cref="String"/></param>
        /// <param name="logonType">Type of the logon.</param>
        /// <param name="logonProvider">The logon provider.</param>
        /// /// <param name="impersonationAction">A callback to perform during the impersonation initialization.</param>
        public virtual void Impersonate(string userName, string domainName, SecureString password, LogonType logonType, LogonProvider logonProvider, Action <IntPtr> impersonationAction = null)
        {
            UndoImpersonation();

            IntPtr logonToken          = IntPtr.Zero;
            IntPtr logonTokenDuplicate = IntPtr.Zero;
            IntPtr passwordPtr         = new IntPtr();

            passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);
            bool logonValue = false;

            try
            {
                // revert to the application pool identity, saving the identity of the current requestor
                this._wic = WindowsIdentity.Impersonate(IntPtr.Zero);

                // do logon & impersonate
                logonValue = Win32NativeMethods.LogonUser(
                    userName,
                    domainName,
                    passwordPtr,
                    (int)logonType,
                    (int)logonProvider,
                    ref logonToken);

                if (logonValue)
                {
                    Win32NativeMethods.SECURITY_ATTRIBUTES sa = new Win32NativeMethods.SECURITY_ATTRIBUTES();
                    sa.nLength = (uint)Marshal.SizeOf(sa);

                    if (Win32NativeMethods.DuplicateTokenEx(
                            logonToken,
                            Win32NativeMethods.TOKEN_ASSIGN_PRIMARY | Win32NativeMethods.TOKEN_DUPLICATE | Win32NativeMethods.TOKEN_QUERY,
                            ref sa,
                            (int)Win32NativeMethods.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                            (int)Win32NativeMethods.TOKEN_TYPE.TokenPrimary,
                            ref logonTokenDuplicate))
                    {
                        // Looks like it is working without impersonating. To be revisited.
                        ////var wi = new WindowsIdentity(logonTokenDuplicate);
                        ////wi.Impersonate(); // discard the returned identity context (which is the context of the application)
                        ////this.IsImpersonating = true;
                        if (impersonationAction != null)
                        {
                            impersonationAction(logonTokenDuplicate);
                        }
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);

                if (logonToken != IntPtr.Zero)
                {
                    Win32NativeMethods.CloseHandle(logonToken);
                }

                if (logonTokenDuplicate != IntPtr.Zero)
                {
                    Win32NativeMethods.CloseHandle(logonTokenDuplicate);
                }
            }
        }