mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-29 08:44:52 +02:00
Rework username same as hostname (#469)
This commit is contained in:
parent
59a96cfee4
commit
62ea86fdbe
@ -1587,6 +1587,104 @@ am_system()
|
|||||||
return running_as_system;
|
return running_as_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns SID of user/group. If psid argument is NULL, allocates a new one,
|
||||||
|
* otherwise saves SID into the supplied memory area.
|
||||||
|
* Sets psid_len (if non-NULL) to the actual SID size.
|
||||||
|
* Caller should free() return value if psid argument was NULL.
|
||||||
|
*/
|
||||||
|
PSID
|
||||||
|
lookup_sid(const wchar_t* name_utf16, PSID psid, DWORD * psid_len)
|
||||||
|
{
|
||||||
|
PSID ret = NULL, alloc_psid = NULL, target_psid;
|
||||||
|
DWORD sid_len = 0;
|
||||||
|
SID_NAME_USE n_use;
|
||||||
|
WCHAR dom[DNLEN + 1] = L"";
|
||||||
|
DWORD dom_len = DNLEN + 1;
|
||||||
|
wchar_t* name_utf16_modified = NULL;
|
||||||
|
BOOL resolveAsAdminsSid = 0, r;
|
||||||
|
|
||||||
|
debug3_f("name_utf16:%S", name_utf16);
|
||||||
|
|
||||||
|
LookupAccountNameW(NULL, name_utf16, NULL, &sid_len, dom, &dom_len, &n_use);
|
||||||
|
|
||||||
|
if (sid_len == 0 && _wcsicmp(name_utf16, L"administrators") == 0) {
|
||||||
|
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, NULL, &sid_len);
|
||||||
|
resolveAsAdminsSid = 1;
|
||||||
|
debug3_f("resolveAsAdminsSid:%d", resolveAsAdminsSid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sid_len == 0) {
|
||||||
|
error_f("LookupAccountNameW() failed with error:%d", GetLastError());
|
||||||
|
errno = errno_from_Win32LastError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_psid = psid;
|
||||||
|
if (target_psid == NULL) {
|
||||||
|
if ((alloc_psid = malloc(sid_len)) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
error_f("Failed to allocate memory");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
target_psid = alloc_psid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolveAsAdminsSid)
|
||||||
|
r = CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, target_psid, &sid_len);
|
||||||
|
else
|
||||||
|
r = LookupAccountNameW(NULL, name_utf16, target_psid, &sid_len, dom, &dom_len, &n_use);
|
||||||
|
|
||||||
|
if (!r) {
|
||||||
|
error_f("Failed to retrieve SID for user:%S error:%d", name_utf16, GetLastError());
|
||||||
|
errno = errno_from_Win32LastError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_use == SidTypeDomain) {
|
||||||
|
// Additionally check the case when name is the same as computer name and
|
||||||
|
// thus same as local domain. Try to resolve <name>\<name>.
|
||||||
|
/* fetch the computer name so we can determine if the specified user is local or not */
|
||||||
|
wchar_t computer_name[CNLEN + 1];
|
||||||
|
DWORD computer_name_size = ARRAYSIZE(computer_name);
|
||||||
|
if (GetComputerNameW(computer_name, &computer_name_size) == 0) {
|
||||||
|
error_f("GetComputerNameW() failed with error:%d", GetLastError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wcsicmp(name_utf16, computer_name) != 0) {
|
||||||
|
error_f("For SidTypeDomain, name:%ls must be same as machine name:%ls", name_utf16, computer_name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug3_f("local user name is same as machine name");
|
||||||
|
size_t name_size = wcslen(name_utf16) * 2U + 2U;
|
||||||
|
name_utf16_modified = malloc(name_size * sizeof(wchar_t));
|
||||||
|
name_utf16_modified[0] = L'\0';
|
||||||
|
wcscat_s(name_utf16_modified, name_size, name_utf16);
|
||||||
|
wcscat_s(name_utf16_modified, name_size, L"\\");
|
||||||
|
wcscat_s(name_utf16_modified, name_size, name_utf16);
|
||||||
|
|
||||||
|
ret = lookup_sid(name_utf16_modified, psid, psid_len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (psid_len != NULL)
|
||||||
|
*psid_len = sid_len;
|
||||||
|
|
||||||
|
alloc_psid = NULL;
|
||||||
|
ret = target_psid;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if (name_utf16_modified)
|
||||||
|
free(name_utf16_modified);
|
||||||
|
if (alloc_psid)
|
||||||
|
free(alloc_psid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns SID of user/group or current user if (user = NULL)
|
* returns SID of user/group or current user if (user = NULL)
|
||||||
* caller should free() return value
|
* caller should free() return value
|
||||||
@ -1601,41 +1699,10 @@ get_sid(const char* name)
|
|||||||
wchar_t* name_utf16 = NULL;
|
wchar_t* name_utf16 = NULL;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
DWORD sid_len = 0;
|
|
||||||
SID_NAME_USE n_use;
|
|
||||||
WCHAR dom[DNLEN + 1] = L"";
|
|
||||||
DWORD dom_len = DNLEN + 1;
|
|
||||||
BOOL resolveAsAdminsSid = 0, r;
|
|
||||||
|
|
||||||
if ((name_utf16 = utf8_to_utf16(name)) == NULL)
|
if ((name_utf16 = utf8_to_utf16(name)) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
LookupAccountNameW(NULL, name_utf16, NULL, &sid_len, dom, &dom_len, &n_use);
|
psid = lookup_sid(name_utf16, NULL, NULL);
|
||||||
|
|
||||||
if (sid_len == 0 && _stricmp(name, "administrators") == 0) {
|
|
||||||
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, NULL, &sid_len);
|
|
||||||
resolveAsAdminsSid = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sid_len == 0) {
|
|
||||||
errno = errno_from_Win32LastError();
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((psid = malloc(sid_len)) == NULL) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolveAsAdminsSid)
|
|
||||||
r = CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, psid, &sid_len);
|
|
||||||
else
|
|
||||||
r = LookupAccountNameW(NULL, name_utf16, psid, &sid_len, dom, &dom_len, &n_use);
|
|
||||||
|
|
||||||
if (!r) {
|
|
||||||
errno = errno_from_Win32LastError();
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == FALSE ||
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == FALSE ||
|
||||||
|
@ -70,6 +70,7 @@ int load_user_profile(HANDLE user_token, char* user);
|
|||||||
int create_directory_withsddl(wchar_t *path, wchar_t *sddl);
|
int create_directory_withsddl(wchar_t *path, wchar_t *sddl);
|
||||||
int is_absolute_path(const char *);
|
int is_absolute_path(const char *);
|
||||||
int file_in_chroot_jail(HANDLE);
|
int file_in_chroot_jail(HANDLE);
|
||||||
|
PSID lookup_sid(const wchar_t* name_utf16, PSID psid, DWORD * psid_len);
|
||||||
PSID get_sid(const char*);
|
PSID get_sid(const char*);
|
||||||
int am_system();
|
int am_system();
|
||||||
int is_conpty_supported();
|
int is_conpty_supported();
|
||||||
|
@ -1,458 +1,458 @@
|
|||||||
/*
|
/*
|
||||||
* Author: NoMachine <developers@nomachine.com>
|
* Author: NoMachine <developers@nomachine.com>
|
||||||
*
|
*
|
||||||
* Author: Bryan Berns <berns@uwalumni.com>
|
* Author: Bryan Berns <berns@uwalumni.com>
|
||||||
* Normalized and optimized login routines and added support for
|
* Normalized and optimized login routines and added support for
|
||||||
* internet-linked accounts.
|
* internet-linked accounts.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009, 2011 NoMachine
|
* Copyright (c) 2009, 2011 NoMachine
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
* Support functions and system calls' replacements needed to let the
|
* Support functions and system calls' replacements needed to let the
|
||||||
* software run on Win32 based operating systems.
|
* software run on Win32 based operating systems.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <LM.h>
|
#include <LM.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
#include <DsGetDC.h>
|
#include <DsGetDC.h>
|
||||||
#define SECURITY_WIN32
|
#define SECURITY_WIN32
|
||||||
#include <security.h>
|
#include <security.h>
|
||||||
|
|
||||||
#include "inc\pwd.h"
|
#include "inc\pwd.h"
|
||||||
#include "inc\grp.h"
|
#include "inc\grp.h"
|
||||||
#include "inc\utf.h"
|
#include "inc\utf.h"
|
||||||
#include "misc_internal.h"
|
#include "misc_internal.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static struct passwd pw;
|
static struct passwd pw;
|
||||||
static char* pw_shellpath = NULL;
|
static char* pw_shellpath = NULL;
|
||||||
char* shell_command_option = NULL;
|
char* shell_command_option = NULL;
|
||||||
char* shell_arguments = NULL;
|
char* shell_arguments = NULL;
|
||||||
BOOLEAN arg_escape = TRUE;
|
BOOLEAN arg_escape = TRUE;
|
||||||
|
|
||||||
/* returns 0 on success, and -1 with errno set on failure */
|
/* returns 0 on success, and -1 with errno set on failure */
|
||||||
static int
|
static int
|
||||||
set_defaultshell()
|
set_defaultshell()
|
||||||
{
|
{
|
||||||
HKEY reg_key = 0;
|
HKEY reg_key = 0;
|
||||||
int tmp_len, ret = -1;
|
int tmp_len, ret = -1;
|
||||||
REGSAM mask = STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY;
|
REGSAM mask = STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY;
|
||||||
wchar_t path_buf[PATH_MAX], option_buf[32], arg_buf[PATH_MAX];
|
wchar_t path_buf[PATH_MAX], option_buf[32], arg_buf[PATH_MAX];
|
||||||
char *pw_shellpath_local = NULL, *command_option_local = NULL, *shell_arguments_local = NULL;
|
char *pw_shellpath_local = NULL, *command_option_local = NULL, *shell_arguments_local = NULL;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
/* if already set, return success */
|
/* if already set, return success */
|
||||||
if (pw_shellpath != NULL)
|
if (pw_shellpath != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
path_buf[0] = L'\0';
|
path_buf[0] = L'\0';
|
||||||
option_buf[0] = L'\0';
|
option_buf[0] = L'\0';
|
||||||
arg_buf[0] = L'\0';
|
arg_buf[0] = L'\0';
|
||||||
|
|
||||||
tmp_len = _countof(path_buf);
|
tmp_len = _countof(path_buf);
|
||||||
if ((RegOpenKeyExW(HKEY_LOCAL_MACHINE, SSH_REGISTRY_ROOT, 0, mask, ®_key) == ERROR_SUCCESS) &&
|
if ((RegOpenKeyExW(HKEY_LOCAL_MACHINE, SSH_REGISTRY_ROOT, 0, mask, ®_key) == ERROR_SUCCESS) &&
|
||||||
(RegQueryValueExW(reg_key, L"DefaultShell", 0, NULL, (LPBYTE)path_buf, &tmp_len) == ERROR_SUCCESS) &&
|
(RegQueryValueExW(reg_key, L"DefaultShell", 0, NULL, (LPBYTE)path_buf, &tmp_len) == ERROR_SUCCESS) &&
|
||||||
(path_buf[0] != L'\0')) {
|
(path_buf[0] != L'\0')) {
|
||||||
/* fetched default shell path from registry */
|
/* fetched default shell path from registry */
|
||||||
tmp_len = _countof(option_buf);
|
tmp_len = _countof(option_buf);
|
||||||
DWORD size = sizeof(DWORD);
|
DWORD size = sizeof(DWORD);
|
||||||
DWORD escape_option = 1;
|
DWORD escape_option = 1;
|
||||||
if (RegQueryValueExW(reg_key, L"DefaultShellCommandOption", 0, NULL, (LPBYTE)option_buf, &tmp_len) != ERROR_SUCCESS)
|
if (RegQueryValueExW(reg_key, L"DefaultShellCommandOption", 0, NULL, (LPBYTE)option_buf, &tmp_len) != ERROR_SUCCESS)
|
||||||
option_buf[0] = L'\0';
|
option_buf[0] = L'\0';
|
||||||
|
|
||||||
tmp_len = _countof(arg_buf);
|
tmp_len = _countof(arg_buf);
|
||||||
if (RegQueryValueExW(reg_key, L"DefaultShellArguments", 0, NULL, (LPBYTE)arg_buf, &tmp_len) != ERROR_SUCCESS)
|
if (RegQueryValueExW(reg_key, L"DefaultShellArguments", 0, NULL, (LPBYTE)arg_buf, &tmp_len) != ERROR_SUCCESS)
|
||||||
arg_buf[0] = L'\0';
|
arg_buf[0] = L'\0';
|
||||||
|
|
||||||
if (RegQueryValueExW(reg_key, L"DefaultShellEscapeArguments", 0, NULL, (LPBYTE)&escape_option, &size) == ERROR_SUCCESS)
|
if (RegQueryValueExW(reg_key, L"DefaultShellEscapeArguments", 0, NULL, (LPBYTE)&escape_option, &size) == ERROR_SUCCESS)
|
||||||
arg_escape = (escape_option != 0) ? TRUE : FALSE;
|
arg_escape = (escape_option != 0) ? TRUE : FALSE;
|
||||||
} else {
|
} else {
|
||||||
if (!GetSystemDirectoryW(path_buf, _countof(path_buf))) {
|
if (!GetSystemDirectoryW(path_buf, _countof(path_buf))) {
|
||||||
errno = GetLastError();
|
errno = GetLastError();
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (wcscat_s(path_buf, _countof(path_buf), L"\\cmd.exe") != 0)
|
if (wcscat_s(path_buf, _countof(path_buf), L"\\cmd.exe") != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pw_shellpath_local = utf16_to_utf8(path_buf)) == NULL)
|
if ((pw_shellpath_local = utf16_to_utf8(path_buf)) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (option_buf[0] != L'\0')
|
if (option_buf[0] != L'\0')
|
||||||
if ((command_option_local = utf16_to_utf8(option_buf)) == NULL)
|
if ((command_option_local = utf16_to_utf8(option_buf)) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (arg_buf[0] != L'\0')
|
if (arg_buf[0] != L'\0')
|
||||||
if ((shell_arguments_local = utf16_to_utf8(arg_buf)) == NULL)
|
if ((shell_arguments_local = utf16_to_utf8(arg_buf)) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
convertToBackslash(pw_shellpath_local);
|
convertToBackslash(pw_shellpath_local);
|
||||||
to_lower_case(pw_shellpath_local);
|
to_lower_case(pw_shellpath_local);
|
||||||
pw_shellpath = pw_shellpath_local;
|
pw_shellpath = pw_shellpath_local;
|
||||||
pw_shellpath_local = NULL;
|
pw_shellpath_local = NULL;
|
||||||
shell_command_option = command_option_local;
|
shell_command_option = command_option_local;
|
||||||
shell_arguments = shell_arguments_local;
|
shell_arguments = shell_arguments_local;
|
||||||
command_option_local = NULL;
|
command_option_local = NULL;
|
||||||
shell_arguments_local = NULL;
|
shell_arguments_local = NULL;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
if (pw_shellpath_local)
|
if (pw_shellpath_local)
|
||||||
free(pw_shellpath_local);
|
free(pw_shellpath_local);
|
||||||
|
|
||||||
if (command_option_local)
|
if (command_option_local)
|
||||||
free(command_option_local);
|
free(command_option_local);
|
||||||
|
|
||||||
if (shell_arguments_local)
|
if (shell_arguments_local)
|
||||||
free(shell_arguments_local);
|
free(shell_arguments_local);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
initialize_pw()
|
initialize_pw()
|
||||||
{
|
{
|
||||||
if (set_defaultshell() != 0)
|
if (set_defaultshell() != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pw.pw_shell != pw_shellpath) {
|
if (pw.pw_shell != pw_shellpath) {
|
||||||
memset(&pw, 0, sizeof(pw));
|
memset(&pw, 0, sizeof(pw));
|
||||||
pw.pw_shell = pw_shellpath;
|
pw.pw_shell = pw_shellpath;
|
||||||
pw.pw_passwd = "\0";
|
pw.pw_passwd = "\0";
|
||||||
/* pw_uid = 0 for root on Unix and SSH code has specific restrictions for root
|
/* pw_uid = 0 for root on Unix and SSH code has specific restrictions for root
|
||||||
* that are not applicable in Windows */
|
* that are not applicable in Windows */
|
||||||
pw.pw_uid = 1;
|
pw.pw_uid = 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clean_pw()
|
clean_pw()
|
||||||
{
|
{
|
||||||
if (pw.pw_name)
|
if (pw.pw_name)
|
||||||
free(pw.pw_name);
|
free(pw.pw_name);
|
||||||
if (pw.pw_dir)
|
if (pw.pw_dir)
|
||||||
free(pw.pw_dir);
|
free(pw.pw_dir);
|
||||||
pw.pw_name = NULL;
|
pw.pw_name = NULL;
|
||||||
pw.pw_dir = NULL;
|
pw.pw_dir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
reset_pw()
|
reset_pw()
|
||||||
{
|
{
|
||||||
if (initialize_pw() != 0)
|
if (initialize_pw() != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
clean_pw();
|
clean_pw();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct passwd*
|
static struct passwd*
|
||||||
get_passwd(const wchar_t * user_utf16, PSID sid)
|
get_passwd(const wchar_t * user_utf16, PSID sid)
|
||||||
{
|
{
|
||||||
wchar_t user_resolved[DNLEN + 1 + UNLEN + 1];
|
wchar_t user_resolved[DNLEN + 1 + UNLEN + 1];
|
||||||
struct passwd *ret = NULL;
|
struct passwd *ret = NULL;
|
||||||
wchar_t *sid_string = NULL, *tmp = NULL, *user_utf16_modified = NULL;
|
wchar_t *sid_string = NULL, *tmp = NULL, *user_utf16_modified = NULL;
|
||||||
wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX], profile_home_exp[PATH_MAX];
|
wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX], profile_home_exp[PATH_MAX];
|
||||||
DWORD reg_path_len = PATH_MAX;
|
DWORD reg_path_len = PATH_MAX;
|
||||||
HKEY reg_key = 0;
|
HKEY reg_key = 0;
|
||||||
|
|
||||||
BYTE binary_sid[SECURITY_MAX_SID_SIZE];
|
BYTE binary_sid[SECURITY_MAX_SID_SIZE];
|
||||||
DWORD sid_size = ARRAYSIZE(binary_sid);
|
DWORD sid_size = ARRAYSIZE(binary_sid);
|
||||||
WCHAR domain_name[DNLEN + 1] = L"";
|
WCHAR domain_name[DNLEN + 1] = L"";
|
||||||
DWORD domain_name_size = DNLEN + 1;
|
DWORD domain_name_size = DNLEN + 1;
|
||||||
SID_NAME_USE account_type = 0;
|
SID_NAME_USE account_type = 0;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (reset_pw() != 0)
|
if (reset_pw() != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We support both "domain\user" and "domain/user" formats.
|
* We support both "domain\user" and "domain/user" formats.
|
||||||
* But win32 APIs only accept domain\user format so convert it.
|
* But win32 APIs only accept domain\user format so convert it.
|
||||||
*/
|
*/
|
||||||
if (user_utf16) {
|
if (user_utf16) {
|
||||||
user_utf16_modified = _wcsdup(user_utf16);
|
user_utf16_modified = _wcsdup(user_utf16);
|
||||||
if (!user_utf16_modified) {
|
if (!user_utf16_modified) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
error("%s failed to duplicate %s", __func__, user_utf16);
|
error("%s failed to duplicate %s", __func__, user_utf16);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp = wcsstr(user_utf16_modified, L"/"))
|
if (tmp = wcsstr(user_utf16_modified, L"/"))
|
||||||
*tmp = L'\\';
|
*tmp = L'\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip forward lookup on name if sid was passed in */
|
/* skip forward lookup on name if sid was passed in */
|
||||||
if (sid != NULL)
|
if (sid != NULL)
|
||||||
CopySid(sizeof(binary_sid), binary_sid, sid);
|
CopySid(sizeof(binary_sid), binary_sid, sid);
|
||||||
/* else attempt to lookup the account; this will verify the account is valid and
|
/* else attempt to lookup the account; this will verify the account is valid and
|
||||||
* is will return its sid and the realm that owns it */
|
* is will return its sid and the realm that owns it */
|
||||||
else if(LookupAccountNameW(NULL, user_utf16_modified, binary_sid, &sid_size,
|
else if (lookup_sid(user_utf16_modified, binary_sid, &sid_size) == NULL) {
|
||||||
domain_name, &domain_name_size, &account_type) == 0) {
|
errno = ENOENT;
|
||||||
errno = ENOENT;
|
debug("%s: lookup_sid() failed: %d.", __FUNCTION__, GetLastError());
|
||||||
debug("%s: LookupAccountName() failed: %d.", __FUNCTION__, GetLastError());
|
goto cleanup;
|
||||||
goto cleanup;
|
}
|
||||||
}
|
|
||||||
|
/* convert the binary string to a string */
|
||||||
/* convert the binary string to a string */
|
if (ConvertSidToStringSidW((PSID) binary_sid, &sid_string) == FALSE) {
|
||||||
if (ConvertSidToStringSidW((PSID) binary_sid, &sid_string) == FALSE) {
|
errno = errno_from_Win32LastError();
|
||||||
errno = errno_from_Win32LastError();
|
goto cleanup;
|
||||||
goto cleanup;
|
}
|
||||||
}
|
|
||||||
|
/* lookup the account name from the sid */
|
||||||
/* lookup the account name from the sid */
|
WCHAR user_name[UNLEN + 1];
|
||||||
WCHAR user_name[UNLEN + 1];
|
DWORD user_name_length = ARRAYSIZE(user_name);
|
||||||
DWORD user_name_length = ARRAYSIZE(user_name);
|
domain_name_size = DNLEN + 1;
|
||||||
domain_name_size = DNLEN + 1;
|
if (LookupAccountSidW(NULL, binary_sid, user_name, &user_name_length,
|
||||||
if (LookupAccountSidW(NULL, binary_sid, user_name, &user_name_length,
|
domain_name, &domain_name_size, &account_type) == 0) {
|
||||||
domain_name, &domain_name_size, &account_type) == 0) {
|
errno = errno_from_Win32LastError();
|
||||||
errno = errno_from_Win32LastError();
|
debug("%s: LookupAccountSid() failed: %d.", __FUNCTION__, GetLastError());
|
||||||
debug("%s: LookupAccountSid() failed: %d.", __FUNCTION__, GetLastError());
|
goto cleanup;
|
||||||
goto cleanup;
|
}
|
||||||
}
|
|
||||||
|
/* verify passed account is actually a user account */
|
||||||
/* verify passed account is actually a user account */
|
if (account_type != SidTypeUser) {
|
||||||
if (account_type != SidTypeUser) {
|
errno = ENOENT;
|
||||||
errno = ENOENT;
|
debug3("%s: Invalid account type: %d.", __FUNCTION__, account_type);
|
||||||
debug3("%s: Invalid account type: %d.", __FUNCTION__, account_type);
|
goto cleanup;
|
||||||
goto cleanup;
|
}
|
||||||
}
|
|
||||||
|
/* fetch the computer name so we can determine if the specified user is local or not */
|
||||||
/* fetch the computer name so we can determine if the specified user is local or not */
|
wchar_t computer_name[CNLEN + 1];
|
||||||
wchar_t computer_name[CNLEN + 1];
|
DWORD computer_name_size = ARRAYSIZE(computer_name);
|
||||||
DWORD computer_name_size = ARRAYSIZE(computer_name);
|
if (GetComputerNameW(computer_name, &computer_name_size) == 0) {
|
||||||
if (GetComputerNameW(computer_name, &computer_name_size) == 0) {
|
error_f("GetComputerNameW() failed with error:%d", GetLastError());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if standard local user name or system account, just use name without decoration */
|
/* if standard local user name or system account, just use name without decoration */
|
||||||
const SID_IDENTIFIER_AUTHORITY nt_authority = SECURITY_NT_AUTHORITY;
|
const SID_IDENTIFIER_AUTHORITY nt_authority = SECURITY_NT_AUTHORITY;
|
||||||
if (((_wcsicmp(domain_name, computer_name) == 0) && (_wcsicmp(computer_name, user_name) != 0)) ||
|
if ((_wcsicmp(domain_name, computer_name) == 0) ||
|
||||||
((memcmp(&nt_authority, GetSidIdentifierAuthority((PSID)binary_sid), sizeof(SID_IDENTIFIER_AUTHORITY)) == 0) &&
|
((memcmp(&nt_authority, GetSidIdentifierAuthority((PSID)binary_sid), sizeof(SID_IDENTIFIER_AUTHORITY)) == 0) &&
|
||||||
(((SID*)binary_sid)->SubAuthority[0] == SECURITY_LOCAL_SYSTEM_RID))) {
|
(((SID*)binary_sid)->SubAuthority[0] == SECURITY_LOCAL_SYSTEM_RID))) {
|
||||||
wcscpy_s(user_resolved, ARRAYSIZE(user_resolved), user_name);
|
wcscpy_s(user_resolved, ARRAYSIZE(user_resolved), user_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put any other format in sam compatible format */
|
/* put any other format in sam compatible format */
|
||||||
else
|
else
|
||||||
swprintf_s(user_resolved, ARRAYSIZE(user_resolved), L"%s\\%s", domain_name, user_name);
|
swprintf_s(user_resolved, ARRAYSIZE(user_resolved), L"%s\\%s", domain_name, user_name);
|
||||||
|
|
||||||
/* if one of below fails, set profile path to Windows directory */
|
/* if one of below fails, set profile path to Windows directory */
|
||||||
if (swprintf_s(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_string) == -1 ||
|
if (swprintf_s(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_string) == -1 ||
|
||||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_key) != 0 ||
|
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_key) != 0 ||
|
||||||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, ®_path_len) != 0 ||
|
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, ®_path_len) != 0 ||
|
||||||
ExpandEnvironmentStringsW(profile_home, NULL, 0) > PATH_MAX ||
|
ExpandEnvironmentStringsW(profile_home, NULL, 0) > PATH_MAX ||
|
||||||
ExpandEnvironmentStringsW(profile_home, profile_home_exp, PATH_MAX) == 0)
|
ExpandEnvironmentStringsW(profile_home, profile_home_exp, PATH_MAX) == 0)
|
||||||
if (GetWindowsDirectoryW(profile_home_exp, PATH_MAX) == 0) {
|
if (GetWindowsDirectoryW(profile_home_exp, PATH_MAX) == 0) {
|
||||||
debug3("GetWindowsDirectoryW failed with %d", GetLastError());
|
debug3("GetWindowsDirectoryW failed with %d", GetLastError());
|
||||||
errno = EOTHER;
|
errno = EOTHER;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert to utf8, make name lowercase, and assign to output structure*/
|
/* convert to utf8, make name lowercase, and assign to output structure*/
|
||||||
_wcslwr_s(user_resolved, wcslen(user_resolved) + 1);
|
_wcslwr_s(user_resolved, wcslen(user_resolved) + 1);
|
||||||
if ((pw.pw_name = utf16_to_utf8(user_resolved)) == NULL ||
|
if ((pw.pw_name = utf16_to_utf8(user_resolved)) == NULL ||
|
||||||
(pw.pw_dir = utf16_to_utf8(profile_home_exp)) == NULL) {
|
(pw.pw_dir = utf16_to_utf8(profile_home_exp)) == NULL) {
|
||||||
clean_pw();
|
clean_pw();
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = &pw;
|
ret = &pw;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
if (sid_string)
|
if (sid_string)
|
||||||
LocalFree(sid_string);
|
LocalFree(sid_string);
|
||||||
if (reg_key)
|
if (reg_key)
|
||||||
RegCloseKey(reg_key);
|
RegCloseKey(reg_key);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct passwd*
|
static struct passwd*
|
||||||
getpwnam_placeholder(const char* user) {
|
getpwnam_placeholder(const char* user) {
|
||||||
wchar_t tmp_home[PATH_MAX];
|
wchar_t tmp_home[PATH_MAX];
|
||||||
char *pw_name = NULL, *pw_dir = NULL;
|
char *pw_name = NULL, *pw_dir = NULL;
|
||||||
struct passwd* ret = NULL;
|
struct passwd* ret = NULL;
|
||||||
|
|
||||||
if (GetWindowsDirectoryW(tmp_home, PATH_MAX) == 0) {
|
if (GetWindowsDirectoryW(tmp_home, PATH_MAX) == 0) {
|
||||||
debug3("GetWindowsDirectoryW failed with %d", GetLastError());
|
debug3("GetWindowsDirectoryW failed with %d", GetLastError());
|
||||||
errno = EOTHER;
|
errno = EOTHER;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
pw_name = _strdup(user);
|
pw_name = _strdup(user);
|
||||||
pw_dir = utf16_to_utf8(tmp_home);
|
pw_dir = utf16_to_utf8(tmp_home);
|
||||||
|
|
||||||
if (!pw_name || !pw_dir) {
|
if (!pw_name || !pw_dir) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.pw_name = pw_name;
|
pw.pw_name = pw_name;
|
||||||
pw_name = NULL;
|
pw_name = NULL;
|
||||||
pw.pw_dir = pw_dir;
|
pw.pw_dir = pw_dir;
|
||||||
pw_dir = NULL;
|
pw_dir = NULL;
|
||||||
|
|
||||||
ret = &pw;
|
ret = &pw;
|
||||||
cleanup:
|
cleanup:
|
||||||
if (pw_name)
|
if (pw_name)
|
||||||
free(pw_name);
|
free(pw_name);
|
||||||
if (pw_dir)
|
if (pw_dir)
|
||||||
free(pw_dir);
|
free(pw_dir);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct passwd*
|
struct passwd*
|
||||||
w32_getpwnam(const char *user_utf8)
|
w32_getpwnam(const char *user_utf8)
|
||||||
{
|
{
|
||||||
struct passwd* ret = NULL;
|
struct passwd* ret = NULL;
|
||||||
wchar_t * user_utf16 = NULL;
|
wchar_t * user_utf16 = NULL;
|
||||||
|
|
||||||
user_utf16 = utf8_to_utf16(user_utf8);
|
user_utf16 = utf8_to_utf16(user_utf8);
|
||||||
if (user_utf16 == NULL) {
|
if (user_utf16 == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = get_passwd(user_utf16, NULL);
|
ret = get_passwd(user_utf16, NULL);
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* for unpriviliged user account, create placeholder and return*/
|
/* for unpriviliged user account, create placeholder and return*/
|
||||||
if (_stricmp(user_utf8, "sshd") == 0) {
|
if (_stricmp(user_utf8, "sshd") == 0) {
|
||||||
ret = getpwnam_placeholder(user_utf8);
|
ret = getpwnam_placeholder(user_utf8);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if custom passwd auth is enabled */
|
/* check if custom passwd auth is enabled */
|
||||||
if (get_custom_lsa_package())
|
if (get_custom_lsa_package())
|
||||||
ret = getpwnam_placeholder(user_utf8);
|
ret = getpwnam_placeholder(user_utf8);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (user_utf16)
|
if (user_utf16)
|
||||||
free(user_utf16);
|
free(user_utf16);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct passwd*
|
struct passwd*
|
||||||
w32_getpwuid(uid_t uid)
|
w32_getpwuid(uid_t uid)
|
||||||
{
|
{
|
||||||
struct passwd* ret = NULL;
|
struct passwd* ret = NULL;
|
||||||
PSID cur_user_sid = NULL;
|
PSID cur_user_sid = NULL;
|
||||||
|
|
||||||
if ((cur_user_sid = get_sid(NULL)) == NULL)
|
if ((cur_user_sid = get_sid(NULL)) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = get_passwd(NULL, cur_user_sid);
|
ret = get_passwd(NULL, cur_user_sid);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (cur_user_sid)
|
if (cur_user_sid)
|
||||||
free(cur_user_sid);
|
free(cur_user_sid);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
group_from_gid(gid_t gid, int nogroup)
|
group_from_gid(gid_t gid, int nogroup)
|
||||||
{
|
{
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
user_from_uid(uid_t uid, int nouser)
|
user_from_uid(uid_t uid, int nouser)
|
||||||
{
|
{
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_t
|
uid_t
|
||||||
w32_getuid(void)
|
w32_getuid(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gid_t
|
gid_t
|
||||||
getgid(void)
|
getgid(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_t
|
uid_t
|
||||||
geteuid(void)
|
geteuid(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gid_t
|
gid_t
|
||||||
getegid(void)
|
getegid(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
setuid(uid_t uid)
|
setuid(uid_t uid)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
setgid(gid_t gid)
|
setgid(gid_t gid)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
seteuid(uid_t uid)
|
seteuid(uid_t uid)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
setegid(gid_t gid)
|
setegid(gid_t gid)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct passwd *getpwent(void)
|
struct passwd *getpwent(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setpwent(void)
|
void setpwent(void)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
endpwent(void)
|
endpwent(void)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user