ntdll: Implement NtCreateToken().
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
This commit is contained in:
parent
509483356d
commit
a52cf805d2
12 changed files with 362 additions and 8 deletions
|
@ -192,7 +192,7 @@
|
|||
@ stdcall -syscall NtCreateThread(ptr long ptr long ptr ptr ptr long)
|
||||
@ stdcall -syscall NtCreateThreadEx(ptr long ptr long ptr ptr long long long long ptr)
|
||||
@ stdcall -syscall NtCreateTimer(ptr long ptr long)
|
||||
# @ stub NtCreateToken
|
||||
@ stdcall -syscall NtCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall -syscall NtCreateTransaction(ptr long ptr ptr long long long long ptr ptr)
|
||||
@ stdcall -syscall NtCreateUserProcess(ptr ptr long long ptr ptr long long ptr ptr ptr)
|
||||
# @ stub NtCreateWaitablePort
|
||||
|
@ -1241,7 +1241,7 @@
|
|||
@ stdcall -private -syscall ZwCreateThread(ptr long ptr long ptr ptr ptr long) NtCreateThread
|
||||
@ stdcall -private -syscall ZwCreateThreadEx(ptr long ptr long ptr ptr long long long long ptr) NtCreateThreadEx
|
||||
@ stdcall -private -syscall ZwCreateTimer(ptr long ptr long) NtCreateTimer
|
||||
# @ stub ZwCreateToken
|
||||
@ stdcall -private -syscall ZwCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) NtCreateToken
|
||||
@ stdcall -private -syscall ZwCreateUserProcess(ptr ptr long long ptr ptr long long ptr ptr ptr) NtCreateUserProcess
|
||||
# @ stub ZwCreateWaitablePort
|
||||
@ stdcall -private -syscall ZwDebugActiveProcess(long long) NtDebugActiveProcess
|
||||
|
|
|
@ -166,6 +166,7 @@ static void * const syscalls[] =
|
|||
NtCreateThread,
|
||||
NtCreateThreadEx,
|
||||
NtCreateTimer,
|
||||
NtCreateToken,
|
||||
NtCreateTransaction,
|
||||
NtCreateUserProcess,
|
||||
NtDebugActiveProcess,
|
||||
|
|
|
@ -36,6 +36,113 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||
|
||||
static BOOL is_equal_sid( const SID *sid1, const SID *sid2 )
|
||||
{
|
||||
size_t size1 = offsetof( SID, SubAuthority[sid1->SubAuthorityCount] );
|
||||
size_t size2 = offsetof( SID, SubAuthority[sid2->SubAuthorityCount] );
|
||||
return size1 == size2 && !memcmp( sid1, sid2, size1 );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtCreateToken (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtCreateToken( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||
TOKEN_TYPE type, LUID *token_id, LARGE_INTEGER *expire, TOKEN_USER *user,
|
||||
TOKEN_GROUPS *groups, TOKEN_PRIVILEGES *privs, TOKEN_OWNER *owner,
|
||||
TOKEN_PRIMARY_GROUP *group, TOKEN_DEFAULT_DACL *dacl, TOKEN_SOURCE *source)
|
||||
{
|
||||
SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
|
||||
unsigned int status, i, *attrs;
|
||||
data_size_t objattr_size, groups_size, size;
|
||||
struct object_attributes *objattr;
|
||||
void *groups_info;
|
||||
BYTE *p;
|
||||
SID *sid;
|
||||
int primary_group = -1;
|
||||
|
||||
TRACE( "(%p,0x%08x,%p,%d,%p,%p,%p,%p,%p,%p,%p,%p,%p)\n", handle, (int)access, attr,
|
||||
type, token_id, expire, user, groups, privs, owner, group, dacl, source );
|
||||
|
||||
*handle = 0;
|
||||
if ((status = alloc_object_attributes( attr, &objattr, &objattr_size ))) return status;
|
||||
|
||||
if (attr->SecurityQualityOfService)
|
||||
{
|
||||
SECURITY_QUALITY_OF_SERVICE *qos = attr->SecurityQualityOfService;
|
||||
TRACE( "ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
|
||||
(int)qos->Length, qos->ImpersonationLevel, qos->ContextTrackingMode,
|
||||
qos->EffectiveOnly ? "TRUE" : "FALSE");
|
||||
level = qos->ImpersonationLevel;
|
||||
}
|
||||
|
||||
groups_size = groups->GroupCount * sizeof( attrs[0] );
|
||||
|
||||
for (i = 0; i < groups->GroupCount; i++)
|
||||
{
|
||||
SID *group_sid = group->PrimaryGroup;
|
||||
sid = groups->Groups[i].Sid;
|
||||
groups_size += offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
|
||||
if (is_equal_sid( sid, group_sid ))
|
||||
primary_group = i;
|
||||
}
|
||||
|
||||
if (primary_group == -1)
|
||||
return STATUS_INVALID_PRIMARY_GROUP;
|
||||
|
||||
groups_info = malloc( groups_size );
|
||||
if (!groups_info)
|
||||
{
|
||||
free( objattr );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
attrs = (unsigned int *)groups_info;
|
||||
p = (BYTE *)&attrs[groups->GroupCount];
|
||||
for (i = 0; i < groups->GroupCount; i++)
|
||||
{
|
||||
sid = groups->Groups[i].Sid;
|
||||
attrs[i] = groups->Groups[i].Attributes;
|
||||
size = offsetof( SID, SubAuthority[sid->SubAuthorityCount] );
|
||||
memcpy( p, sid, size );
|
||||
p += size;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( create_token )
|
||||
{
|
||||
req->token_id.low_part = token_id->LowPart;
|
||||
req->token_id.high_part = token_id->HighPart;
|
||||
req->access = access;
|
||||
req->primary = (type == TokenPrimary);
|
||||
req->impersonation_level = level;
|
||||
req->expire = expire->QuadPart;
|
||||
|
||||
wine_server_add_data( req, objattr, objattr_size );
|
||||
|
||||
sid = user->User.Sid;
|
||||
wine_server_add_data( req, sid, offsetof( SID, SubAuthority[sid->SubAuthorityCount] ) );
|
||||
|
||||
req->group_count = groups->GroupCount;
|
||||
wine_server_add_data( req, groups_info, groups_size );
|
||||
|
||||
req->primary_group = primary_group;
|
||||
|
||||
req->priv_count = privs->PrivilegeCount;
|
||||
wine_server_add_data( req, privs->Privileges, privs->PrivilegeCount * sizeof(privs->Privileges[0]) );
|
||||
|
||||
if (dacl && dacl->DefaultDacl)
|
||||
wine_server_add_data( req, dacl->DefaultDacl, dacl->DefaultDacl->AclSize );
|
||||
|
||||
status = wine_server_call( req );
|
||||
if (!status) *handle = wine_server_ptr_handle( reply->token );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
free( groups_info );
|
||||
free( objattr );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NtOpenProcessToken (NTDLL.@)
|
||||
|
|
|
@ -154,6 +154,42 @@ NTSTATUS WINAPI wow64_NtCreateLowBoxToken( UINT *args )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtCreateToken
|
||||
*/
|
||||
NTSTATUS WINAPI wow64_NtCreateToken( UINT *args )
|
||||
{
|
||||
ULONG *handle_ptr = get_ptr( &args );
|
||||
ACCESS_MASK access = get_ulong( &args );
|
||||
OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
|
||||
TOKEN_TYPE type = get_ulong( &args );
|
||||
LUID *luid = get_ptr( &args );
|
||||
LARGE_INTEGER *expire = get_ptr( &args );
|
||||
TOKEN_USER32 *user32 = get_ptr( &args );
|
||||
TOKEN_GROUPS32 *groups32 = get_ptr( &args );
|
||||
TOKEN_PRIVILEGES *privs = get_ptr( &args );
|
||||
TOKEN_OWNER32 *owner32 = get_ptr( &args );
|
||||
TOKEN_PRIMARY_GROUP32 *group32 = get_ptr( &args );
|
||||
TOKEN_DEFAULT_DACL32 *dacl32 = get_ptr( &args );
|
||||
TOKEN_SOURCE *source = get_ptr( &args );
|
||||
|
||||
struct object_attr64 attr;
|
||||
TOKEN_USER user;
|
||||
TOKEN_OWNER owner;
|
||||
TOKEN_PRIMARY_GROUP group;
|
||||
TOKEN_DEFAULT_DACL dacl;
|
||||
HANDLE handle = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtCreateToken( &handle, access, objattr_32to64( &attr, attr32 ), type, luid, expire,
|
||||
token_user_32to64( &user, user32 ), token_groups_32to64( groups32 ), privs,
|
||||
token_owner_32to64( &owner, owner32 ), token_primary_group_32to64( &group, group32 ),
|
||||
token_default_dacl_32to64( &dacl, dacl32 ), source );
|
||||
put_handle( handle_ptr, handle );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_NtDuplicateToken
|
||||
*/
|
||||
|
|
|
@ -372,6 +372,11 @@ typedef struct
|
|||
ULONG Owner;
|
||||
} TOKEN_OWNER32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG PrimaryGroup;
|
||||
} TOKEN_PRIMARY_GROUP32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SID_AND_ATTRIBUTES32 User;
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
SYSCALL_ENTRY( NtCreateThread ) \
|
||||
SYSCALL_ENTRY( NtCreateThreadEx ) \
|
||||
SYSCALL_ENTRY( NtCreateTimer ) \
|
||||
SYSCALL_ENTRY( NtCreateToken ) \
|
||||
SYSCALL_ENTRY( NtCreateTransaction ) \
|
||||
SYSCALL_ENTRY( NtCreateUserProcess ) \
|
||||
SYSCALL_ENTRY( NtDebugActiveProcess ) \
|
||||
|
|
|
@ -188,6 +188,31 @@ static inline OBJECT_ATTRIBUTES *objattr_32to64_redirect( struct object_attr64 *
|
|||
return attr;
|
||||
}
|
||||
|
||||
static inline TOKEN_USER *token_user_32to64( TOKEN_USER *out, const TOKEN_USER32 *in )
|
||||
{
|
||||
out->User.Sid = ULongToPtr( in->User.Sid );
|
||||
out->User.Attributes = in->User.Attributes;
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline TOKEN_OWNER *token_owner_32to64( TOKEN_OWNER *out, const TOKEN_OWNER32 *in )
|
||||
{
|
||||
out->Owner = ULongToPtr( in->Owner );
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline TOKEN_PRIMARY_GROUP *token_primary_group_32to64( TOKEN_PRIMARY_GROUP *out, const TOKEN_PRIMARY_GROUP32 *in )
|
||||
{
|
||||
out->PrimaryGroup = ULongToPtr( in->PrimaryGroup );
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline TOKEN_DEFAULT_DACL *token_default_dacl_32to64( TOKEN_DEFAULT_DACL *out, const TOKEN_DEFAULT_DACL32 *in )
|
||||
{
|
||||
out->DefaultDacl = ULongToPtr( in->DefaultDacl );
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline void put_handle( ULONG *handle32, HANDLE handle )
|
||||
{
|
||||
*handle32 = HandleToULong( handle );
|
||||
|
|
|
@ -4482,6 +4482,33 @@ struct remove_clipboard_listener_reply
|
|||
|
||||
|
||||
|
||||
struct create_token_request
|
||||
{
|
||||
struct request_header __header;
|
||||
struct luid token_id;
|
||||
unsigned int access;
|
||||
int primary;
|
||||
int impersonation_level;
|
||||
abstime_t expire;
|
||||
int group_count;
|
||||
int primary_group;
|
||||
int priv_count;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
char __pad_52[4];
|
||||
};
|
||||
struct create_token_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
obj_handle_t token;
|
||||
char __pad_12[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct open_token_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -5807,6 +5834,7 @@ enum request
|
|||
REQ_set_clipboard_viewer,
|
||||
REQ_add_clipboard_listener,
|
||||
REQ_remove_clipboard_listener,
|
||||
REQ_create_token,
|
||||
REQ_open_token,
|
||||
REQ_set_global_windows,
|
||||
REQ_adjust_token_privileges,
|
||||
|
@ -6096,6 +6124,7 @@ union generic_request
|
|||
struct set_clipboard_viewer_request set_clipboard_viewer_request;
|
||||
struct add_clipboard_listener_request add_clipboard_listener_request;
|
||||
struct remove_clipboard_listener_request remove_clipboard_listener_request;
|
||||
struct create_token_request create_token_request;
|
||||
struct open_token_request open_token_request;
|
||||
struct set_global_windows_request set_global_windows_request;
|
||||
struct adjust_token_privileges_request adjust_token_privileges_request;
|
||||
|
@ -6383,6 +6412,7 @@ union generic_reply
|
|||
struct set_clipboard_viewer_reply set_clipboard_viewer_reply;
|
||||
struct add_clipboard_listener_reply add_clipboard_listener_reply;
|
||||
struct remove_clipboard_listener_reply remove_clipboard_listener_reply;
|
||||
struct create_token_reply create_token_reply;
|
||||
struct open_token_reply open_token_reply;
|
||||
struct set_global_windows_reply set_global_windows_reply;
|
||||
struct adjust_token_privileges_reply adjust_token_privileges_reply;
|
||||
|
@ -6457,7 +6487,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 781
|
||||
#define SERVER_PROTOCOL_VERSION 782
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -3187,6 +3187,26 @@ enum caret_state
|
|||
@END
|
||||
|
||||
|
||||
/* Create a security token */
|
||||
@REQ(create_token)
|
||||
struct luid token_id;
|
||||
unsigned int access; /* access rights to the new token */
|
||||
int primary; /* is the new token to be a primary one? */
|
||||
int impersonation_level; /* impersonation level of the new token */
|
||||
abstime_t expire; /* expiration time */
|
||||
int group_count;
|
||||
int primary_group;
|
||||
int priv_count;
|
||||
/* VARARG(objattr,object_attributes); */
|
||||
/* VARARG(user,sid); */
|
||||
/* VARARG(groups,sid); */
|
||||
/* VARARG(privs,luid_attr); */
|
||||
/* VARARG(dacl,acl); */
|
||||
@REPLY
|
||||
obj_handle_t token; /* handle to the token */
|
||||
@END
|
||||
|
||||
|
||||
/* Open a security token */
|
||||
@REQ(open_token)
|
||||
obj_handle_t handle; /* handle to the thread or process */
|
||||
|
|
|
@ -331,6 +331,7 @@ DECL_HANDLER(get_clipboard_info);
|
|||
DECL_HANDLER(set_clipboard_viewer);
|
||||
DECL_HANDLER(add_clipboard_listener);
|
||||
DECL_HANDLER(remove_clipboard_listener);
|
||||
DECL_HANDLER(create_token);
|
||||
DECL_HANDLER(open_token);
|
||||
DECL_HANDLER(set_global_windows);
|
||||
DECL_HANDLER(adjust_token_privileges);
|
||||
|
@ -619,6 +620,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_set_clipboard_viewer,
|
||||
(req_handler)req_add_clipboard_listener,
|
||||
(req_handler)req_remove_clipboard_listener,
|
||||
(req_handler)req_create_token,
|
||||
(req_handler)req_open_token,
|
||||
(req_handler)req_set_global_windows,
|
||||
(req_handler)req_adjust_token_privileges,
|
||||
|
@ -1970,6 +1972,17 @@ C_ASSERT( FIELD_OFFSET(struct add_clipboard_listener_request, window) == 12 );
|
|||
C_ASSERT( sizeof(struct add_clipboard_listener_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct remove_clipboard_listener_request, window) == 12 );
|
||||
C_ASSERT( sizeof(struct remove_clipboard_listener_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, token_id) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, access) == 20 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, primary) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, impersonation_level) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, expire) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, group_count) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, primary_group) == 44 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_request, priv_count) == 48 );
|
||||
C_ASSERT( sizeof(struct create_token_request) == 56 );
|
||||
C_ASSERT( FIELD_OFFSET(struct create_token_reply, token) == 8 );
|
||||
C_ASSERT( sizeof(struct create_token_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct open_token_request, handle) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct open_token_request, access) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct open_token_request, attributes) == 20 );
|
||||
|
|
106
server/token.c
106
server/token.c
|
@ -472,7 +472,7 @@ static struct token *create_token( unsigned int primary, unsigned int session_id
|
|||
const struct sid_attrs *groups, unsigned int group_count,
|
||||
const struct luid_attr *privs, unsigned int priv_count,
|
||||
const struct acl *default_dacl, const struct luid *modified_id,
|
||||
int impersonation_level, int elevation )
|
||||
unsigned int primary_group, int impersonation_level, int elevation )
|
||||
{
|
||||
struct token *token = alloc_object( &token_ops );
|
||||
if (token)
|
||||
|
@ -519,8 +519,8 @@ static struct token *create_token( unsigned int primary, unsigned int session_id
|
|||
group->attrs = groups[i].attrs;
|
||||
copy_sid( &group->sid, groups[i].sid );
|
||||
list_add_tail( &token->groups, &group->entry );
|
||||
/* Use first owner capable group as owner and primary group */
|
||||
if (!token->primary_group && (group->attrs & SE_GROUP_OWNER))
|
||||
|
||||
if (primary_group == i)
|
||||
{
|
||||
token->owner = &group->sid;
|
||||
token->primary_group = &group->sid;
|
||||
|
@ -598,7 +598,7 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
|
|||
|
||||
token = create_token( primary, src_token->session_id, src_token->user, NULL, 0,
|
||||
NULL, 0, src_token->default_dacl, modified_id,
|
||||
impersonation_level, src_token->elevation );
|
||||
0, impersonation_level, src_token->elevation );
|
||||
if (!token) return token;
|
||||
|
||||
/* copy groups */
|
||||
|
@ -773,7 +773,7 @@ struct token *token_create_admin( unsigned primary, int impersonation_level, int
|
|||
|
||||
token = create_token( primary, session_id, user_sid, admin_groups, ARRAY_SIZE( admin_groups ),
|
||||
admin_privs, ARRAY_SIZE( admin_privs ), default_dacl,
|
||||
NULL, impersonation_level, elevation );
|
||||
NULL, 4 /* domain_users */, impersonation_level, elevation );
|
||||
/* we really need a primary group */
|
||||
assert( token->primary_group );
|
||||
|
||||
|
@ -1089,6 +1089,102 @@ int check_object_access(struct token *token, struct object *obj, unsigned int *a
|
|||
}
|
||||
|
||||
|
||||
/* create a security token */
|
||||
DECL_HANDLER(create_token)
|
||||
{
|
||||
struct token *token;
|
||||
struct object_attributes *objattr;
|
||||
struct sid *user;
|
||||
struct sid_attrs *groups;
|
||||
struct luid_attr *privs;
|
||||
struct acl *dacl = NULL;
|
||||
unsigned int i;
|
||||
data_size_t data_size, groups_size;
|
||||
struct acl *default_dacl = NULL;
|
||||
unsigned int *attrs;
|
||||
struct sid *sid;
|
||||
|
||||
objattr = (struct object_attributes *)get_req_data();
|
||||
user = (struct sid *)get_req_data_after_objattr( objattr, &data_size );
|
||||
|
||||
if (!user || !sid_valid_size( user, data_size ))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
data_size -= sid_len( user );
|
||||
groups_size = req->group_count * sizeof( attrs[0] );
|
||||
|
||||
if (data_size < groups_size)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->primary_group < 0 || req->primary_group >= req->group_count)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
groups = mem_alloc( req->group_count * sizeof( groups[0] ) );
|
||||
if (!groups) return;
|
||||
|
||||
attrs = (unsigned int *)((char *)user + sid_len( user ));
|
||||
sid = (struct sid *)&attrs[req->group_count];
|
||||
|
||||
for (i = 0; i < req->group_count; i++)
|
||||
{
|
||||
groups[i].attrs = attrs[i];
|
||||
groups[i].sid = sid;
|
||||
|
||||
if (!sid_valid_size( sid, data_size - groups_size ))
|
||||
{
|
||||
free( groups );
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
groups_size += sid_len( sid );
|
||||
sid = (struct sid *)((char *)sid + sid_len( sid ));
|
||||
}
|
||||
|
||||
data_size -= groups_size;
|
||||
|
||||
if (data_size < req->priv_count * sizeof( privs[0] ))
|
||||
{
|
||||
free( groups );
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
privs = (struct luid_attr *)((char *)attrs + groups_size);
|
||||
data_size -= req->priv_count * sizeof( privs[0] );
|
||||
|
||||
if (data_size)
|
||||
{
|
||||
dacl = (struct acl *)((char *)privs + req->priv_count * sizeof(privs[0]));
|
||||
if (!acl_is_valid( dacl, data_size ))
|
||||
{
|
||||
free( groups );
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
dacl = default_dacl = create_default_dacl( &domain_users_sid );
|
||||
|
||||
token = create_token( req->primary, default_session_id, user, groups, req->group_count,
|
||||
privs, req->priv_count, dacl, NULL, req->primary_group, req->impersonation_level, 0 );
|
||||
if (token)
|
||||
reply->token = alloc_handle( current->process, token, req->access, objattr->attributes );
|
||||
|
||||
free( default_dacl );
|
||||
free( groups );
|
||||
}
|
||||
|
||||
|
||||
/* open a security token */
|
||||
DECL_HANDLER(open_token)
|
||||
{
|
||||
|
|
|
@ -3841,6 +3841,23 @@ static void dump_remove_clipboard_listener_request( const struct remove_clipboar
|
|||
fprintf( stderr, " window=%08x", req->window );
|
||||
}
|
||||
|
||||
static void dump_create_token_request( const struct create_token_request *req )
|
||||
{
|
||||
dump_luid( " token_id=", &req->token_id );
|
||||
fprintf( stderr, ", access=%08x", req->access );
|
||||
fprintf( stderr, ", primary=%d", req->primary );
|
||||
fprintf( stderr, ", impersonation_level=%d", req->impersonation_level );
|
||||
dump_abstime( ", expire=", &req->expire );
|
||||
fprintf( stderr, ", group_count=%d", req->group_count );
|
||||
fprintf( stderr, ", primary_group=%d", req->primary_group );
|
||||
fprintf( stderr, ", priv_count=%d", req->priv_count );
|
||||
}
|
||||
|
||||
static void dump_create_token_reply( const struct create_token_reply *req )
|
||||
{
|
||||
fprintf( stderr, " token=%04x", req->token );
|
||||
}
|
||||
|
||||
static void dump_open_token_request( const struct open_token_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%04x", req->handle );
|
||||
|
@ -4792,6 +4809,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_set_clipboard_viewer_request,
|
||||
(dump_func)dump_add_clipboard_listener_request,
|
||||
(dump_func)dump_remove_clipboard_listener_request,
|
||||
(dump_func)dump_create_token_request,
|
||||
(dump_func)dump_open_token_request,
|
||||
(dump_func)dump_set_global_windows_request,
|
||||
(dump_func)dump_adjust_token_privileges_request,
|
||||
|
@ -5077,6 +5095,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_set_clipboard_viewer_reply,
|
||||
NULL,
|
||||
NULL,
|
||||
(dump_func)dump_create_token_reply,
|
||||
(dump_func)dump_open_token_reply,
|
||||
(dump_func)dump_set_global_windows_reply,
|
||||
(dump_func)dump_adjust_token_privileges_reply,
|
||||
|
@ -5362,6 +5381,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"set_clipboard_viewer",
|
||||
"add_clipboard_listener",
|
||||
"remove_clipboard_listener",
|
||||
"create_token",
|
||||
"open_token",
|
||||
"set_global_windows",
|
||||
"adjust_token_privileges",
|
||||
|
|
Loading…
Add table
Reference in a new issue