shdocvw: Return correct error from WebBrowser::Quit.
[wine] / server / token.c
1 /*
2  * Tokens
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  * Copyright (C) 2003 Mike McCormack
6  * Copyright (C) 2005 Robert Shearman
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24
25 #include <assert.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <unistd.h>
30
31 #include "ntstatus.h"
32 #define WIN32_NO_STATUS
33 #include "windef.h"
34 #include "winternl.h"
35
36 #include "handle.h"
37 #include "thread.h"
38 #include "process.h"
39 #include "request.h"
40 #include "security.h"
41
42 #include "wine/unicode.h"
43
44 #define MAX_SUBAUTH_COUNT 1
45
46 const LUID SeIncreaseQuotaPrivilege        = {  5, 0 };
47 const LUID SeSecurityPrivilege             = {  8, 0 };
48 const LUID SeTakeOwnershipPrivilege        = {  9, 0 };
49 const LUID SeLoadDriverPrivilege           = { 10, 0 };
50 const LUID SeSystemProfilePrivilege        = { 11, 0 };
51 const LUID SeSystemtimePrivilege           = { 12, 0 };
52 const LUID SeProfileSingleProcessPrivilege = { 13, 0 };
53 const LUID SeIncreaseBasePriorityPrivilege = { 14, 0 };
54 const LUID SeCreatePagefilePrivilege       = { 15, 0 };
55 const LUID SeBackupPrivilege               = { 17, 0 };
56 const LUID SeRestorePrivilege              = { 18, 0 };
57 const LUID SeShutdownPrivilege             = { 19, 0 };
58 const LUID SeDebugPrivilege                = { 20, 0 };
59 const LUID SeSystemEnvironmentPrivilege    = { 22, 0 };
60 const LUID SeChangeNotifyPrivilege         = { 23, 0 };
61 const LUID SeRemoteShutdownPrivilege       = { 24, 0 };
62 const LUID SeUndockPrivilege               = { 25, 0 };
63 const LUID SeManageVolumePrivilege         = { 28, 0 };
64 const LUID SeImpersonatePrivilege          = { 29, 0 };
65 const LUID SeCreateGlobalPrivilege         = { 30, 0 };
66
67 static const SID world_sid = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } };
68 static const SID local_sid = { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } };
69 static const SID interactive_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } };
70 static const SID anonymous_logon_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } };
71 static const SID authenticated_user_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } };
72 static const SID local_system_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } };
73 const PSID security_world_sid = (PSID)&world_sid;
74 static const PSID security_local_sid = (PSID)&local_sid;
75 const PSID security_interactive_sid = (PSID)&interactive_sid;
76 static const PSID security_authenticated_user_sid = (PSID)&authenticated_user_sid;
77 const PSID security_local_system_sid = (PSID)&local_system_sid;
78
79 static luid_t prev_luid_value = { 1000, 0 };
80
81 struct token
82 {
83     struct object  obj;             /* object header */
84     luid_t         token_id;        /* system-unique id of token */
85     luid_t         modified_id;     /* new id allocated every time token is modified */
86     struct list    privileges;      /* privileges available to the token */
87     struct list    groups;          /* groups that the user of this token belongs to (sid_and_attributes) */
88     SID           *user;            /* SID of user this token represents */
89     SID           *primary_group;   /* SID of user's primary group */
90     unsigned       primary;         /* is this a primary or impersonation token? */
91     ACL           *default_dacl;    /* the default DACL to assign to objects created by this user */
92     TOKEN_SOURCE   source;          /* source of the token */
93     SECURITY_IMPERSONATION_LEVEL impersonation_level; /* impersonation level this token is capable of if non-primary token */
94 };
95
96 struct privilege
97 {
98     struct list entry;
99     LUID        luid;
100     unsigned    enabled  : 1; /* is the privilege currently enabled? */
101     unsigned    def      : 1; /* is the privilege enabled by default? */
102 };
103
104 struct group
105 {
106     struct list entry;
107     unsigned    enabled  : 1; /* is the sid currently enabled? */
108     unsigned    def      : 1; /* is the sid enabled by default? */
109     unsigned    logon    : 1; /* is this a logon sid? */
110     unsigned    mandatory: 1; /* is this sid always enabled? */
111     unsigned    owner    : 1; /* can this sid be an owner of an object? */
112     unsigned    resource : 1; /* is this a domain-local group? */
113     unsigned    deny_only: 1; /* is this a sid that should be use for denying only? */
114     SID         sid;
115 };
116
117 static void token_dump( struct object *obj, int verbose );
118 static unsigned int token_map_access( struct object *obj, unsigned int access );
119 static void token_destroy( struct object *obj );
120
121 static const struct object_ops token_ops =
122 {
123     sizeof(struct token),      /* size */
124     token_dump,                /* dump */
125     no_add_queue,              /* add_queue */
126     NULL,                      /* remove_queue */
127     NULL,                      /* signaled */
128     NULL,                      /* satisfied */
129     no_signal,                 /* signal */
130     no_get_fd,                 /* get_fd */
131     token_map_access,          /* map_access */
132     default_get_sd,            /* get_sd */
133     default_set_sd,            /* set_sd */
134     no_lookup_name,            /* lookup_name */
135     no_open_file,              /* open_file */
136     no_close_handle,           /* close_handle */
137     token_destroy              /* destroy */
138 };
139
140
141 static void token_dump( struct object *obj, int verbose )
142 {
143     fprintf( stderr, "Security token\n" );
144     /* FIXME: dump token members */
145 }
146
147 static unsigned int token_map_access( struct object *obj, unsigned int access )
148 {
149     if (access & GENERIC_READ)    access |= TOKEN_READ;
150     if (access & GENERIC_WRITE)   access |= TOKEN_WRITE;
151     if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE;
152     if (access & GENERIC_ALL)     access |= TOKEN_ALL_ACCESS;
153     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
154 }
155
156 static SID *security_sid_alloc( const SID_IDENTIFIER_AUTHORITY *idauthority, int subauthcount, const unsigned int subauth[] )
157 {
158     int i;
159     SID *sid = mem_alloc( FIELD_OFFSET(SID, SubAuthority[subauthcount]) );
160     if (!sid) return NULL;
161     sid->Revision = SID_REVISION;
162     sid->SubAuthorityCount = subauthcount;
163     sid->IdentifierAuthority = *idauthority;
164     for (i = 0; i < subauthcount; i++)
165         sid->SubAuthority[i] = subauth[i];
166     return sid;
167 }
168
169 void security_set_thread_token( struct thread *thread, obj_handle_t handle )
170 {
171     if (!handle)
172     {
173         if (thread->token)
174             release_object( thread->token );
175         thread->token = NULL;
176     }
177     else
178     {
179         struct token *token = (struct token *)get_handle_obj( current->process,
180                                                               handle,
181                                                               TOKEN_IMPERSONATE,
182                                                               &token_ops );
183         if (token)
184         {
185             if (thread->token)
186                 release_object( thread->token );
187             thread->token = token;
188         }
189     }
190 }
191
192 const SID *security_unix_uid_to_sid( uid_t uid )
193 {
194     /* very simple mapping: either the current user or not the current user */
195     if (uid == getuid())
196         return &interactive_sid;
197     else
198         return &anonymous_logon_sid;
199 }
200
201 static int acl_is_valid( const ACL *acl, data_size_t size )
202 {
203     ULONG i;
204     const ACE_HEADER *ace;
205
206     if (size < sizeof(ACL))
207         return FALSE;
208
209     size = min(size, MAX_ACL_LEN);
210
211     size -= sizeof(ACL);
212
213     ace = (const ACE_HEADER *)(acl + 1);
214     for (i = 0; i < acl->AceCount; i++)
215     {
216         const SID *sid;
217         data_size_t sid_size;
218
219         if (size < sizeof(ACE_HEADER))
220             return FALSE;
221         if (size < ace->AceSize)
222             return FALSE;
223         size -= ace->AceSize;
224         switch (ace->AceType)
225         {
226         case ACCESS_DENIED_ACE_TYPE:
227             sid = (const SID *)&((const ACCESS_DENIED_ACE *)ace)->SidStart;
228             sid_size = ace->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart);
229             break;
230         case ACCESS_ALLOWED_ACE_TYPE:
231             sid = (const SID *)&((const ACCESS_ALLOWED_ACE *)ace)->SidStart;
232             sid_size = ace->AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
233             break;
234         case SYSTEM_AUDIT_ACE_TYPE:
235             sid = (const SID *)&((const SYSTEM_AUDIT_ACE *)ace)->SidStart;
236             sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart);
237             break;
238         case SYSTEM_ALARM_ACE_TYPE:
239             sid = (const SID *)&((const SYSTEM_ALARM_ACE *)ace)->SidStart;
240             sid_size = ace->AceSize - FIELD_OFFSET(SYSTEM_ALARM_ACE, SidStart);
241             break;
242         default:
243             return FALSE;
244         }
245         if (sid_size < FIELD_OFFSET(SID, SubAuthority[0]) ||
246             sid_size < FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]))
247             return FALSE;
248         ace = ace_next( ace );
249     }
250     return TRUE;
251 }
252
253 /* checks whether all members of a security descriptor fit inside the size
254  * of memory specified */
255 int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
256 {
257     size_t offset = sizeof(struct security_descriptor);
258     const SID *group;
259     const SID *owner;
260     const ACL *sacl;
261     const ACL *dacl;
262     int dummy;
263
264     if (size < offset)
265         return FALSE;
266
267     if ((sd->owner_len >= FIELD_OFFSET(SID, SubAuthority[255])) ||
268         (offset + sd->owner_len > size))
269         return FALSE;
270     owner = sd_get_owner( sd );
271     if (owner)
272     {
273         size_t needed_size = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
274         if ((sd->owner_len < sizeof(SID)) || (needed_size > sd->owner_len))
275             return FALSE;
276     }
277     offset += sd->owner_len;
278
279     if ((sd->group_len >= FIELD_OFFSET(SID, SubAuthority[255])) ||
280         (offset + sd->group_len > size))
281         return FALSE;
282     group = sd_get_group( sd );
283     if (group)
284     {
285         size_t needed_size = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
286         if ((sd->group_len < sizeof(SID)) || (needed_size > sd->group_len))
287             return FALSE;
288     }
289     offset += sd->group_len;
290
291     if ((sd->sacl_len >= MAX_ACL_LEN) || (offset + sd->sacl_len > size))
292         return FALSE;
293     sacl = sd_get_sacl( sd, &dummy );
294     if (sacl && !acl_is_valid( sacl, sd->sacl_len ))
295         return FALSE;
296     offset += sd->sacl_len;
297
298     if ((sd->dacl_len >= MAX_ACL_LEN) || (offset + sd->dacl_len > size))
299         return FALSE;
300     dacl = sd_get_dacl( sd, &dummy );
301     if (dacl && !acl_is_valid( dacl, sd->dacl_len ))
302         return FALSE;
303     offset += sd->dacl_len;
304
305     return TRUE;
306 }
307
308 /* determines whether an object_attributes struct is valid in a buffer
309  * and calls set_error appropriately */
310 int objattr_is_valid( const struct object_attributes *objattr, data_size_t size )
311 {
312     if ((size < sizeof(*objattr)) || (size - sizeof(*objattr) < objattr->sd_len) ||
313         (size - sizeof(*objattr) - objattr->sd_len < objattr->name_len))
314     {
315         set_error( STATUS_ACCESS_VIOLATION );
316         return FALSE;
317     }
318
319     if (objattr->sd_len)
320     {
321         const struct security_descriptor *sd = (const struct security_descriptor *)(objattr + 1);
322         if (!sd_is_valid( sd, objattr->sd_len ))
323         {
324             set_error( STATUS_INVALID_SECURITY_DESCR );
325             return FALSE;
326         }
327     }
328
329     return TRUE;
330 }
331
332 /* maps from generic rights to specific rights as given by a mapping */
333 static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
334 {
335     if (*mask & GENERIC_READ) *mask |= mapping->GenericRead;
336     if (*mask & GENERIC_WRITE) *mask |= mapping->GenericWrite;
337     if (*mask & GENERIC_EXECUTE) *mask |= mapping->GenericExecute;
338     if (*mask & GENERIC_ALL) *mask |= mapping->GenericAll;
339     *mask &= 0x0FFFFFFF;
340 }
341
342 static inline int is_equal_luid( const LUID *luid1, const LUID *luid2 )
343 {
344     return (luid1->LowPart == luid2->LowPart && luid1->HighPart == luid2->HighPart);
345 }
346
347 static inline void allocate_luid( luid_t *luid )
348 {
349     prev_luid_value.low_part++;
350     *luid = prev_luid_value;
351 }
352
353 DECL_HANDLER( allocate_locally_unique_id )
354 {
355     allocate_luid( &reply->luid );
356 }
357
358 static inline void luid_and_attr_from_privilege( LUID_AND_ATTRIBUTES *out, const struct privilege *in)
359 {
360     out->Luid = in->luid;
361     out->Attributes =
362         (in->enabled ? SE_PRIVILEGE_ENABLED : 0) |
363         (in->def ? SE_PRIVILEGE_ENABLED_BY_DEFAULT : 0);
364 }
365
366 static struct privilege *privilege_add( struct token *token, const LUID *luid, int enabled )
367 {
368     struct privilege *privilege = mem_alloc( sizeof(*privilege) );
369     if (privilege)
370     {
371         privilege->luid = *luid;
372         privilege->def = privilege->enabled = (enabled != 0);
373         list_add_tail( &token->privileges, &privilege->entry );
374     }
375     return privilege;
376 }
377
378 static inline void privilege_remove( struct privilege *privilege )
379 {
380     list_remove( &privilege->entry );
381     free( privilege );
382 }
383
384 static void token_destroy( struct object *obj )
385 {
386     struct token* token;
387     struct list *cursor, *cursor_next;
388
389     assert( obj->ops == &token_ops );
390     token = (struct token *)obj;
391
392     free( token->user );
393
394     LIST_FOR_EACH_SAFE( cursor, cursor_next, &token->privileges )
395     {
396         struct privilege *privilege = LIST_ENTRY( cursor, struct privilege, entry );
397         privilege_remove( privilege );
398     }
399
400     LIST_FOR_EACH_SAFE( cursor, cursor_next, &token->groups )
401     {
402         struct group *group = LIST_ENTRY( cursor, struct group, entry );
403         list_remove( &group->entry );
404         free( group );
405     }
406
407     free( token->default_dacl );
408 }
409
410 /* creates a new token.
411  *  groups may be NULL if group_count is 0.
412  *  privs may be NULL if priv_count is 0.
413  *  default_dacl may be NULL, indicating that all objects created by the user
414  *   are unsecured.
415  *  modified_id may be NULL, indicating that a new modified_id luid should be
416  *   allocated.
417  */
418 static struct token *create_token( unsigned primary, const SID *user,
419                                    const SID_AND_ATTRIBUTES *groups, unsigned int group_count,
420                                    const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count,
421                                    const ACL *default_dacl, TOKEN_SOURCE source,
422                                    const luid_t *modified_id,
423                                    SECURITY_IMPERSONATION_LEVEL impersonation_level )
424 {
425     struct token *token = alloc_object( &token_ops );
426     if (token)
427     {
428         unsigned int i;
429
430         allocate_luid( &token->token_id );
431         if (modified_id)
432             token->modified_id = *modified_id;
433         else
434             allocate_luid( &token->modified_id );
435         list_init( &token->privileges );
436         list_init( &token->groups );
437         token->primary = primary;
438         /* primary tokens don't have impersonation levels */
439         if (primary)
440             token->impersonation_level = -1;
441         else
442             token->impersonation_level = impersonation_level;
443         token->default_dacl = NULL;
444         token->primary_group = NULL;
445
446         /* copy user */
447         token->user = memdup( user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
448         if (!token->user)
449         {
450             release_object( token );
451             return NULL;
452         }
453
454         /* copy groups */
455         for (i = 0; i < group_count; i++)
456         {
457             size_t size = FIELD_OFFSET( struct group, sid.SubAuthority[((const SID *)groups[i].Sid)->SubAuthorityCount] );
458             struct group *group = mem_alloc( size );
459
460             if (!group)
461             {
462                 release_object( token );
463                 return NULL;
464             }
465             memcpy( &group->sid, groups[i].Sid, FIELD_OFFSET( SID, SubAuthority[((const SID *)groups[i].Sid)->SubAuthorityCount] ) );
466             group->enabled = TRUE;
467             group->def = TRUE;
468             group->logon = FALSE;
469             group->mandatory = (groups[i].Attributes & SE_GROUP_MANDATORY) ? TRUE : FALSE;
470             group->owner = groups[i].Attributes & SE_GROUP_OWNER ? TRUE : FALSE;
471             group->resource = FALSE;
472             group->deny_only = FALSE;
473             list_add_tail( &token->groups, &group->entry );
474             /* Use first owner capable group as an owner */
475             if (!token->primary_group && group->owner)
476                 token->primary_group = &group->sid;
477         }
478
479         /* copy privileges */
480         for (i = 0; i < priv_count; i++)
481         {
482             /* note: we don't check uniqueness: the caller must make sure
483              * privs doesn't contain any duplicate luids */
484             if (!privilege_add( token, &privs[i].Luid,
485                                 privs[i].Attributes & SE_PRIVILEGE_ENABLED ))
486             {
487                 release_object( token );
488                 return NULL;
489             }
490         }
491
492         if (default_dacl)
493         {
494             token->default_dacl = memdup( default_dacl, default_dacl->AclSize );
495             if (!token->default_dacl)
496             {
497                 release_object( token );
498                 return NULL;
499             }
500         }
501
502         token->source = source;
503     }
504     return token;
505 }
506
507 struct token *token_duplicate( struct token *src_token, unsigned primary,
508                                SECURITY_IMPERSONATION_LEVEL impersonation_level )
509 {
510     const luid_t *modified_id =
511         primary || (impersonation_level == src_token->impersonation_level) ?
512             &src_token->modified_id : NULL;
513     struct token *token = NULL;
514     struct privilege *privilege;
515     struct group *group;
516
517     if ((impersonation_level < SecurityAnonymous) ||
518         (impersonation_level > SecurityDelegation))
519     {
520         set_error( STATUS_BAD_IMPERSONATION_LEVEL );
521         return NULL;
522     }
523
524     if (primary || (impersonation_level <= src_token->impersonation_level))
525         token = create_token( primary, src_token->user, NULL, 0,
526                               NULL, 0, src_token->default_dacl,
527                               src_token->source, modified_id,
528                               impersonation_level );
529     else set_error( STATUS_BAD_IMPERSONATION_LEVEL );
530
531     if (!token) return token;
532
533     /* copy groups */
534     LIST_FOR_EACH_ENTRY( group, &src_token->groups, struct group, entry )
535     {
536         size_t size = FIELD_OFFSET( struct group, sid.SubAuthority[group->sid.SubAuthorityCount] );
537         struct group *newgroup = mem_alloc( size );
538         if (!newgroup)
539         {
540             release_object( token );
541             return NULL;
542         }
543         memcpy( newgroup, group, size );
544         list_add_tail( &token->groups, &newgroup->entry );
545     }
546     token->primary_group = src_token->primary_group;
547     assert( token->primary_group );
548
549     /* copy privileges */
550     LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
551         if (!privilege_add( token, &privilege->luid, privilege->enabled ))
552         {
553             release_object( token );
554             return NULL;
555         }
556
557     return token;
558 }
559
560 static ACL *create_default_dacl( const SID *user )
561 {
562     ACCESS_ALLOWED_ACE *aaa;
563     ACL *default_dacl;
564     SID *sid;
565     size_t default_dacl_size = sizeof(ACL) +
566                                2*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
567                                sizeof(local_system_sid) +
568                                FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
569
570     default_dacl = mem_alloc( default_dacl_size );
571     if (!default_dacl) return NULL;
572
573     default_dacl->AclRevision = ACL_REVISION;
574     default_dacl->Sbz1 = 0;
575     default_dacl->AclSize = default_dacl_size;
576     default_dacl->AceCount = 2;
577     default_dacl->Sbz2 = 0;
578
579     /* GENERIC_ALL for Local System */
580     aaa = (ACCESS_ALLOWED_ACE *)(default_dacl + 1);
581     aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
582     aaa->Header.AceFlags = 0;
583     aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
584                           sizeof(local_system_sid);
585     aaa->Mask = GENERIC_ALL;
586     sid = (SID *)&aaa->SidStart;
587     memcpy( sid, &local_system_sid, sizeof(local_system_sid) );
588
589     /* GENERIC_ALL for specified user */
590     aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize);
591     aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
592     aaa->Header.AceFlags = 0;
593     aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
594                           FIELD_OFFSET( SID, SubAuthority[user->SubAuthorityCount] );
595     aaa->Mask = GENERIC_ALL;
596     sid = (SID *)&aaa->SidStart;
597     memcpy( sid, user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
598
599     return default_dacl;
600 }
601
602 struct sid_data
603 {
604     SID_IDENTIFIER_AUTHORITY idauth;
605     int count;
606     unsigned int subauth[MAX_SUBAUTH_COUNT];
607 };
608
609 struct token *token_create_admin( void )
610 {
611     struct token *token = NULL;
612     static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY };
613     static const unsigned int alias_admins_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS };
614     static const unsigned int alias_users_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS };
615     /* on Windows, this value changes every time the user logs on */
616     static const unsigned int logon_subauth[] = { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ };
617     PSID alias_admins_sid;
618     PSID alias_users_sid;
619     PSID logon_sid;
620     /* note: should be the owner specified in the token */
621     ACL *default_dacl = create_default_dacl( &interactive_sid );
622
623     alias_admins_sid = security_sid_alloc( &nt_authority, sizeof(alias_admins_subauth)/sizeof(alias_admins_subauth[0]),
624                                            alias_admins_subauth );
625     alias_users_sid = security_sid_alloc( &nt_authority, sizeof(alias_users_subauth)/sizeof(alias_users_subauth[0]),
626                                           alias_users_subauth );
627     logon_sid = security_sid_alloc( &nt_authority, sizeof(logon_subauth)/sizeof(logon_subauth[0]),
628                                     logon_subauth );
629
630     if (alias_admins_sid && alias_users_sid && logon_sid && default_dacl)
631     {
632         const LUID_AND_ATTRIBUTES admin_privs[] =
633         {
634             { SeChangeNotifyPrivilege        , SE_PRIVILEGE_ENABLED },
635             { SeSecurityPrivilege            , 0                    },
636             { SeBackupPrivilege              , 0                    },
637             { SeRestorePrivilege             , 0                    },
638             { SeSystemtimePrivilege          , 0                    },
639             { SeShutdownPrivilege            , 0                    },
640             { SeRemoteShutdownPrivilege      , 0                    },
641             { SeTakeOwnershipPrivilege       , 0                    },
642             { SeDebugPrivilege               , 0                    },
643             { SeSystemEnvironmentPrivilege   , 0                    },
644             { SeSystemProfilePrivilege       , 0                    },
645             { SeProfileSingleProcessPrivilege, 0                    },
646             { SeIncreaseBasePriorityPrivilege, 0                    },
647             { SeLoadDriverPrivilege          , SE_PRIVILEGE_ENABLED },
648             { SeCreatePagefilePrivilege      , 0                    },
649             { SeIncreaseQuotaPrivilege       , 0                    },
650             { SeUndockPrivilege              , 0                    },
651             { SeManageVolumePrivilege        , 0                    },
652             { SeImpersonatePrivilege         , SE_PRIVILEGE_ENABLED },
653             { SeCreateGlobalPrivilege        , SE_PRIVILEGE_ENABLED },
654         };
655         /* note: we don't include non-builtin groups here for the user -
656          * telling us these is the job of a client-side program */
657         const SID_AND_ATTRIBUTES admin_groups[] =
658         {
659             { security_world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
660             { security_local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
661             { security_interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
662             { security_authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
663             { alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER },
664             { alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
665             { logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID },
666         };
667         static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
668         token = create_token( TRUE, security_unix_uid_to_sid( getuid() ),
669                             admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]),
670                             admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]),
671                             default_dacl, admin_source, NULL, -1 );
672         /* we really need a primary group */
673         assert( token->primary_group );
674     }
675
676     free( logon_sid );
677     free( alias_admins_sid );
678     free( alias_users_sid );
679     free( default_dacl );
680
681     return token;
682 }
683
684 static struct privilege *token_find_privilege( struct token *token, const LUID *luid, int enabled_only )
685 {
686     struct privilege *privilege;
687     LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
688     {
689         if (is_equal_luid( luid, &privilege->luid ))
690         {
691             if (enabled_only && !privilege->enabled)
692                 return NULL;
693             return privilege;
694         }
695     }
696     return NULL;
697 }
698
699 static unsigned int token_adjust_privileges( struct token *token, const LUID_AND_ATTRIBUTES *privs,
700                                              unsigned int count, LUID_AND_ATTRIBUTES *mod_privs,
701                                              unsigned int mod_privs_count )
702 {
703     unsigned int i, modified_count = 0;
704
705     /* mark as modified */
706     allocate_luid( &token->modified_id );
707
708     for (i = 0; i < count; i++)
709     {
710         struct privilege *privilege =
711             token_find_privilege( token, &privs[i].Luid, FALSE );
712         if (!privilege)
713         {
714             set_error( STATUS_NOT_ALL_ASSIGNED );
715             continue;
716         }
717
718         if (privs[i].Attributes & SE_PRIVILEGE_REMOVE)
719             privilege_remove( privilege );
720         else
721         {
722             /* save previous state for caller */
723             if (mod_privs_count)
724             {
725                 luid_and_attr_from_privilege(mod_privs, privilege);
726                 mod_privs++;
727                 mod_privs_count--;
728                 modified_count++;
729             }
730
731             if (privs[i].Attributes & SE_PRIVILEGE_ENABLED)
732                 privilege->enabled = TRUE;
733             else
734                 privilege->enabled = FALSE;
735         }
736     }
737     return modified_count;
738 }
739
740 static void token_disable_privileges( struct token *token )
741 {
742     struct privilege *privilege;
743
744     /* mark as modified */
745     allocate_luid( &token->modified_id );
746
747     LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
748         privilege->enabled = FALSE;
749 }
750
751 int token_check_privileges( struct token *token, int all_required,
752                             const LUID_AND_ATTRIBUTES *reqprivs,
753                             unsigned int count, LUID_AND_ATTRIBUTES *usedprivs)
754 {
755     unsigned int i, enabled_count = 0;
756
757     for (i = 0; i < count; i++)
758     {
759         struct privilege *privilege = 
760             token_find_privilege( token, &reqprivs[i].Luid, TRUE );
761
762         if (usedprivs)
763             usedprivs[i] = reqprivs[i];
764
765         if (privilege && privilege->enabled)
766         {
767             enabled_count++;
768             if (usedprivs)
769                 usedprivs[i].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
770         }
771     }
772
773     if (all_required)
774         return (enabled_count == count);
775     else
776         return (enabled_count > 0);
777 }
778
779 static int token_sid_present( struct token *token, const SID *sid, int deny )
780 {
781     struct group *group;
782
783     if (security_equal_sid( token->user, sid )) return TRUE;
784
785     LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry )
786     {
787         if (!group->enabled) continue;
788         if (group->deny_only && !deny) continue;
789
790         if (security_equal_sid( &group->sid, sid )) return TRUE;
791     }
792
793     return FALSE;
794 }
795
796 /* Checks access to a security descriptor. 'sd' must have been validated by
797  * caller. It returns STATUS_SUCCESS if call succeeded or an error indicating
798  * the reason. 'status' parameter will indicate if access is granted or denied.
799  *
800  * If both returned value and 'status' are STATUS_SUCCESS then access is granted.
801  */
802 static unsigned int token_access_check( struct token *token,
803                                  const struct security_descriptor *sd,
804                                  unsigned int desired_access,
805                                  LUID_AND_ATTRIBUTES *privs,
806                                  unsigned int *priv_count,
807                                  const GENERIC_MAPPING *mapping,
808                                  unsigned int *granted_access,
809                                  unsigned int *status )
810 {
811     unsigned int current_access = 0;
812     unsigned int denied_access = 0;
813     ULONG i;
814     const ACL *dacl;
815     int dacl_present;
816     const ACE_HEADER *ace;
817     const SID *owner;
818
819     /* assume no access rights */
820     *granted_access = 0;
821
822     /* fail if desired_access contains generic rights */
823     if (desired_access & (GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|GENERIC_ALL))
824     {
825         *priv_count = 0;
826         return STATUS_GENERIC_NOT_MAPPED;
827     }
828
829     dacl = sd_get_dacl( sd, &dacl_present );
830     owner = sd_get_owner( sd );
831     if (!owner || !sd_get_group( sd ))
832     {
833         *priv_count = 0;
834         return STATUS_INVALID_SECURITY_DESCR;
835     }
836
837     /* 1: Grant desired access if the object is unprotected */
838     if (!dacl_present || !dacl)
839     {
840         *priv_count = 0;
841         *granted_access = desired_access;
842         return *status = STATUS_SUCCESS;
843     }
844
845     /* 2: Check if caller wants access to system security part. Note: access
846      * is only granted if specifically asked for */
847     if (desired_access & ACCESS_SYSTEM_SECURITY)
848     {
849         const LUID_AND_ATTRIBUTES security_priv = { SeSecurityPrivilege, 0 };
850         LUID_AND_ATTRIBUTES retpriv = security_priv;
851         if (token_check_privileges( token, TRUE, &security_priv, 1, &retpriv ))
852         {
853             if (priv_count)
854             {
855                 /* assumes that there will only be one privilege to return */
856                 if (*priv_count >= 1)
857                 {
858                     *priv_count = 1;
859                     *privs = retpriv;
860                 }
861                 else
862                 {
863                     *priv_count = 1;
864                     return STATUS_BUFFER_TOO_SMALL;
865                 }
866             }
867             current_access |= ACCESS_SYSTEM_SECURITY;
868             if (desired_access == current_access)
869             {
870                 *granted_access = current_access;
871                 return *status = STATUS_SUCCESS;
872             }
873         }
874         else
875         {
876             *priv_count = 0;
877             *status = STATUS_PRIVILEGE_NOT_HELD;
878             return STATUS_SUCCESS;
879         }
880     }
881     else if (priv_count) *priv_count = 0;
882
883     /* 3: Check whether the token is the owner */
884     /* NOTE: SeTakeOwnershipPrivilege is not checked for here - it is instead
885      * checked when a "set owner" call is made, overriding the access rights
886      * determined here. */
887     if (token_sid_present( token, owner, FALSE ))
888     {
889         current_access |= (READ_CONTROL | WRITE_DAC);
890         if (desired_access == current_access)
891         {
892             *granted_access = current_access;
893             return *status = STATUS_SUCCESS;
894         }
895     }
896
897     /* 4: Grant rights according to the DACL */
898     ace = (const ACE_HEADER *)(dacl + 1);
899     for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace ))
900     {
901         const ACCESS_ALLOWED_ACE *aa_ace;
902         const ACCESS_DENIED_ACE *ad_ace;
903         const SID *sid;
904
905         if (ace->AceFlags & INHERIT_ONLY_ACE)
906             continue;
907
908         switch (ace->AceType)
909         {
910         case ACCESS_DENIED_ACE_TYPE:
911             ad_ace = (const ACCESS_DENIED_ACE *)ace;
912             sid = (const SID *)&ad_ace->SidStart;
913             if (token_sid_present( token, sid, TRUE ))
914             {
915                 unsigned int access = ad_ace->Mask;
916                 map_generic_mask(&access, mapping);
917                 if (desired_access & MAXIMUM_ALLOWED)
918                     denied_access |= access;
919                 else
920                 {
921                     denied_access |= (access & ~current_access);
922                     if (desired_access & access) goto done;
923                 }
924             }
925             break;
926         case ACCESS_ALLOWED_ACE_TYPE:
927             aa_ace = (const ACCESS_ALLOWED_ACE *)ace;
928             sid = (const SID *)&aa_ace->SidStart;
929             if (token_sid_present( token, sid, FALSE ))
930             {
931                 unsigned int access = aa_ace->Mask;
932                 map_generic_mask(&access, mapping);
933                 if (desired_access & MAXIMUM_ALLOWED)
934                     current_access |= access;
935                 else
936                     current_access |= (access & ~denied_access);
937             }
938             break;
939         }
940
941         /* don't bother carrying on checking if we've already got all of
942             * rights we need */
943         if (desired_access == *granted_access)
944             break;
945     }
946
947 done:
948     if (desired_access & MAXIMUM_ALLOWED)
949         *granted_access = current_access & ~denied_access;
950     else
951         if ((current_access & desired_access) == desired_access)
952             *granted_access = current_access & desired_access;
953         else
954             *granted_access = 0;
955
956     *status = *granted_access ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
957     return STATUS_SUCCESS;
958 }
959
960 const ACL *token_get_default_dacl( struct token *token )
961 {
962     return token->default_dacl;
963 }
964
965 const SID *token_get_user( struct token *token )
966 {
967     return token->user;
968 }
969
970 const SID *token_get_primary_group( struct token *token )
971 {
972     return token->primary_group;
973 }
974
975 int check_object_access(struct object *obj, unsigned int *access)
976 {
977     GENERIC_MAPPING mapping;
978     struct token *token = current->token ? current->token : current->process->token;
979     LUID_AND_ATTRIBUTES priv;
980     unsigned int status, priv_count = 1;
981     int res;
982
983     mapping.GenericAll = obj->ops->map_access( obj, GENERIC_ALL );
984
985     if (!obj->sd)
986     {
987         if (*access & MAXIMUM_ALLOWED)
988             *access = mapping.GenericAll;
989         return TRUE;
990     }
991
992     mapping.GenericRead  = obj->ops->map_access( obj, GENERIC_READ );
993     mapping.GenericWrite = obj->ops->map_access( obj, GENERIC_WRITE );
994     mapping.GenericExecute = obj->ops->map_access( obj, GENERIC_EXECUTE );
995
996     res = token_access_check( token, obj->sd, *access, &priv, &priv_count,
997                               &mapping, access, &status ) == STATUS_SUCCESS &&
998           status == STATUS_SUCCESS;
999
1000     if (!res) set_error( STATUS_ACCESS_DENIED );
1001     return res;
1002 }
1003
1004
1005 /* open a security token */
1006 DECL_HANDLER(open_token)
1007 {
1008     if (req->flags & OPEN_TOKEN_THREAD)
1009     {
1010         struct thread *thread = get_thread_from_handle( req->handle, 0 );
1011         if (thread)
1012         {
1013             if (thread->token)
1014             {
1015                 if (thread->token->impersonation_level <= SecurityAnonymous)
1016                     set_error( STATUS_CANT_OPEN_ANONYMOUS );
1017                 else
1018                     reply->token = alloc_handle( current->process, thread->token,
1019                                                  req->access, req->attributes );
1020             }
1021             else
1022                 set_error( STATUS_NO_TOKEN );
1023             release_object( thread );
1024         }
1025     }
1026     else
1027     {
1028         struct process *process = get_process_from_handle( req->handle, 0 );
1029         if (process)
1030         {
1031             if (process->token)
1032                 reply->token = alloc_handle( current->process, process->token, req->access,
1033                                              req->attributes );
1034             else
1035                 set_error( STATUS_NO_TOKEN );
1036             release_object( process );
1037         }
1038     }
1039 }
1040
1041 /* adjust the privileges held by a token */
1042 DECL_HANDLER(adjust_token_privileges)
1043 {
1044     struct token *token;
1045     unsigned int access = TOKEN_ADJUST_PRIVILEGES;
1046
1047     if (req->get_modified_state) access |= TOKEN_QUERY;
1048
1049     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1050                                                  access, &token_ops )))
1051     {
1052         const LUID_AND_ATTRIBUTES *privs = get_req_data();
1053         LUID_AND_ATTRIBUTES *modified_privs = NULL;
1054         unsigned int priv_count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
1055         unsigned int modified_priv_count = 0;
1056
1057         if (req->get_modified_state && !req->disable_all)
1058         {
1059             unsigned int i;
1060             /* count modified privs */
1061             for (i = 0; i < priv_count; i++)
1062             {
1063                 struct privilege *privilege =
1064                     token_find_privilege( token, &privs[i].Luid, FALSE );
1065                 if (privilege && req->get_modified_state)
1066                     modified_priv_count++;
1067             }
1068             reply->len = modified_priv_count;
1069             modified_priv_count = min( modified_priv_count, get_reply_max_size() / sizeof(*modified_privs) );
1070             if (modified_priv_count)
1071                 modified_privs = set_reply_data_size( modified_priv_count * sizeof(*modified_privs) );
1072         }
1073         reply->len = modified_priv_count * sizeof(*modified_privs);
1074
1075         if (req->disable_all)
1076             token_disable_privileges( token );
1077         else
1078             modified_priv_count = token_adjust_privileges( token, privs,
1079                 priv_count, modified_privs, modified_priv_count );
1080
1081         release_object( token );
1082     }
1083 }
1084
1085 /* retrieves the list of privileges that may be held be the token */
1086 DECL_HANDLER(get_token_privileges)
1087 {
1088     struct token *token;
1089
1090     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1091                                                  TOKEN_QUERY,
1092                                                  &token_ops )))
1093     {
1094         int priv_count = 0;
1095         LUID_AND_ATTRIBUTES *privs;
1096         struct privilege *privilege;
1097
1098         LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
1099             priv_count++;
1100
1101         reply->len = priv_count * sizeof(*privs);
1102         if (reply->len <= get_reply_max_size())
1103         {
1104             privs = set_reply_data_size( priv_count * sizeof(*privs) );
1105             if (privs)
1106             {
1107                 int i = 0;
1108                 LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
1109                 {
1110                     luid_and_attr_from_privilege( &privs[i], privilege );
1111                     i++;
1112                 }
1113             }
1114         }
1115         else
1116             set_error(STATUS_BUFFER_TOO_SMALL);
1117
1118         release_object( token );
1119     }
1120 }
1121
1122 /* creates a duplicate of the token */
1123 DECL_HANDLER(duplicate_token)
1124 {
1125     struct token *src_token;
1126
1127     if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
1128                                                      TOKEN_DUPLICATE,
1129                                                      &token_ops )))
1130     {
1131         struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level );
1132         if (token)
1133         {
1134             reply->new_handle = alloc_handle( current->process, token, req->access, req->attributes);
1135             release_object( token );
1136         }
1137         release_object( src_token );
1138     }
1139 }
1140
1141 /* checks the specified privileges are held by the token */
1142 DECL_HANDLER(check_token_privileges)
1143 {
1144     struct token *token;
1145
1146     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1147                                                  TOKEN_QUERY,
1148                                                  &token_ops )))
1149     {
1150         unsigned int count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
1151
1152         if (!token->primary && token->impersonation_level <= SecurityAnonymous)
1153             set_error( STATUS_BAD_IMPERSONATION_LEVEL );
1154         else if (get_reply_max_size() >= count * sizeof(LUID_AND_ATTRIBUTES))
1155         {
1156             LUID_AND_ATTRIBUTES *usedprivs = set_reply_data_size( count * sizeof(*usedprivs) );
1157             reply->has_privileges = token_check_privileges( token, req->all_required, get_req_data(), count, usedprivs );
1158         }
1159         else
1160             set_error( STATUS_BUFFER_OVERFLOW );
1161         release_object( token );
1162     }
1163 }
1164
1165 /* checks that a user represented by a token is allowed to access an object
1166  * represented by a security descriptor */
1167 DECL_HANDLER(access_check)
1168 {
1169     data_size_t sd_size = get_req_data_size();
1170     const struct security_descriptor *sd = get_req_data();
1171     struct token *token;
1172
1173     if (!sd_is_valid( sd, sd_size ))
1174     {
1175         set_error( STATUS_ACCESS_VIOLATION );
1176         return;
1177     }
1178
1179     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1180                                                  TOKEN_QUERY,
1181                                                  &token_ops )))
1182     {
1183         GENERIC_MAPPING mapping;
1184         unsigned int status;
1185         LUID_AND_ATTRIBUTES priv;
1186         unsigned int priv_count = 1;
1187
1188         memset(&priv, 0, sizeof(priv));
1189
1190         /* only impersonation tokens may be used with this function */
1191         if (token->primary)
1192         {
1193             set_error( STATUS_NO_IMPERSONATION_TOKEN );
1194             release_object( token );
1195             return;
1196         }
1197         /* anonymous impersonation tokens can't be used */
1198         if (token->impersonation_level <= SecurityAnonymous)
1199         {
1200             set_error( STATUS_BAD_IMPERSONATION_LEVEL );
1201             release_object( token );
1202             return;
1203         }
1204
1205         mapping.GenericRead = req->mapping_read;
1206         mapping.GenericWrite = req->mapping_write;
1207         mapping.GenericExecute = req->mapping_execute;
1208         mapping.GenericAll = req->mapping_all;
1209
1210         status = token_access_check(
1211             token, sd, req->desired_access, &priv, &priv_count, &mapping,
1212             &reply->access_granted, &reply->access_status );
1213
1214         reply->privileges_len = priv_count*sizeof(LUID_AND_ATTRIBUTES);
1215
1216         if ((priv_count > 0) && (reply->privileges_len <= get_reply_max_size()))
1217         {
1218             LUID_AND_ATTRIBUTES *privs = set_reply_data_size( priv_count * sizeof(*privs) );
1219             memcpy( privs, &priv, sizeof(priv) );
1220         }
1221
1222         set_error( status );
1223         release_object( token );
1224     }
1225 }
1226
1227 /* retrieves the SID of the user that the token represents */
1228 DECL_HANDLER(get_token_user)
1229 {
1230     struct token *token;
1231
1232     reply->user_len = 0;
1233
1234     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1235                                                  TOKEN_QUERY,
1236                                                  &token_ops )))
1237     {
1238         const SID *user = token->user;
1239
1240         reply->user_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
1241         if (reply->user_len <= get_reply_max_size())
1242         {
1243             SID *user_reply = set_reply_data_size( reply->user_len );
1244             if (user_reply)
1245                 memcpy( user_reply, user, reply->user_len );
1246         }
1247         else set_error( STATUS_BUFFER_TOO_SMALL );
1248
1249         release_object( token );
1250     }
1251 }
1252
1253 /* retrieves the groups that the user represented by the token belongs to */
1254 DECL_HANDLER(get_token_groups)
1255 {
1256     struct token *token;
1257
1258     reply->user_len = 0;
1259
1260     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1261                                                  TOKEN_QUERY,
1262                                                  &token_ops )))
1263     {
1264         size_t size_needed = sizeof(struct token_groups);
1265         unsigned int group_count = 0;
1266         const struct group *group;
1267
1268         LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
1269         {
1270             group_count++;
1271             size_needed += FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]);
1272         }
1273         size_needed += sizeof(unsigned int) * group_count;
1274
1275         reply->user_len = size_needed;
1276
1277         if (size_needed <= get_reply_max_size())
1278         {
1279             struct token_groups *tg = set_reply_data_size( size_needed );
1280             if (tg)
1281             {
1282                 unsigned int *attr_ptr = (unsigned int *)(tg + 1);
1283                 SID *sid_ptr = (SID *)(attr_ptr + group_count);
1284
1285                 tg->count = group_count;
1286
1287                 LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
1288                 {
1289
1290                     *attr_ptr = 0;
1291                     if (group->mandatory) *attr_ptr |= SE_GROUP_MANDATORY;
1292                     if (group->def) *attr_ptr |= SE_GROUP_ENABLED_BY_DEFAULT;
1293                     if (group->enabled) *attr_ptr |= SE_GROUP_ENABLED;
1294                     if (group->owner) *attr_ptr |= SE_GROUP_OWNER;
1295                     if (group->deny_only) *attr_ptr |= SE_GROUP_USE_FOR_DENY_ONLY;
1296                     if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
1297
1298                     memcpy(sid_ptr, &group->sid, FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]));
1299
1300                     sid_ptr = (SID *)((char *)sid_ptr + FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]));
1301                     attr_ptr++;
1302                 }
1303             }
1304         }
1305         else set_error( STATUS_BUFFER_TOO_SMALL );
1306
1307         release_object( token );
1308     }
1309 }
1310
1311 DECL_HANDLER(get_token_impersonation_level)
1312 {
1313     struct token *token;
1314
1315     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1316                                                  TOKEN_QUERY,
1317                                                  &token_ops )))
1318     {
1319         if (token->primary)
1320             set_error( STATUS_INVALID_PARAMETER );
1321         else
1322             reply->impersonation_level = token->impersonation_level;
1323
1324         release_object( token );
1325     }
1326 }
1327
1328 DECL_HANDLER(get_token_statistics)
1329 {
1330     struct token *token;
1331
1332     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1333                                                  TOKEN_QUERY,
1334                                                  &token_ops )))
1335     {
1336         reply->token_id = token->token_id;
1337         reply->modified_id = token->modified_id;
1338         reply->primary = token->primary;
1339         reply->impersonation_level = token->impersonation_level;
1340         reply->group_count = list_count( &token->groups );
1341         reply->privilege_count = list_count( &token->privileges );
1342
1343         release_object( token );
1344     }
1345 }