123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * Copyright 2020 Brendan Shanks for CodeWeavers
- * Copyright 2023 Maxim Karasev <mxkrsv@etersoft.ru>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #define WIN32_LEAN_AND_MEAN
- #define SECURITY_WIN32
- #include <windows.h>
- #include <security.h>
- #include <sddl.h>
- #include <stdarg.h>
- #include "wine/debug.h"
- WINE_DEFAULT_DEBUG_CHANNEL(whoami);
- static int output_write(const WCHAR* str, int len)
- {
- DWORD count;
- if (len < 0)
- len = wcslen(str);
- if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, len, &count, NULL))
- {
- DWORD lenA;
- char *strA;
- /* On Windows WriteConsoleW() fails if the output is redirected. So fall
- * back to WriteFile() with OEM code page.
- */
- lenA = WideCharToMultiByte(GetOEMCP(), 0, str, len, NULL, 0, NULL, NULL);
- strA = malloc(lenA);
- if (!strA)
- return 0;
- WideCharToMultiByte(GetOEMCP(), 0, str, len, strA, lenA, NULL, NULL);
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strA, lenA, &count, FALSE);
- free(strA);
- }
- return count;
- }
- static WCHAR *get_user_name(EXTENDED_NAME_FORMAT name_format)
- {
- ULONG size = 0;
- WCHAR *ret;
- if (GetUserNameExW(name_format, NULL, &size) || GetLastError() != ERROR_MORE_DATA)
- return NULL;
- ret = malloc(size * sizeof(WCHAR));
- if (!ret)
- return NULL;
- if (!GetUserNameExW(name_format, ret, &size))
- {
- free(ret);
- return NULL;
- }
- return ret;
- }
- static void *get_token(TOKEN_INFORMATION_CLASS token_type)
- {
- HANDLE token_handle;
- void *ret;
- /* GetTokenInformation wants a dword-aligned buffer */
- ULONG ret_size = sizeof(DWORD) * 256;
- ULONG token_size;
- ret = malloc(ret_size);
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token_handle))
- return NULL;
- if (!GetTokenInformation(token_handle, token_type, ret, ret_size, &token_size))
- {
- CloseHandle(token_handle);
- return NULL;
- }
- CloseHandle(token_handle);
- return ret;
- }
- static SID *get_process_sid(void)
- {
- ULONG user_sid_len;
- TOKEN_USER *token_user;
- SID *ret;
- token_user = get_token(TokenUser);
- if (!token_user)
- return NULL;
- user_sid_len = GetLengthSid(token_user->User.Sid);
- ret = malloc(user_sid_len);
- if (!ret)
- {
- free(token_user);
- return NULL;
- }
- if (!CopySid(user_sid_len, ret, token_user->User.Sid))
- {
- free(token_user);
- free(ret);
- return NULL;
- }
- free(token_user);
- return ret;
- }
- static SID *get_logon_sid(void)
- {
- TOKEN_GROUPS *token_groups;
- DWORD group_token_len;
- DWORD i;
- SID *ret;
- token_groups = get_token(TokenGroups);
- if (!token_groups)
- return NULL;
- for (i = 0; i < token_groups->GroupCount; i++)
- {
- if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
- {
- group_token_len = GetLengthSid(token_groups->Groups[i].Sid);
- ret = malloc(group_token_len);
- if (!ret)
- {
- free(token_groups);
- return NULL;
- }
- if (!CopySid(group_token_len, ret, token_groups->Groups[i].Sid))
- {
- free(token_groups);
- free(ret);
- return NULL;
- }
- free(token_groups);
- return ret;
- }
- }
- free(token_groups);
- return NULL;
- }
- static int simple(EXTENDED_NAME_FORMAT name_format)
- {
- WCHAR *name;
- name = get_user_name(name_format);
- if (!name)
- {
- ERR("get_user_name failed\n");
- return 1;
- }
- output_write(name, -1);
- output_write(L"\n", 1);
- free(name);
- return 0;
- }
- static int logon_id(void)
- {
- PSID sid;
- WCHAR *sid_string;
- sid = get_logon_sid();
- if (!sid)
- {
- ERR("get_logon_sid failed\n");
- return 1;
- }
- if (!ConvertSidToStringSidW(sid, &sid_string))
- {
- ERR("ConvertSidToStringSidW failed, error %ld\n", GetLastError());
- return 1;
- }
- output_write(sid_string, -1);
- output_write(L"\n", 1);
- free(sid);
- LocalFree(sid_string);
- return 0;
- }
- static int user(void)
- {
- PSID sid;
- WCHAR *name;
- WCHAR *sid_string;
- ULONG i;
- name = get_user_name(NameSamCompatible);
- if (!name)
- {
- ERR("get_user_name failed\n");
- return 1;
- }
- sid = get_process_sid();
- if (!sid)
- {
- ERR("get_process_sid failed\n");
- return 1;
- }
- if (!ConvertSidToStringSidW(sid, &sid_string))
- {
- ERR("ConvertSidToStringSidW failed, error %ld\n", GetLastError());
- return 1;
- }
- output_write(L"\nUSER INFORMATION\n----------------\n\n", -1);
- output_write(L"User Name", -1);
- for (i = 0; i <= max(wcslen(name), wcslen(L"User Name")) - wcslen(L"User Name"); i++)
- output_write(L" ", 1);
- output_write(L"SID\n", -1);
- for (i = 0; i < wcslen(name); i++)
- output_write(L"=", 1);
- output_write(L" ", 1);
- for (i = 0; i < wcslen(sid_string); i++)
- output_write(L"=", 1);
- output_write(L"\n", 1);
- output_write(name, -1);
- output_write(L" ", 1);
- output_write(sid_string, -1);
- output_write(L"\n", 1);
- free(name);
- free(sid);
- LocalFree(sid_string);
- return 0;
- }
- int __cdecl wmain(int argc, WCHAR *argv[])
- {
- if (argv[1] == NULL)
- {
- return simple(NameSamCompatible);
- }
- else
- {
- wcslwr(argv[1]);
- if (!wcscmp(argv[1], L"/upn"))
- {
- /* Not implemented as of now, therefore fails */
- return simple(NameUserPrincipal);
- }
- else if (!wcscmp(argv[1], L"/fqdn"))
- {
- /* Not implemented as of now, therefore fails */
- return simple(NameFullyQualifiedDN);
- }
- else if (!wcscmp(argv[1], L"/logonid"))
- {
- return logon_id();
- }
- else if (!wcscmp(argv[1], L"/user"))
- {
- return user();
- }
- else
- {
- FIXME("stub\n");
- return 0;
- }
- }
- }
|