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