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