From 91eaea53ae301d5c6fc4a0606518191408db8a90 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Mon, 18 Jul 2005 13:22:55 +0000 Subject: [PATCH] - Change the default user SID to match what was previously returned by NtQueryInformationToken. - Implement TokenUser for NtQueryInformationToken. - Add a function for getting the user's registry path from a SID. --- dlls/ntdll/nt.c | 21 ++++++++++------- include/wine/server_protocol.h | 17 +++++++++++++- server/protocol.def | 7 ++++++ server/registry.c | 31 ++++++++++++++++++++---- server/request.h | 2 ++ server/security.h | 2 ++ server/token.c | 43 ++++++++++++++++++++++++++++------ server/trace.c | 22 +++++++++++++++++ 8 files changed, 125 insertions(+), 20 deletions(-) diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index de489f1b17e..d9ba0560607 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -196,9 +196,6 @@ NTSTATUS WINAPI NtQueryInformationToken( switch (tokeninfoclass) { - case TokenUser: - len = sizeof(TOKEN_USER) + sizeof(SID); - break; case TokenGroups: len = sizeof(TOKEN_GROUPS); break; @@ -232,15 +229,23 @@ NTSTATUS WINAPI NtQueryInformationToken( switch (tokeninfoclass) { case TokenUser: - if( tokeninfo ) + SERVER_START_REQ( get_token_user ) { TOKEN_USER * tuser = tokeninfo; PSID sid = (PSID) (tuser + 1); - SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY}; - RtlInitializeSid(sid, &localSidAuthority, 1); - *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID; - tuser->User.Sid = sid; + DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER); + + req->handle = token; + wine_server_set_reply( req, sid, sid_len ); + status = wine_server_call( req ); + *retlen = reply->user_len + sizeof(TOKEN_USER); + if (status == STATUS_SUCCESS) + { + tuser->User.Sid = sid; + tuser->User.Attributes = 0; + } } + SERVER_END_REQ; break; case TokenGroups: if (tokeninfo) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index be5317fa982..b8e16c3ebfc 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3487,6 +3487,18 @@ struct access_check_reply /* VARARG(privileges,LUID_AND_ATTRIBUTES); */ }; +struct get_token_user_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_token_user_reply +{ + struct reply_header __header; + size_t user_len; + /* VARARG(user,SID); */ +}; + struct create_mailslot_request { @@ -3739,6 +3751,7 @@ enum request REQ_check_token_privileges, REQ_duplicate_token, REQ_access_check, + REQ_get_token_user, REQ_create_mailslot, REQ_open_mailslot, REQ_set_mailslot_info, @@ -3948,6 +3961,7 @@ union generic_request struct check_token_privileges_request check_token_privileges_request; struct duplicate_token_request duplicate_token_request; struct access_check_request access_check_request; + struct get_token_user_request get_token_user_request; struct create_mailslot_request create_mailslot_request; struct open_mailslot_request open_mailslot_request; struct set_mailslot_info_request set_mailslot_info_request; @@ -4155,11 +4169,12 @@ union generic_reply struct check_token_privileges_reply check_token_privileges_reply; struct duplicate_token_reply duplicate_token_reply; struct access_check_reply access_check_reply; + struct get_token_user_reply get_token_user_reply; struct create_mailslot_reply create_mailslot_reply; struct open_mailslot_reply open_mailslot_reply; struct set_mailslot_info_reply set_mailslot_info_reply; }; -#define SERVER_PROTOCOL_VERSION 187 +#define SERVER_PROTOCOL_VERSION 188 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 25bc6d7a084..b18782d4d2f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2448,6 +2448,13 @@ enum message_type VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges used during access check */ @END +@REQ(get_token_user) + obj_handle_t handle; /* handle to the token */ +@REPLY + size_t user_len; /* length needed to store user */ + VARARG(user,SID); /* sid of the user the token represents */ +@END + /* Create a mailslot */ @REQ(create_mailslot) unsigned int max_msgsize; diff --git a/server/registry.c b/server/registry.c index 40fdc36b434..ba78e1b84c6 100644 --- a/server/registry.c +++ b/server/registry.c @@ -1421,14 +1421,34 @@ static void load_init_registry_from_file( const char *filename, struct key *key } } +static WCHAR *format_user_registry_path( const SID *sid ) +{ + static const WCHAR prefixW[] = {'U','s','e','r','\\','S',0}; + static const WCHAR formatW[] = {'-','%','u',0}; + WCHAR buffer[7 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES]; + WCHAR *p = buffer; + unsigned int i; + + strcpyW( p, prefixW ); + p += strlenW( prefixW ); + p += sprintfW( p, formatW, sid->Revision ); + p += sprintfW( p, formatW, MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5], + sid->IdentifierAuthority.Value[4] ), + MAKEWORD( sid->IdentifierAuthority.Value[3], + sid->IdentifierAuthority.Value[2] ))); + for (i = 0; i < sid->SubAuthorityCount; i++) + p += sprintfW( p, formatW, sid->SubAuthority[i] ); + + return memdup( buffer, (p + 1 - buffer) * sizeof(WCHAR) ); +} + /* registry initialisation */ void init_registry(void) { static const WCHAR root_name[] = { 0 }; static const WCHAR HKLM[] = { 'M','a','c','h','i','n','e' }; static const WCHAR HKU_default[] = { 'U','s','e','r','\\','.','D','e','f','a','u','l','t' }; - /* FIXME: hardcoded to match what NtQueryTokenInformation currently returns */ - static const WCHAR HKCU[] = {'U','s','e','r','\\','S','-','1','-','5','-','4',0}; + WCHAR *current_user_path; const char *config = wine_get_config_dir(); char *p, *filename; @@ -1465,9 +1485,12 @@ void init_registry(void) /* load user.reg into HKEY_CURRENT_USER */ - if (!(key = create_key( root_key, copy_path( HKCU, sizeof(HKCU), 0 ), - NULL, 0, time(NULL), &dummy ))) + /* FIXME: match default user in token.c. should get from process token instead */ + current_user_path = format_user_registry_path( security_interactive_sid ); + if (!current_user_path || + !(key = create_key( root_key, current_user_path, NULL, 0, time(NULL), &dummy ))) fatal_error( "could not create HKEY_CURRENT_USER registry key\n" ); + free( current_user_path ); strcpy( p, "/user.reg" ); load_init_registry_from_file( filename, key ); release_object( key ); diff --git a/server/request.h b/server/request.h index ea47a77536e..71dbc7d0078 100644 --- a/server/request.h +++ b/server/request.h @@ -302,6 +302,7 @@ DECL_HANDLER(get_token_privileges); DECL_HANDLER(check_token_privileges); DECL_HANDLER(duplicate_token); DECL_HANDLER(access_check); +DECL_HANDLER(get_token_user); DECL_HANDLER(create_mailslot); DECL_HANDLER(open_mailslot); DECL_HANDLER(set_mailslot_info); @@ -510,6 +511,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_check_token_privileges, (req_handler)req_duplicate_token, (req_handler)req_access_check, + (req_handler)req_get_token_user, (req_handler)req_create_mailslot, (req_handler)req_open_mailslot, (req_handler)req_set_mailslot_info, diff --git a/server/security.h b/server/security.h index 1864c4f106e..7fec9ed40d3 100644 --- a/server/security.h +++ b/server/security.h @@ -39,6 +39,8 @@ extern const LUID SeManageVolumePrivilege; extern const LUID SeImpersonatePrivilege; extern const LUID SeCreateGlobalPrivilege; +extern const PSID security_interactive_sid; + extern struct token *token_create_admin(void); extern int token_check_privileges( struct token *token, int all_required, const LUID_AND_ATTRIBUTES *reqprivs, diff --git a/server/token.c b/server/token.c index cdcd31da473..e42e891d844 100644 --- a/server/token.c +++ b/server/token.c @@ -34,6 +34,8 @@ #include "request.h" #include "security.h" +#include "wine/unicode.h" + #define MAX_SUBAUTH_COUNT 1 const LUID SeIncreaseQuotaPrivilege = { 5, 0 }; @@ -62,10 +64,11 @@ static const SID local_sid = { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY } static const SID interactive_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } }; static const SID authenticated_user_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } }; static const SID local_system_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } }; -static PSID security_world_sid = (PSID)&world_sid; -static PSID security_local_sid = (PSID)&local_sid; -static PSID security_interactive_sid = (PSID)&interactive_sid; -static PSID security_authenticated_user_sid = (PSID)&authenticated_user_sid; +static const PSID security_world_sid = (PSID)&world_sid; +static const PSID security_local_sid = (PSID)&local_sid; +const PSID security_interactive_sid = (PSID)&interactive_sid; +static const PSID security_authenticated_user_sid = (PSID)&authenticated_user_sid; +static const PSID security_local_system_sid = (PSID)&local_system_sid; struct token { @@ -557,9 +560,9 @@ struct token *token_create_admin( void ) { alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, { alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, }; - /* note: we just set the user sid to be the local system builtin sid - - * telling us what this should be is the job of a client-side program */ - token = create_token( TRUE, &local_system_sid, + /* note: we just set the user sid to be the interactive builtin sid - + * we should really translate the UNIX user id to a sid */ + token = create_token( TRUE, &interactive_sid, admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]), admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]), default_dacl ); @@ -1091,3 +1094,29 @@ DECL_HANDLER(access_check) release_object( token ); } } + +/* */ +DECL_HANDLER(get_token_user) +{ + struct token *token; + + reply->user_len = 0; + + if ((token = (struct token *)get_handle_obj( current->process, req->handle, + TOKEN_QUERY, + &token_ops ))) + { + const SID *user = token->user; + + reply->user_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]); + if (reply->user_len <= get_reply_max_size()) + { + SID *user_reply = set_reply_data_size( reply->user_len ); + if (user_reply) + memcpy( user_reply, user, reply->user_len ); + } + else set_error( STATUS_BUFFER_TOO_SMALL ); + + release_object( token ); + } +} diff --git a/server/trace.c b/server/trace.c index 304cc6ac998..94139568466 100644 --- a/server/trace.c +++ b/server/trace.c @@ -446,6 +446,13 @@ static void dump_inline_sid( const SID *sid, size_t size ) fputc( '}', stderr ); } +static void dump_varargs_SID( size_t size ) +{ + const SID *sid = cur_data; + dump_inline_sid( sid, size ); + remove_data( size ); +} + static void dump_inline_acl( const ACL *acl, size_t size ) { const ACE_HEADER *ace; @@ -3011,6 +3018,18 @@ static void dump_access_check_reply( const struct access_check_reply *req ) dump_varargs_LUID_AND_ATTRIBUTES( cur_size ); } +static void dump_get_token_user_request( const struct get_token_user_request *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_get_token_user_reply( const struct get_token_user_reply *req ) +{ + fprintf( stderr, " user_len=%d,", req->user_len ); + fprintf( stderr, " user=" ); + dump_varargs_SID( cur_size ); +} + static void dump_create_mailslot_request( const struct create_mailslot_request *req ) { fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize ); @@ -3254,6 +3273,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_check_token_privileges_request, (dump_func)dump_duplicate_token_request, (dump_func)dump_access_check_request, + (dump_func)dump_get_token_user_request, (dump_func)dump_create_mailslot_request, (dump_func)dump_open_mailslot_request, (dump_func)dump_set_mailslot_info_request, @@ -3459,6 +3479,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_check_token_privileges_reply, (dump_func)dump_duplicate_token_reply, (dump_func)dump_access_check_reply, + (dump_func)dump_get_token_user_reply, (dump_func)dump_create_mailslot_reply, (dump_func)dump_open_mailslot_reply, (dump_func)dump_set_mailslot_info_reply, @@ -3664,6 +3685,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "check_token_privileges", "duplicate_token", "access_check", + "get_token_user", "create_mailslot", "open_mailslot", "set_mailslot_info",