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