public static extern bool CreateProcessAsUser( IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SecurityWin32.SECURITY_ATTRIBUTES lpProcessAttributes, ref SecurityWin32.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, ProcessWin32.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref ProcessWin32.STARTUPINFO lpStartupInfo, out ProcessWin32.PROCESS_INFORMATION lpProcessInformation);
/// <summary> /// ASP.NET で偽装ユーザーのコンテキストで実行されるプロセスを生成する /// http://support.microsoft.com/kb/889251/ja /// </summary> /// <param name="commandLinePath">コマンドライン</param> /// <param name="currentDirectory">カレント・ディレクトリ</param> /// <param name="impersonationLevel">偽装レベル</param> /// <param name="errorInfo">エラー情報</param> /// <returns> /// ・true:成功 /// ・false:失敗 /// </returns> public static bool CreateProcessAsImpersonationUser( string commandLinePath, string currentDirectory, SecurityWin32.SECURITY_IMPERSONATION_LEVEL impersonationLevel, out string errorInfo) { // エラー情報の初期化 errorInfo = ""; // 失敗するので初期化 if (string.IsNullOrEmpty(currentDirectory)) { currentDirectory = Environment.GetEnvironmentVariable( "SystemRoot", EnvironmentVariableTarget.Process); } // トークン IntPtr token = IntPtr.Zero; // 継承可能にする。 IntPtr tokenDuplicate = IntPtr.Zero; // 戻り値 bool ret; // 偽装ユーザのアカウント・トークン token = WindowsIdentity.GetCurrent().Token; // SECURITY_ATTRIBUTES構造体 SecurityWin32.SECURITY_ATTRIBUTES sa = new SecurityWin32.SECURITY_ATTRIBUTES(); // Security Descriptor sa.lpSecurityDescriptor = IntPtr.Zero; // = (IntPtr)0; // Security Descriptorのハンドルは継承不可能 sa.bInheritHandle = false; // サイズ sa.Length = Marshal.SizeOf(sa); try { // 偽装アクセストークンハンドルは、 // CreateProcessAsUserに指定できないため、 // DuplicateTokenExでプライマリ・トークンに変換する ret = SecurityWin32.DuplicateTokenEx( token, (uint)SecurityWin32.ACCESS_MASK.GENERIC_ALL, ref sa, (int)impersonationLevel, (int)SecurityWin32.TOKEN_TYPE.TokenPrimary, ref tokenDuplicate); // 戻り値判定 if (ret) { // true(成功) // STARTUPINFO構造体 ProcessWin32.STARTUPINFO si = new ProcessWin32.STARTUPINFO(); // デスクトップ名 si.lpDesktop = ""; // サイズ si.cb = Marshal.SizeOf(si); // PROCESS_INFORMATION構造体 ProcessWin32.PROCESS_INFORMATION pi = new ProcessWin32.PROCESS_INFORMATION(); // 偽装可能にしたトークンを指定してプロセス起動 ret = ProcessWin32.CreateProcessAsUser( tokenDuplicate, null, commandLinePath, ref sa, ref sa, false, 0, IntPtr.Zero, currentDirectory, ref si, out pi); // 戻り値判定 if (ret) { // true(成功) CmnWin32.CloseHandle(pi.hProcess); CmnWin32.CloseHandle(pi.hThread); // 偽装可能にしたトークンのハンドラを閉じる ret = CmnWin32.CloseHandle(tokenDuplicate); } else { // asp.net - Running cscript.exe from C# .ashx does not execute code in vbscript file - Stack Overflow // http://stackoverflow.com/questions/3842020/running-cscript-exe-from-c-sharp-ashx-does-not-execute-code-in-vbscript-file // false(失敗) errorInfo = "CreateProcessAsUser failed with " + Marshal.GetLastWin32Error() + ": if 1314, make sure user is a member 'Replace a process level token' Control Panel -> Administrative Tools -> Local Security Settings."; } } else { // false(失敗) errorInfo = "DuplicateTokenEx failed with " + Marshal.GetLastWin32Error(); } } finally { // 失敗(例外発生)時など。 // トークンハンドル、 // 偽装アクセストークンハンドルをクローズ if (token != IntPtr.Zero) { CmnWin32.CloseHandle(token); } if (tokenDuplicate != IntPtr.Zero) { CmnWin32.CloseHandle(tokenDuplicate); } } // false(失敗) return false; }