- Clean up well-known privileges.

- Implement checking tokens for privileges in the server.
- Implement NtPrivilegeCheck.
This commit is contained in:
Robert Shearman 2005-04-22 21:17:15 +00:00 committed by Alexandre Julliard
parent 2a788026a3
commit d2ea92d14e
14 changed files with 244 additions and 30 deletions

View File

@ -376,6 +376,34 @@ NTSTATUS WINAPI NtAdjustGroupsToken(
return STATUS_NOT_IMPLEMENTED;
}
/******************************************************************************
* NtPrivilegeCheck [NTDLL.@]
* ZwPrivilegeCheck [NTDLL.@]
*/
NTSTATUS WINAPI NtPrivilegeCheck(
HANDLE ClientToken,
PPRIVILEGE_SET RequiredPrivileges,
PBOOLEAN Result)
{
NTSTATUS status;
SERVER_START_REQ( check_token_privileges )
{
req->handle = ClientToken;
req->all_required = ((RequiredPrivileges->Control & PRIVILEGE_SET_ALL_NECESSARY) ? TRUE : FALSE);
wine_server_add_data( req, &RequiredPrivileges->Privilege,
RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
wine_server_set_reply( req, &RequiredPrivileges->Privilege,
RequiredPrivileges->PrivilegeCount * sizeof(RequiredPrivileges->Privilege[0]) );
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
*Result = (reply->has_privileges ? TRUE : FALSE);
}
SERVER_END_REQ;
return status;
}
/*
* Section
*/

View File

@ -156,7 +156,7 @@
@ stdcall NtOpenTimer(ptr long ptr)
@ stub NtPlugPlayControl
@ stdcall NtPowerInformation(long ptr long ptr long)
@ stub NtPrivilegeCheck
@ stdcall NtPrivilegeCheck(ptr ptr ptr)
@ stub NtPrivilegeObjectAuditAlarm
@ stub NtPrivilegedServiceAuditAlarm
@ stdcall NtProtectVirtualMemory(long ptr ptr long ptr)
@ -746,7 +746,7 @@
@ stdcall ZwOpenThreadToken(long long long long) NtOpenThreadToken
@ stdcall ZwOpenTimer(ptr long ptr) NtOpenTimer
@ stub ZwPlugPlayControl
@ stub ZwPrivilegeCheck
@ stdcall ZwPrivilegeCheck(ptr ptr ptr) NtPrivilegeCheck
@ stub ZwPrivilegeObjectAuditAlarm
@ stub ZwPrivilegedServiceAuditAlarm
@ stdcall ZwProtectVirtualMemory(long ptr ptr long ptr) NtProtectVirtualMemory

View File

@ -3237,6 +3237,21 @@ struct get_token_privileges_reply
/* VARARG(privileges,LUID_AND_ATTRIBUTES); */
};
struct check_token_privileges_request
{
struct request_header __header;
obj_handle_t handle;
int all_required;
/* VARARG(privileges,LUID_AND_ATTRIBUTES); */
};
struct check_token_privileges_reply
{
struct reply_header __header;
int has_privileges;
/* VARARG(privileges,LUID_AND_ATTRIBUTES); */
};
struct duplicate_token_request
{
struct request_header __header;
@ -3490,6 +3505,7 @@ enum request
REQ_set_global_windows,
REQ_adjust_token_privileges,
REQ_get_token_privileges,
REQ_check_token_privileges,
REQ_duplicate_token,
REQ_create_mailslot,
REQ_open_mailslot,
@ -3685,6 +3701,7 @@ union generic_request
struct set_global_windows_request set_global_windows_request;
struct adjust_token_privileges_request adjust_token_privileges_request;
struct get_token_privileges_request get_token_privileges_request;
struct check_token_privileges_request check_token_privileges_request;
struct duplicate_token_request duplicate_token_request;
struct create_mailslot_request create_mailslot_request;
struct open_mailslot_request open_mailslot_request;
@ -3878,12 +3895,13 @@ union generic_reply
struct set_global_windows_reply set_global_windows_reply;
struct adjust_token_privileges_reply adjust_token_privileges_reply;
struct get_token_privileges_reply get_token_privileges_reply;
struct check_token_privileges_reply check_token_privileges_reply;
struct duplicate_token_reply duplicate_token_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 169
#define SERVER_PROTOCOL_VERSION 170
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -2823,6 +2823,8 @@ typedef struct _ACL_SIZE_INFORMATION
#define SE_PRIVILEGE_REMOVE 0x00000004
#define SE_PRIVILEGE_USED_FOR_ACCESS 0x80000000
#define PRIVILEGE_SET_ALL_NECESSARY 1
#define SE_OWNER_DEFAULTED 0x00000001
#define SE_GROUP_DEFAULTED 0x00000002
#define SE_DACL_PRESENT 0x00000004

View File

@ -1469,6 +1469,7 @@ NTSTATUS WINAPI NtOpenThread(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const
NTSTATUS WINAPI NtOpenThreadToken(HANDLE,DWORD,BOOLEAN,HANDLE *);
NTSTATUS WINAPI NtOpenTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*);
NTSTATUS WINAPI NtPowerInformation(POWER_INFORMATION_LEVEL,PVOID,ULONG,PVOID,ULONG);
NTSTATUS WINAPI NtPrivilegeCheck(HANDLE,PPRIVILEGE_SET,PBOOLEAN);
NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*);
NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG);
NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR);

View File

@ -149,10 +149,6 @@ extern void registry_close_handle( struct object *obj, obj_handle_t hkey );
extern void init_signals(void);
extern void close_signals(void);
/* token functions */
extern struct token *create_admin_token(void);
/* atom functions */
extern void close_atom_table(void);

View File

@ -48,6 +48,7 @@
#include "request.h"
#include "console.h"
#include "user.h"
#include "security.h"
/* process structure */
@ -284,7 +285,7 @@ struct thread *create_process( int fd )
process->exe.namelen = 0;
process->exe.filename = NULL;
process->group_id = 0;
process->token = create_admin_token();
process->token = token_create_admin();
list_init( &process->thread_list );
list_init( &process->locks );
list_init( &process->classes );

View File

@ -2275,6 +2275,16 @@ enum message_type
VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges held by or available to a token */
@END
/* Check the token has the required privileges */
@REQ(check_token_privileges)
obj_handle_t handle; /* handle to the token */
int all_required; /* are all the privileges required for the check to succeed? */
VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges to check */
@REPLY
int has_privileges; /* does the token have the required privileges? */
VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges held by or available to a token */
@END
@REQ(duplicate_token)
obj_handle_t handle; /* handle to the token to duplicate */
unsigned int access; /* access rights to the new token */

View File

@ -287,6 +287,7 @@ DECL_HANDLER(open_token);
DECL_HANDLER(set_global_windows);
DECL_HANDLER(adjust_token_privileges);
DECL_HANDLER(get_token_privileges);
DECL_HANDLER(check_token_privileges);
DECL_HANDLER(duplicate_token);
DECL_HANDLER(create_mailslot);
DECL_HANDLER(open_mailslot);
@ -481,6 +482,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_set_global_windows,
(req_handler)req_adjust_token_privileges,
(req_handler)req_get_token_privileges,
(req_handler)req_check_token_privileges,
(req_handler)req_duplicate_token,
(req_handler)req_create_mailslot,
(req_handler)req_open_mailslot,

55
server/security.h Normal file
View File

