https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5811da1ec5c7fe377e28dc...
commit 5811da1ec5c7fe377e28dc207b250d771fade5e3 Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Sun Feb 13 21:45:10 2022 +0100 Commit: Eric Kohl eric.kohl@reactos.org CommitDate: Sun Feb 13 21:45:10 2022 +0100
[RUNAS] Initial version of the runas utility
- Work in progress - Please do not translate it yet because the resources will change significantly --- base/applications/CMakeLists.txt | 1 + base/applications/runas/CMakeLists.txt | 8 ++ base/applications/runas/lang/de-DE.rc | 12 ++ base/applications/runas/lang/en-US.rc | 12 ++ base/applications/runas/resource.h | 7 ++ base/applications/runas/runas.c | 210 +++++++++++++++++++++++++++++++++ base/applications/runas/runas.rc | 24 ++++ 7 files changed, 274 insertions(+)
diff --git a/base/applications/CMakeLists.txt b/base/applications/CMakeLists.txt index 7c18212ed4f..c363430f0cb 100644 --- a/base/applications/CMakeLists.txt +++ b/base/applications/CMakeLists.txt @@ -33,6 +33,7 @@ add_subdirectory(rapps) add_subdirectory(rapps_com) add_subdirectory(regedit) add_subdirectory(regedt32) +add_subdirectory(runas) add_subdirectory(sc) add_subdirectory(screensavers) add_subdirectory(sdbinst) diff --git a/base/applications/runas/CMakeLists.txt b/base/applications/runas/CMakeLists.txt new file mode 100644 index 00000000000..0bc636230f3 --- /dev/null +++ b/base/applications/runas/CMakeLists.txt @@ -0,0 +1,8 @@ + +include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/conutils) + +add_executable(runas runas.c runas.rc) +set_module_type(runas win32cui UNICODE) +target_link_libraries(runas conutils ${PSEH_LIB}) +add_importlibs(runas advapi32 msvcrt kernel32 ntdll) +add_cd_file(TARGET runas DESTINATION reactos/system32 FOR all) diff --git a/base/applications/runas/lang/de-DE.rc b/base/applications/runas/lang/de-DE.rc new file mode 100644 index 00000000000..53f50974495 --- /dev/null +++ b/base/applications/runas/lang/de-DE.rc @@ -0,0 +1,12 @@ +LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL + +STRINGTABLE +BEGIN + IDS_USAGE01 "Syntax für RUNAS:\n\n" + IDS_USAGE02 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly] ]\n" + IDS_USAGE03 " /user:<Benutzername> Programm\n\n" + IDS_USAGE04 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly] ]\n" + IDS_USAGE05 " /smartcard [/user:<Benutzername>] Programm\n\n" + IDS_USAGE06 "/noprofile" + IDS_USAGE07 "/profile" +END diff --git a/base/applications/runas/lang/en-US.rc b/base/applications/runas/lang/en-US.rc new file mode 100644 index 00000000000..815319ea936 --- /dev/null +++ b/base/applications/runas/lang/en-US.rc @@ -0,0 +1,12 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_USAGE01 "RUNAS USAGE\n\n" + IDS_USAGE02 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly] ]\n" + IDS_USAGE03 " /user:<UserName> program\n\n" + IDS_USAGE04 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly] ]\n" + IDS_USAGE05 " /smartcard [/user:<UserName>] program\n\n" + IDS_USAGE06 "/noprofile" + IDS_USAGE07 "/profile" +END diff --git a/base/applications/runas/resource.h b/base/applications/runas/resource.h new file mode 100644 index 00000000000..11ad5ad8fa3 --- /dev/null +++ b/base/applications/runas/resource.h @@ -0,0 +1,7 @@ +#define IDS_USAGE01 7000 +#define IDS_USAGE02 7001 +#define IDS_USAGE03 7002 +#define IDS_USAGE04 7003 +#define IDS_USAGE05 7004 +#define IDS_USAGE06 7005 +#define IDS_USAGE07 7006 diff --git a/base/applications/runas/runas.c b/base/applications/runas/runas.c new file mode 100644 index 00000000000..581f24e2d00 --- /dev/null +++ b/base/applications/runas/runas.c @@ -0,0 +1,210 @@ +/* + * PROJECT: ReactOS runas utility + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/runas/runas.c + * COPYRIGHT: Copyright 2022 Eric Kohl eric.kohl@reactos.org + */ + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <stdarg.h> + +#define WIN32_NO_STATUS +#include <windef.h> +#include <winbase.h> +#include <winnls.h> +#include <wincon.h> +#include <winsvc.h> +#include <conutils.h> + +#include "resource.h" + +#define NDEBUG +#include <debug.h> + +static +void +Usage(void) +{ + ConResPuts(StdOut, IDS_USAGE01); + ConResPuts(StdOut, IDS_USAGE02); + ConResPuts(StdOut, IDS_USAGE03); + ConResPuts(StdOut, IDS_USAGE04); + ConResPuts(StdOut, IDS_USAGE05); + ConResPuts(StdOut, IDS_USAGE06); + ConResPuts(StdOut, IDS_USAGE07); +} + + +int +wmain( + int argc, + LPCWSTR argv[]) +{ + LPCWSTR pszArg; + int i, result = 0; + BOOL bProfile = FALSE, bNoProfile = FALSE; + BOOL bEnv = FALSE; + PWSTR pszUserName = NULL; + PWSTR pszDomain = NULL; + PWSTR pszCommandLine = NULL; + PWSTR pszPassword = NULL; + PWSTR ptr; + STARTUPINFOW StartupInfo; + PROCESS_INFORMATION ProcessInfo; + DWORD dwLogonFlags = 0; + BOOL rc; + + /* Initialize the Console Standard Streams */ + ConInitStdStreams(); + + if (argc == 1) + { + Usage(); + return 0; + } + + ZeroMemory(&StartupInfo, sizeof(StartupInfo)); + ZeroMemory(&ProcessInfo, sizeof(ProcessInfo)); + + for (i = 1; i < argc; i++) + { + pszArg = argv[i]; + if (*pszArg == L'-' || *pszArg == L'/') + { + pszArg++; + if (wcscmp(pszArg, L"?") == 0) + { + Usage(); + } + else if (wcsicmp(pszArg, L"profile") == 0) + { + bProfile = TRUE; + } + else if (wcsicmp(pszArg, L"noprofile") == 0) + { + bNoProfile = TRUE; + } + else if (wcsicmp(pszArg, L"env") == 0) + { + bEnv = TRUE; + } + else if (_wcsnicmp(pszArg, L"user:", 5) == 0) + { + pszArg += 5; + ptr = wcschr(pszArg, L'@'); + if (ptr != NULL) + { + /* User@Domain */ + pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((ptr - pszArg) + 1) * sizeof(WCHAR)); + if (pszUserName) + wcsncpy(pszUserName, pszArg, (ptr - pszArg)); + + ptr++; + pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(ptr) + 1) * sizeof(WCHAR)); + if (pszDomain) + wcscpy(pszDomain, ptr); + } + else + { + ptr = wcschr(pszArg, L'\'); + if (ptr != NULL) + { + /* Domain\User */ + pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(ptr + 1) + 1)* sizeof(WCHAR)); + if (pszUserName) + wcscpy(pszUserName, (ptr + 1)); + + pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((ptr - pszArg) + 1) * sizeof(WCHAR)); + if (pszDomain) + wcsncpy(pszDomain, pszArg, (ptr - pszArg)); + } + else + { + /* User */ + pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pszArg) + 1) * sizeof(WCHAR)); + if (pszUserName) + wcscpy(pszUserName, pszArg); + } + } + } + else + { + Usage(); + result = -1; + } + } + else + { + if (pszCommandLine == NULL) + { + pszCommandLine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pszArg) + 1) * sizeof(WCHAR)); + if (pszCommandLine != NULL) + wcscpy(pszCommandLine, pszArg); + break; + } + } + } + + if (bProfile && bNoProfile) + { + Usage(); + result = -1; + goto done; + } + + if (bProfile) + dwLogonFlags |= LOGON_WITH_PROFILE; + + if (bNoProfile) + dwLogonFlags &= ~LOGON_WITH_PROFILE; + + if (bEnv) + { + DPRINT("env\n"); + } + + DPRINT("User: %S\n", pszUserName); + DPRINT("Domain: %S\n", pszDomain); + DPRINT("CommandLine: %S\n", pszCommandLine); + + /* FIXME: Query the password: */ + + rc = CreateProcessWithLogonW(pszUserName, + pszDomain, + pszPassword, + dwLogonFlags, + NULL, //[in, optional] LPCWSTR lpApplicationName, + pszCommandLine, + 0, //[in] DWORD dwCreationFlags, + bEnv ? GetEnvironmentStringsW() : NULL, + NULL, //[in, optional] LPCWSTR lpCurrentDirectory, + &StartupInfo, + &ProcessInfo); + if (rc == FALSE) + { + DPRINT("Error: %lu\n", GetLastError()); + } + +done: + if (ProcessInfo.hThread) + CloseHandle(ProcessInfo.hThread); + + if (ProcessInfo.hProcess) + CloseHandle(ProcessInfo.hProcess); + + if (pszPassword) + HeapFree(GetProcessHeap(), 0, pszPassword); + + if (pszCommandLine) + HeapFree(GetProcessHeap(), 0, pszCommandLine); + + if (pszUserName) + HeapFree(GetProcessHeap(), 0, pszUserName); + + if (pszDomain) + HeapFree(GetProcessHeap(), 0, pszDomain); + + return result; +} diff --git a/base/applications/runas/runas.rc b/base/applications/runas/runas.rc new file mode 100644 index 00000000000..ebf9f255cd9 --- /dev/null +++ b/base/applications/runas/runas.rc @@ -0,0 +1,24 @@ +#include <windef.h> +#include <winuser.h> + +#include "resource.h" + +/* Define language neutral resources */ +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#define REACTOS_STR_FILE_DESCRIPTION "Run As Utility" +#define REACTOS_STR_INTERNAL_NAME "runas" +#define REACTOS_STR_ORIGINAL_FILENAME "runas.exe" +#include <reactos/version.rc> + +#include <reactos/manifest_exe.rc> + +/* UTF-8 */ +#pragma code_page(65001) + +#ifdef LANGUAGE_DE_DE + #include "lang/de-DE.rc" +#endif +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif