mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-21 00:07:36 +08:00
* autoload.cc (CreateProfile): Import.
(LoadUserProfileW): Import. * registry.cc (get_registry_hive_path): Move to sec_auth.cc. (load_registry_hive): Remove. * registry.h (get_registry_hive_path): Drop declaration. (load_registry_hive): Ditto. * sec_auth.cc (get_user_profile_directory): Moved from registry.cc and renamed. Take third parameter with buffer length. (load_user_profile): New function taking over for load_registry_hive. Use official functions to load profile. If profile is missing, create it on Vista and later. * security.h (get_user_profile_directory): Declare. (load_user_profile): Declare. * syscalls.cc (seteuid32): Replace call to load_registry_hive with call to load_user_profile. * uinfo.cc (cygheap_user::env_userprofile): Replace call to get_registry_hive_path with call to get_user_profile_directory.
This commit is contained in:
parent
195a9205e5
commit
41f77e25f1
@ -1,3 +1,23 @@
|
|||||||
|
2014-12-02 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (CreateProfile): Import.
|
||||||
|
(LoadUserProfileW): Import.
|
||||||
|
* registry.cc (get_registry_hive_path): Move to sec_auth.cc.
|
||||||
|
(load_registry_hive): Remove.
|
||||||
|
* registry.h (get_registry_hive_path): Drop declaration.
|
||||||
|
(load_registry_hive): Ditto.
|
||||||
|
* sec_auth.cc (get_user_profile_directory): Moved from registry.cc and
|
||||||
|
renamed. Take third parameter with buffer length.
|
||||||
|
(load_user_profile): New function taking over for load_registry_hive.
|
||||||
|
Use official functions to load profile. If profile is missing, create
|
||||||
|
it on Vista and later.
|
||||||
|
* security.h (get_user_profile_directory): Declare.
|
||||||
|
(load_user_profile): Declare.
|
||||||
|
* syscalls.cc (seteuid32): Replace call to load_registry_hive with call
|
||||||
|
to load_user_profile.
|
||||||
|
* uinfo.cc (cygheap_user::env_userprofile): Replace call to
|
||||||
|
get_registry_hive_path with call to get_user_profile_directory.
|
||||||
|
|
||||||
2014-12-02 Corinna Vinschen <corinna@vinschen.de>
|
2014-12-02 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* uinfo.cc (fetch_from_description): Make static.
|
* uinfo.cc (fetch_from_description): Make static.
|
||||||
|
@ -676,7 +676,9 @@ LoadDLLfunc (SetProcessWindowStation, 4, user32)
|
|||||||
LoadDLLfunc (SetThreadDesktop, 4, user32)
|
LoadDLLfunc (SetThreadDesktop, 4, user32)
|
||||||
|
|
||||||
LoadDLLfunc (CreateEnvironmentBlock, 12, userenv)
|
LoadDLLfunc (CreateEnvironmentBlock, 12, userenv)
|
||||||
|
LoadDLLfuncEx2 (CreateProfile, 16, userenv, 1, 1)
|
||||||
LoadDLLfunc (DestroyEnvironmentBlock, 4, userenv)
|
LoadDLLfunc (DestroyEnvironmentBlock, 4, userenv)
|
||||||
|
LoadDLLfunc (LoadUserProfileW, 8, userenv)
|
||||||
|
|
||||||
LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 1, 0, 1)
|
LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 1, 0, 1)
|
||||||
LoadDLLfuncEx3 (waveInClose, 4, winmm, 1, 0, 1)
|
LoadDLLfuncEx3 (waveInClose, 4, winmm, 1, 0, 1)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* registry.cc: registry interface
|
/* registry.cc: registry interface
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
|
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -19,7 +19,6 @@ details. */
|
|||||||
#include "tls_pbuf.h"
|
#include "tls_pbuf.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <alloca.h>
|
|
||||||
|
|
||||||
/* Opens a key under the appropriate Cygwin key.
|
/* Opens a key under the appropriate Cygwin key.
|
||||||
Do not use HKCU per MS KB 199190 */
|
Do not use HKCU per MS KB 199190 */
|
||||||
@ -213,96 +212,3 @@ reg_key::~reg_key ()
|
|||||||
NtClose (key);
|
NtClose (key);
|
||||||
key_is_invalid = 1;
|
key_is_invalid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The buffer path points to should be at least MAX_PATH bytes. */
|
|
||||||
PWCHAR
|
|
||||||
get_registry_hive_path (PCWSTR name, PWCHAR path)
|
|
||||||
{
|
|
||||||
if (!name || !path)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
WCHAR key[256];
|
|
||||||
UNICODE_STRING buf;
|
|
||||||
tmp_pathbuf tp;
|
|
||||||
tp.u_get (&buf);
|
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
RTL_QUERY_REGISTRY_TABLE tab[2] = {
|
|
||||||
{ NULL, RTL_QUERY_REGISTRY_NOEXPAND | RTL_QUERY_REGISTRY_DIRECT
|
|
||||||
| RTL_QUERY_REGISTRY_REQUIRED,
|
|
||||||
L"ProfileImagePath", &buf, REG_NONE, NULL, 0 },
|
|
||||||
{ NULL, 0, NULL, NULL, 0, NULL, 0 }
|
|
||||||
};
|
|
||||||
wcpcpy (wcpcpy (key, L"ProfileList\\"), name);
|
|
||||||
status = RtlQueryRegistryValues (RTL_REGISTRY_WINDOWS_NT, key, tab,
|
|
||||||
NULL, NULL);
|
|
||||||
if (!NT_SUCCESS (status) || buf.Length == 0)
|
|
||||||
{
|
|
||||||
debug_printf ("ProfileImagePath for %W not found, status %y", name,
|
|
||||||
status);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ExpandEnvironmentStringsW (buf.Buffer, path, MAX_PATH);
|
|
||||||
debug_printf ("ProfileImagePath for %W: %W", name, path);
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
load_registry_hive (PCWSTR name)
|
|
||||||
{
|
|
||||||
if (!name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Fetch the path. Prepend native NT path prefix. */
|
|
||||||
tmp_pathbuf tp;
|
|
||||||
PWCHAR path = tp.w_get ();
|
|
||||||
if (!get_registry_hive_path (name, wcpcpy (path, L"\\??\\")))
|
|
||||||
return;
|
|
||||||
|
|
||||||
WCHAR key[256];
|
|
||||||
PWCHAR path_comp;
|
|
||||||
UNICODE_STRING ukey, upath;
|
|
||||||
OBJECT_ATTRIBUTES key_attr, path_attr;
|
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
/* Create keyname and path strings and object attributes. */
|
|
||||||
wcpcpy (wcpcpy (key, L"\\Registry\\User\\"), name);
|
|
||||||
RtlInitUnicodeString (&ukey, key);
|
|
||||||
InitializeObjectAttributes (&key_attr, &ukey, OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL, NULL);
|
|
||||||
/* First try to load the "normal" registry hive, which is what the user
|
|
||||||
is supposed to see under HKEY_CURRENT_USER. */
|
|
||||||
path_comp = wcschr (path, L'\0');
|
|
||||||
wcpcpy (path_comp, L"\\ntuser.dat");
|
|
||||||
RtlInitUnicodeString (&upath, path);
|
|
||||||
InitializeObjectAttributes (&path_attr, &upath, OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL, NULL);
|
|
||||||
status = NtLoadKey (&key_attr, &path_attr);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
debug_printf ("Loading user registry hive %S into %S failed: %y",
|
|
||||||
&upath, &ukey, status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debug_printf ("Loading user registry hive %S into %S SUCCEEDED: %y",
|
|
||||||
&upath, &ukey, status);
|
|
||||||
/* If loading the normal hive worked, try to load the classes hive into
|
|
||||||
the sibling *_Classes subkey, which is what the user is supposed to
|
|
||||||
see under HKEY_CLASSES_ROOT, merged with the machine-wide classes. */
|
|
||||||
wcscat (key, L"_Classes");
|
|
||||||
RtlInitUnicodeString (&ukey, key);
|
|
||||||
/* Path to UsrClass.dat changed in Vista to
|
|
||||||
\\AppData\\Local\\Microsoft\\Windows\\UsrClass.dat
|
|
||||||
but old path is still available via symlinks. */
|
|
||||||
wcpcpy (path_comp, L"\\Local Settings\\Application Data\\Microsoft\\"
|
|
||||||
"Windows\\UsrClass.dat");
|
|
||||||
RtlInitUnicodeString (&upath, path);
|
|
||||||
/* Load UsrClass.dat file into key. */
|
|
||||||
status = NtLoadKey (&key_attr, &path_attr);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
debug_printf ("Loading user classes hive %S into %S failed: %y",
|
|
||||||
&upath, &ukey, status);
|
|
||||||
else
|
|
||||||
debug_printf ("Loading user classes hive %S into %S SUCCEEDED: %y",
|
|
||||||
&upath, &ukey, status);
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* registry.h: shared info for cygwin
|
/* registry.h: shared info for cygwin
|
||||||
|
|
||||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
2011 Red Hat, Inc.
|
2011, 2012, 2014 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -37,7 +37,3 @@ public:
|
|||||||
|
|
||||||
~reg_key ();
|
~reg_key ();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Evaluates path to the directory of the local user registry hive */
|
|
||||||
PWCHAR __stdcall get_registry_hive_path (PCWSTR name, PWCHAR path);
|
|
||||||
void __stdcall load_registry_hive (PCWSTR name);
|
|
||||||
|
@ -20,10 +20,13 @@ details. */
|
|||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
#include "registry.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "tls_pbuf.h"
|
#include "tls_pbuf.h"
|
||||||
#include <lm.h>
|
#include <lm.h>
|
||||||
#include <iptypes.h>
|
#include <iptypes.h>
|
||||||
|
#include <wininet.h>
|
||||||
|
#include <userenv.h>
|
||||||
#include "cyglsa.h"
|
#include "cyglsa.h"
|
||||||
#include "cygserver_setpwd.h"
|
#include "cygserver_setpwd.h"
|
||||||
#include <cygwin/version.h>
|
#include <cygwin/version.h>
|
||||||
@ -172,6 +175,113 @@ cygwin_logon_user (const struct passwd *pw, const char *password)
|
|||||||
return hToken;
|
return hToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The buffer path points to should be at least MAX_PATH bytes. */
|
||||||
|
PWCHAR
|
||||||
|
get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len)
|
||||||
|
{
|
||||||
|
if (!sidstr || !path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
UNICODE_STRING buf;
|
||||||
|
tmp_pathbuf tp;
|
||||||
|
tp.u_get (&buf);
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
RTL_QUERY_REGISTRY_TABLE tab[2] = {
|
||||||
|
{ NULL, RTL_QUERY_REGISTRY_NOEXPAND | RTL_QUERY_REGISTRY_DIRECT
|
||||||
|
| RTL_QUERY_REGISTRY_REQUIRED,
|
||||||
|
L"ProfileImagePath", &buf, REG_NONE, NULL, 0 },
|
||||||
|
{ NULL, 0, NULL, NULL, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
WCHAR key[wcslen (sidstr) + 16];
|
||||||
|
wcpcpy (wcpcpy (key, L"ProfileList\\"), sidstr);
|
||||||
|
status = RtlQueryRegistryValues (RTL_REGISTRY_WINDOWS_NT, key, tab,
|
||||||
|
NULL, NULL);
|
||||||
|
if (!NT_SUCCESS (status) || buf.Length == 0)
|
||||||
|
{
|
||||||
|
debug_printf ("ProfileImagePath for %W not found, status %y", sidstr,
|
||||||
|
status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ExpandEnvironmentStringsW (buf.Buffer, path, path_len);
|
||||||
|
debug_printf ("ProfileImagePath for %W: %W", sidstr, path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The CreateProfile prototype is for some reason missing in our w32api headers,
|
||||||
|
even though it's defined upstream since Dec-2013. */
|
||||||
|
extern "C" {
|
||||||
|
HRESULT WINAPI CreateProfile (LPCWSTR pszUserSid, LPCWSTR pszUserName,
|
||||||
|
LPWSTR pszProfilePath, DWORD cchProfilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load user profile if it's not already loaded. If the user profile doesn't
|
||||||
|
exist on the machine, and if we're running Vista or later, try to create it.
|
||||||
|
|
||||||
|
Return a handle to the loaded user registry hive only if it got actually
|
||||||
|
loaded here, not if it already existed. There's no reliable way to know
|
||||||
|
when to unload the hive yet, so we're leaking this registry handle for now.
|
||||||
|
TODO: Try to find a way to reliably unload the user profile again. */
|
||||||
|
HANDLE
|
||||||
|
load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid)
|
||||||
|
{
|
||||||
|
WCHAR domain[DNLEN + 1];
|
||||||
|
WCHAR username[UNLEN + 1];
|
||||||
|
WCHAR sid[128];
|
||||||
|
HKEY hkey;
|
||||||
|
WCHAR userpath[MAX_PATH];
|
||||||
|
PROFILEINFOW pi;
|
||||||
|
WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
|
||||||
|
NET_API_STATUS nas = NERR_UserNotFound;
|
||||||
|
PUSER_INFO_3 ui;
|
||||||
|
|
||||||
|
extract_nt_dom_user (pw, domain, username);
|
||||||
|
usersid.string (sid);
|
||||||
|
debug_printf ("user: <%W> <%W>", username, sid);
|
||||||
|
/* Check if user hive is already loaded. */
|
||||||
|
if (!RegOpenKeyExW (HKEY_USERS, sid, 0, KEY_READ, &hkey))
|
||||||
|
{
|
||||||
|
debug_printf ("User registry hive for %W already exists", username);
|
||||||
|
RegCloseKey (hkey);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Check if the local profile dir has already been created. */
|
||||||
|
if (!get_user_profile_directory (sid, userpath, MAX_PATH))
|
||||||
|
{
|
||||||
|
/* No, try to create it. This function exists only on Vista and later. */
|
||||||
|
HRESULT res = CreateProfile (sid, username, userpath, MAX_PATH);
|
||||||
|
if (res != S_OK)
|
||||||
|
{
|
||||||
|
/* If res is 1 (S_FALSE), autoloading failed (XP or 2K3). */
|
||||||
|
if (res != S_FALSE)
|
||||||
|
debug_printf ("CreateProfile, HRESULT %x", res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Fill PROFILEINFO */
|
||||||
|
memset (&pi, 0, sizeof pi);
|
||||||
|
pi.dwSize = sizeof pi;
|
||||||
|
pi.dwFlags = PI_NOUI;
|
||||||
|
pi.lpUserName = username;
|
||||||
|
/* Check if user has a roaming profile and fill in lpProfilePath, if so. */
|
||||||
|
if (get_logon_server (domain, server, DS_IS_FLAT_NAME))
|
||||||
|
{
|
||||||
|
nas = NetUserGetInfo (server, username, 3, (PBYTE *) &ui);
|
||||||
|
if (NetUserGetInfo (server, username, 3, (PBYTE *) &ui) != NERR_Success)
|
||||||
|
debug_printf ("NetUserGetInfo, %u", nas);
|
||||||
|
else if (ui->usri3_profile && *ui->usri3_profile)
|
||||||
|
pi.lpProfilePath = ui->usri3_profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LoadUserProfileW (token, &pi))
|
||||||
|
debug_printf ("LoadUserProfileW, %E");
|
||||||
|
/* Free buffer created by NetUserGetInfo */
|
||||||
|
if (nas == NERR_Success)
|
||||||
|
NetApiBufferFree (ui);
|
||||||
|
return pi.hProfile;
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
lsa_open_policy (PWCHAR server, ACCESS_MASK access)
|
lsa_open_policy (PWCHAR server, ACCESS_MASK access)
|
||||||
{
|
{
|
||||||
|
@ -472,6 +472,12 @@ void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user);
|
|||||||
/* Get default logonserver for a domain. */
|
/* Get default logonserver for a domain. */
|
||||||
bool get_logon_server (PWCHAR domain, PWCHAR wserver, ULONG flags);
|
bool get_logon_server (PWCHAR domain, PWCHAR wserver, ULONG flags);
|
||||||
|
|
||||||
|
/* Fetch user profile path from registry, if it already exists. */
|
||||||
|
PWCHAR get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len);
|
||||||
|
|
||||||
|
/* Load user profile if it's not already loaded. */
|
||||||
|
HANDLE load_user_profile (HANDLE token, struct passwd *pw, cygpsid &sid);
|
||||||
|
|
||||||
HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access);
|
HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access);
|
||||||
void lsa_close_policy (HANDLE lsa);
|
void lsa_close_policy (HANDLE lsa);
|
||||||
|
|
||||||
|
@ -3387,11 +3387,7 @@ seteuid32 (uid_t uid)
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!request_restricted_uid_switch)
|
if (!request_restricted_uid_switch)
|
||||||
{
|
load_user_profile (new_token, pw_new, usersid);
|
||||||
/* Avoid having HKCU use default user */
|
|
||||||
WCHAR name[128];
|
|
||||||
load_registry_hive (usersid.string (name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try setting owner to same value as user. */
|
/* Try setting owner to same value as user. */
|
||||||
status = NtSetInformationToken (new_token, TokenOwner,
|
status = NtSetInformationToken (new_token, TokenOwner,
|
||||||
|
@ -482,13 +482,13 @@ cygheap_user::env_userprofile (const char *name, size_t namelen)
|
|||||||
if (test_uid (puserprof, name, namelen))
|
if (test_uid (puserprof, name, namelen))
|
||||||
return puserprof;
|
return puserprof;
|
||||||
|
|
||||||
/* User hive path is never longer than MAX_PATH. */
|
/* User profile path is never longer than MAX_PATH. */
|
||||||
WCHAR userprofile_env_buf[MAX_PATH];
|
WCHAR profile[MAX_PATH];
|
||||||
WCHAR win_id[UNLEN + 1]; /* Large enough for SID */
|
WCHAR win_id[UNLEN + 1]; /* Large enough for SID */
|
||||||
|
|
||||||
cfree_and_set (puserprof, almost_null);
|
cfree_and_set (puserprof, almost_null);
|
||||||
if (get_registry_hive_path (get_windows_id (win_id), userprofile_env_buf))
|
if (get_user_profile_directory (get_windows_id (win_id), profile, MAX_PATH))
|
||||||
sys_wcstombs_alloc (&puserprof, HEAP_STR, userprofile_env_buf);
|
sys_wcstombs_alloc (&puserprof, HEAP_STR, profile);
|
||||||
|
|
||||||
return puserprof;
|
return puserprof;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user