@ -0,0 +1,55 @@
/*
* Security Management
*
* Copyright (C) 2005 Robert Shearman
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
extern const LUID SeIncreaseQuotaPrivilege;
extern const LUID SeSecurityPrivilege;
extern const LUID SeTakeOwnershipPrivilege;
extern const LUID SeLoadDriverPrivilege;
extern const LUID SeSystemProfilePrivilege;
extern const LUID SeSystemtimePrivilege;
extern const LUID SeProfileSingleProcessPrivilege;
extern const LUID SeIncreaseBasePriorityPrivilege;
extern const LUID SeCreatePagefilePrivilege;
extern const LUID SeBackupPrivilege;
extern const LUID SeRestorePrivilege;
extern const LUID SeShutdownPrivilege;
extern const LUID SeDebugPrivilege;
extern const LUID SeSystemEnvironmentPrivilege;
extern const LUID SeChangeNotifyPrivilege;
extern const LUID SeRemoteShutdownPrivilege;
extern const LUID SeUndockPrivilege;
extern const LUID SeManageVolumePrivilege;
extern const LUID SeImpersonatePrivilege;
extern const LUID SeCreateGlobalPrivilege;
extern struct token *token_create_admin(void);
extern int token_check_privileges( struct token *token, int all_required,
const LUID_AND_ATTRIBUTES *reqprivs,
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
static inline int thread_single_check_privilege( struct thread *thread, const LUID *priv)
{
struct token *token = thread_get_impersonation_token( thread );
const LUID_AND_ATTRIBUTES privs = { *priv, 0 };
if (!token) return FALSE;
return token_check_privileges( token, TRUE, &privs, 1, NULL );
}

View File

@ -767,6 +767,15 @@ struct thread_snapshot *thread_snap( int *count )
return snapshot;
}
/* gets the current impersonation token */
struct token *thread_get_impersonation_token( struct thread *thread )
{
if (thread->token)
return thread->token;
else
return thread->process->token;
}
/* signal that we are finished booting on the client side */
DECL_HANDLER(boot_done)
{

View File

@ -114,6 +114,7 @@ extern void thread_cancel_apc( struct thread *thread, struct object *owner, int
extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
extern int thread_get_inflight_fd( struct thread *thread, int client );
extern struct thread_snapshot *thread_snap( int *count );
extern struct token *thread_get_impersonation_token( struct thread *thread );
/* ptrace functions */

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 1998 Alexandre Julliard
* Copyright (C) 2003 Mike McCormack
* Copyright (C) 2005 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -31,6 +32,28 @@
#include "thread.h"
#include "process.h"
#include "request.h"
#include "security.h"
const LUID SeIncreaseQuotaPrivilege = { 5, 0 };
const LUID SeSecurityPrivilege = { 8, 0 };
const LUID SeTakeOwnershipPrivilege = { 9, 0 };
const LUID SeLoadDriverPrivilege = { 10, 0 };
const LUID SeSystemProfilePrivilege = { 11, 0 };
const LUID SeSystemtimePrivilege = { 12, 0 };
const LUID SeProfileSingleProcessPrivilege = { 13, 0 };
const LUID SeIncreaseBasePriorityPrivilege = { 14, 0 };
const LUID SeCreatePagefilePrivilege = { 15, 0 };
const LUID SeBackupPrivilege = { 17, 0 };
const LUID SeRestorePrivilege = { 18, 0 };
const LUID SeShutdownPrivilege = { 19, 0 };
const LUID SeDebugPrivilege = { 20, 0 };
const LUID SeSystemEnvironmentPrivilege = { 22, 0 };
const LUID SeChangeNotifyPrivilege = { 23, 0 };
const LUID SeRemoteShutdownPrivilege = { 24, 0 };
const LUID SeUndockPrivilege = { 25, 0 };
const LUID SeManageVolumePrivilege = { 28, 0 };
const LUID SeImpersonatePrivilege = { 29, 0 };
const LUID SeCreateGlobalPrivilege = { 30, 0 };
struct token
{
@ -135,30 +158,30 @@ static struct token *create_token( const LUID_AND_ATTRIBUTES *privs, unsigned in
return token;
}
struct token *create_admin_token( void )
struct token *token_create_admin( void )
{
static const LUID_AND_ATTRIBUTES admin_privs[] =
const LUID_AND_ATTRIBUTES admin_privs[] =
{
{ { 23, 0 }, SE_PRIVILEGE_ENABLED }, /* SeChangeNotifyPrivilege */
{ { 8, 0 }, 0 }, /* SeSecurityPrivilege */
{ { 17, 0 }, 0 }, /* SeBackupPrivilege */
{ { 18, 0 }, 0 }, /* SeRestorePrivilege */
{ { 12, 0 }, 0 }, /* SeSystemtimePrivilege */
{ { 19, 0 }, 0 }, /* SeShutdownPrivilege */
{ { 24, 0 }, 0 }, /* SeRemoteShutdownPrivilege */
{ { 9, 0 }, 0 }, /* SeTakeOwnershipPrivilege */
{ { 20, 0 }, 0 }, /* SeDebugPrivilege */
{ { 22, 0 }, 0 }, /* SeSystemEnvironmentPrivilege */
{ { 11, 0 }, 0 }, /* SeSystemProfilePrivilege */
{ { 13, 0 }, 0 }, /* SeProfileSingleProcessPrivilege */
{ { 14, 0 }, 0 }, /* SeIncreaseBasePriorityPrivilege */
{ { 10, 0 }, 0 }, /* SeLoadDriverPrivilege */
{ { 15, 0 }, 0 }, /* SeCreatePagefilePrivilege */
{ { 5, 0 }, 0 }, /* SeIncreaseQuotaPrivilege */
{ { 25, 0 }, 0 }, /* SeUndockPrivilege */
{ { 28, 0 }, 0 }, /* SeManageVolumePrivilege */
{ { 29, 0 }, SE_PRIVILEGE_ENABLED }, /* SeImpersonatePrivilege */
{ { 30, 0 }, SE_PRIVILEGE_ENABLED }, /* SeCreateGlobalPrivilege */
{ SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED },
{ SeSecurityPrivilege , 0 },
{ SeBackupPrivilege , 0 },
{ SeRestorePrivilege , 0 },
{ SeSystemtimePrivilege , 0 },
{ SeShutdownPrivilege , 0 },
{ SeRemoteShutdownPrivilege , 0 },
{ SeTakeOwnershipPrivilege , 0 },
{ SeDebugPrivilege , 0 },
{ SeSystemEnvironmentPrivilege , 0 },
{ SeSystemProfilePrivilege , 0 },
{ SeProfileSingleProcessPrivilege, 0 },
{ SeIncreaseBasePriorityPrivilege, 0 },
{ SeLoadDriverPrivilege , 0 },
{ SeCreatePagefilePrivilege , 0 },
{ SeIncreaseQuotaPrivilege , 0 },
{ SeUndockPrivilege , 0 },
{ SeManageVolumePrivilege , 0 },
{ SeImpersonatePrivilege , SE_PRIVILEGE_ENABLED },
{ SeCreateGlobalPrivilege , SE_PRIVILEGE_ENABLED },
};
return create_token( admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]) );
}
@ -224,6 +247,35 @@ static void token_disable_privileges( struct token *token )
privilege->enabled = FALSE;
}
int token_check_privileges( struct token *token, int all_required,
const LUID_AND_ATTRIBUTES *reqprivs,
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs)
{
int i;
unsigned int enabled_count = 0;
for (i = 0; i < count; i++)
{
struct privilege *privilege =
token_find_privilege( token, &reqprivs[i].Luid, TRUE );
if (usedprivs)
usedprivs[i] = reqprivs[i];
if (privilege && privilege->enabled)
{
enabled_count++;
if (usedprivs)
usedprivs[i].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
}
}
if (all_required)
return (enabled_count == count);
else
return (enabled_count > 0);
}
/* open a security token */
DECL_HANDLER(open_token)
{
@ -360,3 +412,24 @@ DECL_HANDLER(duplicate_token)
release_object( src_token );
}
}
/* checks the specified privileges are held by the token */
DECL_HANDLER(check_token_privileges)
{
struct token *token;
if ((token = (struct token *)get_handle_obj( current->process, req->handle,
TOKEN_QUERY,
&token_ops )))
{
unsigned int count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
if (get_reply_max_size() >= count * sizeof(LUID_AND_ATTRIBUTES))
{
LUID_AND_ATTRIBUTES *usedprivs = set_reply_data_size( count * sizeof(*usedprivs) );
reply->has_privileges = token_check_privileges( token, req->all_required, get_req_data(), count, usedprivs );
}
else
set_error( STATUS_BUFFER_OVERFLOW );
release_object( token );
}
}

