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