View File

@ -2689,6 +2689,21 @@ static void dump_get_token_privileges_reply( const struct get_token_privileges_r
dump_varargs_LUID_AND_ATTRIBUTES( cur_size );
}
static void dump_check_token_privileges_request( const struct check_token_privileges_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " all_required=%d,", req->all_required );
fprintf( stderr, " privileges=" );
dump_varargs_LUID_AND_ATTRIBUTES( cur_size );
}
static void dump_check_token_privileges_reply( const struct check_token_privileges_reply *req )
{
fprintf( stderr, " has_privileges=%d,", req->has_privileges );
fprintf( stderr, " privileges=" );
dump_varargs_LUID_AND_ATTRIBUTES( cur_size );
}
static void dump_duplicate_token_request( const struct duplicate_token_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
@ -2931,6 +2946,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_global_windows_request,
(dump_func)dump_adjust_token_privileges_request,
(dump_func)dump_get_token_privileges_request,
(dump_func)dump_check_token_privileges_request,
(dump_func)dump_duplicate_token_request,
(dump_func)dump_create_mailslot_request,
(dump_func)dump_open_mailslot_request,
@ -3122,6 +3138,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_global_windows_reply,
(dump_func)dump_adjust_token_privileges_reply,
(dump_func)dump_get_token_privileges_reply,
(dump_func)dump_check_token_privileges_reply,
(dump_func)dump_duplicate_token_reply,
(dump_func)dump_create_mailslot_reply,
(dump_func)dump_open_mailslot_reply,
@ -3313,6 +3330,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_global_windows",
"adjust_token_privileges",
"get_token_privileges",
"check_token_privileges",
"duplicate_token",
"create_mailslot",
"open_mailslot",