advapi32: QueryObjectSecurity should return a self-relative security descriptor and...
[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 struct token *token_duplicate( struct token *src_token, unsigned primary,
524                                SECURITY_IMPERSONATION_LEVEL impersonation_level )
525 {
526     const luid_t *modified_id =
527         primary || (impersonation_level == src_token->impersonation_level) ?
528             &src_token->modified_id : NULL;
529     struct token *token = NULL;
530     struct privilege *privilege;
531     struct group *group;
532
533     if ((impersonation_level < SecurityAnonymous) ||
534         (impersonation_level > SecurityDelegation))
535     {
536         set_error( STATUS_BAD_IMPERSONATION_LEVEL );
537         return NULL;
538     }
539
540     if (primary || (impersonation_level <= src_token->impersonation_level))
541         token = create_token( primary, src_token->user, NULL, 0,
542                               NULL, 0, src_token->default_dacl,
543                               src_token->source, modified_id,
544                               impersonation_level );
545     else set_error( STATUS_BAD_IMPERSONATION_LEVEL );
546
547     if (!token) return token;
548
549     /* copy groups */
550     LIST_FOR_EACH_ENTRY( group, &src_token->groups, struct group, entry )
551     {
552         size_t size = FIELD_OFFSET( struct group, sid.SubAuthority[group->sid.SubAuthorityCount] );
553         struct group *newgroup = mem_alloc( size );
554         if (!newgroup)
555         {
556             release_object( token );
557             return NULL;
558         }
559         memcpy( newgroup, group, size );
560         list_add_tail( &token->groups, &newgroup->entry );
561     }
562     token->primary_group = src_token->primary_group;
563     assert( token->primary_group );
564
565     /* copy privileges */
566     LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
567         if (!privilege_add( token, &privilege->luid, privilege->enabled ))
568         {
569             release_object( token );
570             return NULL;
571         }
572
573     return token;
574 }
575
576 static ACL *create_default_dacl( const SID *user )
577 {
578     ACCESS_ALLOWED_ACE *aaa;
579     ACL *default_dacl;
580     SID *sid;
581     size_t default_dacl_size = sizeof(ACL) +
582                                2*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
583                                sizeof(local_system_sid) +
584                                FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
585
586     default_dacl = mem_alloc( default_dacl_size );
587     if (!default_dacl) return NULL;
588
589     default_dacl->AclRevision = MAX_ACL_REVISION;
590     default_dacl->Sbz1 = 0;
591     default_dacl->AclSize = default_dacl_size;
592     default_dacl->AceCount = 2;
593     default_dacl->Sbz2 = 0;
594
595     /* GENERIC_ALL for Local System */
596     aaa = (ACCESS_ALLOWED_ACE *)(default_dacl + 1);
597     aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
598     aaa->Header.AceFlags = 0;
599     aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
600                           sizeof(local_system_sid);
601     aaa->Mask = GENERIC_ALL;
602     sid = (SID *)&aaa->SidStart;
603     memcpy( sid, &local_system_sid, sizeof(local_system_sid) );
604
605     /* GENERIC_ALL for specified user */
606     aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize);
607     aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
608     aaa->Header.AceFlags = 0;
609     aaa->Header.AceSize = (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
610                           FIELD_OFFSET( SID, SubAuthority[user->SubAuthorityCount] );
611     aaa->Mask = GENERIC_ALL;
612     sid = (SID *)&aaa->SidStart;
613     memcpy( sid, user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
614
615     return default_dacl;
616 }
617
618 struct sid_data
619 {
620     SID_IDENTIFIER_AUTHORITY idauth;
621     int count;
622     unsigned int subauth[MAX_SUBAUTH_COUNT];
623 };
624
625 struct token *token_create_admin( void )
626 {
627     struct token *token = NULL;
628     static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY };
629     static const unsigned int alias_admins_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS };
630     static const unsigned int alias_users_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS };
631     /* on Windows, this value changes every time the user logs on */
632     static const unsigned int logon_subauth[] = { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ };
633     PSID alias_admins_sid;
634     PSID alias_users_sid;
635     PSID logon_sid;
636     /* note: should be the owner specified in the token */
637     ACL *default_dacl = create_default_dacl( &interactive_sid );
638
639     alias_admins_sid = security_sid_alloc( &nt_authority, sizeof(alias_admins_subauth)/sizeof(alias_admins_subauth[0]),
640                                            alias_admins_subauth );
641     alias_users_sid = security_sid_alloc( &nt_authority, sizeof(alias_users_subauth)/sizeof(alias_users_subauth[0]),
642                                           alias_users_subauth );
643     logon_sid = security_sid_alloc( &nt_authority, sizeof(logon_subauth)/sizeof(logon_subauth[0]),
644                                     logon_subauth );
645
646     if (alias_admins_sid && alias_users_sid && logon_sid && default_dacl)
647     {
648         const LUID_AND_ATTRIBUTES admin_privs[] =
649         {
650             { SeChangeNotifyPrivilege        , SE_PRIVILEGE_ENABLED },
651             { SeSecurityPrivilege            , 0                    },
652             { SeBackupPrivilege              , 0                    },
653             { SeRestorePrivilege             , 0                    },
654             { SeSystemtimePrivilege          , 0                    },
655             { SeShutdownPrivilege            , 0                    },
656             { SeRemoteShutdownPrivilege      , 0                    },
657             { SeTakeOwnershipPrivilege       , 0                    },
658             { SeDebugPrivilege               , 0                    },
659             { SeSystemEnvironmentPrivilege   , 0                    },
660             { SeSystemProfilePrivilege       , 0                    },
661             { SeProfileSingleProcessPrivilege, 0                    },
662             { SeIncreaseBasePriorityPrivilege, 0                    },
663             { SeLoadDriverPrivilege          , SE_PRIVILEGE_ENABLED },
664             { SeCreatePagefilePrivilege      , 0                    },
665             { SeIncreaseQuotaPrivilege       , 0                    },
666             { SeUndockPrivilege              , 0                    },
667             { SeManageVolumePrivilege        , 0                    },
668             { SeImpersonatePrivilege         , SE_PRIVILEGE_ENABLED },
669             { SeCreateGlobalPrivilege        , SE_PRIVILEGE_ENABLED },
670         };
671         /* note: we don't include non-builtin groups here for the user -
672          * telling us these is the job of a client-side program */
673         const SID_AND_ATTRIBUTES admin_groups[] =
674         {
675             { security_world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
676             { security_local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
677             { security_interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
678             { security_authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
679             { alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER },
680             { alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
681             { logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID },
682         };
683         static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
684         /* note: we just set the user sid to be the interactive builtin sid -
685          * we should really translate the UNIX user id to a sid */
686         token = create_token( TRUE, &interactive_sid,
687                             admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]),
688                             admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]),
689                             default_dacl, admin_source, NULL, -1 );
690         /* we really need a primary group */
691         assert( token->primary_group );
692     }
693
694     free( logon_sid );
695     free( alias_admins_sid );
696     free( alias_users_sid );
697     free( default_dacl );
698
699     return token;
700 }
701
702 static struct privilege *token_find_privilege( struct token *token, const LUID *luid, int enabled_only )
703 {
704     struct privilege *privilege;
705     LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
706     {
707         if (is_equal_luid( luid, &privilege->luid ))
708         {
709             if (enabled_only && !privilege->enabled)
710                 return NULL;
711             return privilege;
712         }
713     }
714     return NULL;
715 }
716
717 static unsigned int token_adjust_privileges( struct token *token, const LUID_AND_ATTRIBUTES *privs,
718                                              unsigned int count, LUID_AND_ATTRIBUTES *mod_privs,
719                                              unsigned int mod_privs_count )
720 {
721     unsigned int i, modified_count = 0;
722
723     /* mark as modified */
724     allocate_luid( &token->modified_id );
725
726     for (i = 0; i < count; i++)
727     {
728         struct privilege *privilege =
729             token_find_privilege( token, &privs[i].Luid, FALSE );
730         if (!privilege)
731         {
732             set_error( STATUS_NOT_ALL_ASSIGNED );
733             continue;
734         }
735
736         if (privs[i].Attributes & SE_PRIVILEGE_REMOVE)
737             privilege_remove( privilege );
738         else
739         {
740             /* save previous state for caller */
741             if (mod_privs_count)
742             {
743                 luid_and_attr_from_privilege(mod_privs, privilege);
744                 mod_privs++;
745                 mod_privs_count--;
746                 modified_count++;
747             }
748
749             if (privs[i].Attributes & SE_PRIVILEGE_ENABLED)
750                 privilege->enabled = TRUE;
751             else
752                 privilege->enabled = FALSE;
753         }
754     }
755     return modified_count;
756 }
757
758 static void token_disable_privileges( struct token *token )
759 {
760     struct privilege *privilege;
761
762     /* mark as modified */
763     allocate_luid( &token->modified_id );
764
765     LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
766         privilege->enabled = FALSE;
767 }
768
769 int token_check_privileges( struct token *token, int all_required,
770                             const LUID_AND_ATTRIBUTES *reqprivs,
771                             unsigned int count, LUID_AND_ATTRIBUTES *usedprivs)
772 {
773     unsigned int i, enabled_count = 0;
774
775     for (i = 0; i < count; i++)
776     {
777         struct privilege *privilege = 
778             token_find_privilege( token, &reqprivs[i].Luid, TRUE );
779
780         if (usedprivs)
781             usedprivs[i] = reqprivs[i];
782
783         if (privilege && privilege->enabled)
784         {
785             enabled_count++;
786             if (usedprivs)
787                 usedprivs[i].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
788         }
789     }
790
791     if (all_required)
792         return (enabled_count == count);
793     else
794         return (enabled_count > 0);
795 }
796
797 static int token_sid_present( struct token *token, const SID *sid, int deny )
798 {
799     struct group *group;
800
801     if (security_equal_sid( token->user, sid )) return TRUE;
802
803     LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry )
804     {
805         if (!group->enabled) continue;
806         if (group->deny_only && !deny) continue;
807
808         if (security_equal_sid( &group->sid, sid )) return TRUE;
809     }
810
811     return FALSE;
812 }
813
814 /* Checks access to a security descriptor. 'sd' must have been validated by
815  * caller. It returns STATUS_SUCCESS if call succeeded or an error indicating
816  * the reason. 'status' parameter will indicate if access is granted or denied.
817  *
818  * If both returned value and 'status' are STATUS_SUCCESS then access is granted.
819  */
820 static unsigned int token_access_check( struct token *token,
821                                  const struct security_descriptor *sd,
822                                  unsigned int desired_access,
823                                  LUID_AND_ATTRIBUTES *privs,
824                                  unsigned int *priv_count,
825                                  const GENERIC_MAPPING *mapping,
826                                  unsigned int *granted_access,
827                                  unsigned int *status )
828 {
829     unsigned int current_access = 0;
830     unsigned int denied_access = 0;
831     ULONG i;
832     const ACL *dacl;
833     int dacl_present;
834     const ACE_HEADER *ace;
835     const SID *owner;
836
837     /* assume no access rights */
838     *granted_access = 0;
839
840     /* fail if desired_access contains generic rights */
841     if (desired_access & (GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|GENERIC_ALL))
842     {
843         *priv_count = 0;
844         return STATUS_GENERIC_NOT_MAPPED;
845     }
846
847     dacl = sd_get_dacl( sd, &dacl_present );
848     owner = sd_get_owner( sd );
849     if (!owner || !sd_get_group( sd ))
850     {
851         *priv_count = 0;
852         return STATUS_INVALID_SECURITY_DESCR;
853     }
854
855     /* 1: Grant desired access if the object is unprotected */
856     if (!dacl_present)
857     {
858         *priv_count = 0;
859         *granted_access = desired_access;
860         return *status = STATUS_SUCCESS;
861     }
862     if (!dacl)
863     {
864         *priv_count = 0;
865         *status = STATUS_ACCESS_DENIED;
866         return STATUS_SUCCESS;
867     }
868
869     /* 2: Check if caller wants access to system security part. Note: access
870      * is only granted if specifically asked for */
871     if (desired_access & ACCESS_SYSTEM_SECURITY)
872     {
873         const LUID_AND_ATTRIBUTES security_priv = { SeSecurityPrivilege, 0 };
874         LUID_AND_ATTRIBUTES retpriv = security_priv;
875         if (token_check_privileges( token, TRUE, &security_priv, 1, &retpriv ))
876         {
877             if (priv_count)
878             {
879                 /* assumes that there will only be one privilege to return */
880                 if (*priv_count >= 1)
881                 {
882                     *priv_count = 1;
883                     *privs = retpriv;
884                 }
885                 else
886                 {
887                     *priv_count = 1;
888                     return STATUS_BUFFER_TOO_SMALL;
889                 }
890             }
891             current_access |= ACCESS_SYSTEM_SECURITY;
892             if (desired_access == current_access)
893             {
894                 *granted_access = current_access;
895                 return *status = STATUS_SUCCESS;
896             }
897         }
898         else
899         {
900             *priv_count = 0;
901             *status = STATUS_PRIVILEGE_NOT_HELD;
902             return STATUS_SUCCESS;
903         }
904     }
905     else if (priv_count) *priv_count = 0;
906
907     /* 3: Check whether the token is the owner */
908     /* NOTE: SeTakeOwnershipPrivilege is not checked for here - it is instead
909      * checked when a "set owner" call is made, overriding the access rights
910      * determined here. */
911     if (token_sid_present( token, owner, FALSE ))
912     {
913         current_access |= (READ_CONTROL | WRITE_DAC);
914         if (desired_access == current_access)
915         {
916             *granted_access = current_access;
917             return *status = STATUS_SUCCESS;
918         }
919     }
920
921     /* 4: Grant rights according to the DACL */
922     ace = (const ACE_HEADER *)(dacl + 1);
923     for (i = 0; i < dacl->AceCount; i++)
924     {
925         const ACCESS_ALLOWED_ACE *aa_ace;
926         const ACCESS_DENIED_ACE *ad_ace;
927         const SID *sid;
928         switch (ace->AceType)
929         {
930         case ACCESS_DENIED_ACE_TYPE:
931             ad_ace = (const ACCESS_DENIED_ACE *)ace;
932             sid = (const SID *)&ad_ace->SidStart;
933             if (token_sid_present( token, sid, TRUE ))
934             {
935                 unsigned int access = ad_ace->Mask;
936                 map_generic_mask(&access, mapping);
937                 if (desired_access & MAXIMUM_ALLOWED)
938                     denied_access |= access;
939                 else
940                 {
941                     denied_access |= (access & ~current_access);
942                     if (desired_access & access) goto done;
943                 }
944             }
945             break;
946         case ACCESS_ALLOWED_ACE_TYPE:
947             aa_ace = (const ACCESS_ALLOWED_ACE *)ace;
948             sid = (const SID *)&aa_ace->SidStart;
949             if (token_sid_present( token, sid, FALSE ))
950             {
951                 unsigned int access = aa_ace->Mask;
952                 map_generic_mask(&access, mapping);
953                 if (desired_access & MAXIMUM_ALLOWED)
954                     current_access |= access;
955                 else
956                     current_access |= (access & ~denied_access);
957             }
958             break;
959         }
960
961         /* don't bother carrying on checking if we've already got all of
962             * rights we need */
963         if (desired_access == *granted_access)
964             break;
965
966         ace = ace_next( ace );
967     }
968
969 done:
970     if (desired_access & MAXIMUM_ALLOWED)
971         *granted_access = current_access & ~denied_access;
972     else
973         if ((current_access & desired_access) == desired_access)
974             *granted_access = current_access & desired_access;
975         else
976             *granted_access = 0;
977
978     *status = *granted_access ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
979     return STATUS_SUCCESS;
980 }
981
982 const ACL *token_get_default_dacl( struct token *token )
983 {
984     return token->default_dacl;
985 }
986
987 static void set_object_sd( struct object *obj, const struct security_descriptor *sd,
988                            unsigned int set_info )
989 {
990     struct security_descriptor new_sd, *pnew_sd;
991     int present;
992     const SID *owner, *group;
993     const ACL *sacl, *dacl;
994     char *ptr;
995
996     if (!set_info) return;
997
998     new_sd.control = sd->control & ~SE_SELF_RELATIVE;
999
1000     owner = sd_get_owner( sd );
1001     if (set_info & OWNER_SECURITY_INFORMATION && owner)
1002         new_sd.owner_len = sd->owner_len;
1003     else
1004     {
1005         owner = current->process->token->user;
1006         new_sd.owner_len = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
1007         new_sd.control |= SE_OWNER_DEFAULTED;
1008     }
1009
1010     group = sd_get_group( sd );
1011     if (set_info & GROUP_SECURITY_INFORMATION && group)
1012         new_sd.group_len = sd->group_len;
1013     else
1014     {
1015         group = current->process->token->primary_group;
1016         new_sd.group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
1017         new_sd.control |= SE_GROUP_DEFAULTED;
1018     }
1019
1020     new_sd.control |= SE_SACL_PRESENT;
1021     sacl = sd_get_sacl( sd, &present );
1022     if (set_info & SACL_SECURITY_INFORMATION && present)
1023         new_sd.sacl_len = sd->sacl_len;
1024     else
1025     {
1026         if (obj->sd) sacl = sd_get_sacl( obj->sd, &present );
1027
1028         if (obj->sd && present)
1029             new_sd.sacl_len = obj->sd->sacl_len;
1030         else
1031         {
1032             new_sd.sacl_len = 0;
1033             new_sd.control |= SE_SACL_DEFAULTED;
1034         }
1035     }
1036
1037     new_sd.control |= SE_DACL_PRESENT;
1038     dacl = sd_get_dacl( sd, &present );
1039     if (set_info & DACL_SECURITY_INFORMATION && present)
1040         new_sd.dacl_len = sd->dacl_len;
1041     else
1042     {
1043         if (obj->sd) dacl = sd_get_dacl( obj->sd, &present );
1044
1045         if (obj->sd && present)
1046             new_sd.dacl_len = obj->sd->dacl_len;
1047         else
1048         {
1049             dacl = token_get_default_dacl( current->process->token );
1050             new_sd.dacl_len = dacl->AclSize;
1051             new_sd.control |= SE_DACL_DEFAULTED;
1052         }
1053     }
1054
1055     ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len +
1056                      new_sd.sacl_len + new_sd.dacl_len );
1057     if (!ptr) return;
1058     pnew_sd = (struct security_descriptor*)ptr;
1059
1060     memcpy( ptr, &new_sd, sizeof(new_sd) );
1061     ptr += sizeof(new_sd);
1062     memcpy( ptr, owner, new_sd.owner_len );
1063     ptr += new_sd.owner_len;
1064     memcpy( ptr, group, new_sd.group_len );
1065     ptr += new_sd.group_len;
1066     memcpy( ptr, sacl, new_sd.sacl_len );
1067     ptr += new_sd.sacl_len;
1068     memcpy( ptr, dacl, new_sd.dacl_len );
1069
1070     free( obj->sd );
1071     obj->sd = pnew_sd;
1072 }
1073
1074 int check_object_access(struct object *obj, unsigned int *access)
1075 {
1076     GENERIC_MAPPING mapping;
1077     struct token *token = current->token ? current->token : current->process->token;
1078     LUID_AND_ATTRIBUTES priv;
1079     unsigned int status, priv_count = 1;
1080     int res;
1081
1082     mapping.GenericAll = obj->ops->map_access( obj, GENERIC_ALL );
1083
1084     if (!obj->sd)
1085     {
1086         if (*access & MAXIMUM_ALLOWED)
1087             *access = mapping.GenericAll;
1088         return TRUE;
1089     }
1090
1091     mapping.GenericRead  = obj->ops->map_access( obj, GENERIC_READ );
1092     mapping.GenericWrite = obj->ops->map_access( obj, GENERIC_WRITE );
1093     mapping.GenericExecute = obj->ops->map_access( obj, GENERIC_EXECUTE );
1094
1095     res = token_access_check( token, obj->sd, *access, &priv, &priv_count,
1096                               &mapping, access, &status ) == STATUS_SUCCESS &&
1097           status == STATUS_SUCCESS;
1098
1099     if (!res) set_error( STATUS_ACCESS_DENIED );
1100     return res;
1101 }
1102
1103
1104 /* open a security token */
1105 DECL_HANDLER(open_token)
1106 {
1107     if (req->flags & OPEN_TOKEN_THREAD)
1108     {
1109         struct thread *thread = get_thread_from_handle( req->handle, 0 );
1110         if (thread)
1111         {
1112             if (thread->token)
1113             {
1114                 if (thread->token->impersonation_level <= SecurityAnonymous)
1115                     set_error( STATUS_CANT_OPEN_ANONYMOUS );
1116                 else
1117                     reply->token = alloc_handle( current->process, thread->token,
1118                                                  req->access, req->attributes );
1119             }
1120             else
1121                 set_error( STATUS_NO_TOKEN );
1122             release_object( thread );
1123         }
1124     }
1125     else
1126     {
1127         struct process *process = get_process_from_handle( req->handle, 0 );
1128         if (process)
1129         {
1130             if (process->token)
1131                 reply->token = alloc_handle( current->process, process->token, req->access,
1132                                              req->attributes );
1133             else
1134                 set_error( STATUS_NO_TOKEN );
1135             release_object( process );
1136         }
1137     }
1138 }
1139
1140 /* adjust the privileges held by a token */
1141 DECL_HANDLER(adjust_token_privileges)
1142 {
1143     struct token *token;
1144     unsigned int access = TOKEN_ADJUST_PRIVILEGES;
1145
1146     if (req->get_modified_state) access |= TOKEN_QUERY;
1147
1148     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1149                                                  access, &token_ops )))
1150     {
1151         const LUID_AND_ATTRIBUTES *privs = get_req_data();
1152         LUID_AND_ATTRIBUTES *modified_privs = NULL;
1153         unsigned int priv_count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
1154         unsigned int modified_priv_count = 0;
1155
1156         if (req->get_modified_state && !req->disable_all)
1157         {
1158             unsigned int i;
1159             /* count modified privs */
1160             for (i = 0; i < priv_count; i++)
1161             {
1162                 struct privilege *privilege =
1163                     token_find_privilege( token, &privs[i].Luid, FALSE );
1164                 if (privilege && req->get_modified_state)
1165                     modified_priv_count++;
1166             }
1167             reply->len = modified_priv_count;
1168             modified_priv_count = min( modified_priv_count, get_reply_max_size() / sizeof(*modified_privs) );
1169             if (modified_priv_count)
1170                 modified_privs = set_reply_data_size( modified_priv_count * sizeof(*modified_privs) );
1171         }
1172         reply->len = modified_priv_count * sizeof(*modified_privs);
1173
1174         if (req->disable_all)
1175             token_disable_privileges( token );
1176         else
1177             modified_priv_count = token_adjust_privileges( token, privs,
1178                 priv_count, modified_privs, modified_priv_count );
1179
1180         release_object( token );
1181     }
1182 }
1183
1184 /* retrieves the list of privileges that may be held be the token */
1185 DECL_HANDLER(get_token_privileges)
1186 {
1187     struct token *token;
1188
1189     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1190                                                  TOKEN_QUERY,
1191                                                  &token_ops )))
1192     {
1193         int priv_count = 0;
1194         LUID_AND_ATTRIBUTES *privs;
1195         struct privilege *privilege;
1196
1197         LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
1198             priv_count++;
1199
1200         reply->len = priv_count * sizeof(*privs);
1201         if (reply->len <= get_reply_max_size())
1202         {
1203             privs = set_reply_data_size( priv_count * sizeof(*privs) );
1204             if (privs)
1205             {
1206                 int i = 0;
1207                 LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
1208                 {
1209                     luid_and_attr_from_privilege( &privs[i], privilege );
1210                     i++;
1211                 }
1212             }
1213         }
1214         else
1215             set_error(STATUS_BUFFER_TOO_SMALL);
1216
1217         release_object( token );
1218     }
1219 }
1220
1221 /* creates a duplicate of the token */
1222 DECL_HANDLER(duplicate_token)
1223 {
1224     struct token *src_token;
1225
1226     if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
1227                                                      TOKEN_DUPLICATE,
1228                                                      &token_ops )))
1229     {
1230         struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level );
1231         if (token)
1232         {
1233             reply->new_handle = alloc_handle( current->process, token, req->access, req->attributes);
1234             release_object( token );
1235         }
1236         release_object( src_token );
1237     }
1238 }
1239
1240 /* checks the specified privileges are held by the token */
1241 DECL_HANDLER(check_token_privileges)
1242 {
1243     struct token *token;
1244
1245     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1246                                                  TOKEN_QUERY,
1247                                                  &token_ops )))
1248     {
1249         unsigned int count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
1250
1251         if (!token->primary && token->impersonation_level <= SecurityAnonymous)
1252             set_error( STATUS_BAD_IMPERSONATION_LEVEL );
1253         else if (get_reply_max_size() >= count * sizeof(LUID_AND_ATTRIBUTES))
1254         {
1255             LUID_AND_ATTRIBUTES *usedprivs = set_reply_data_size( count * sizeof(*usedprivs) );
1256             reply->has_privileges = token_check_privileges( token, req->all_required, get_req_data(), count, usedprivs );
1257         }
1258         else
1259             set_error( STATUS_BUFFER_OVERFLOW );
1260         release_object( token );
1261     }
1262 }
1263
1264 /* checks that a user represented by a token is allowed to access an object
1265  * represented by a security descriptor */
1266 DECL_HANDLER(access_check)
1267 {
1268     data_size_t sd_size = get_req_data_size();
1269     const struct security_descriptor *sd = get_req_data();
1270     struct token *token;
1271
1272     if (!sd_is_valid( sd, sd_size ))
1273     {
1274         set_error( STATUS_ACCESS_VIOLATION );
1275         return;
1276     }
1277
1278     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1279                                                  TOKEN_QUERY,
1280                                                  &token_ops )))
1281     {
1282         GENERIC_MAPPING mapping;
1283         unsigned int status;
1284         LUID_AND_ATTRIBUTES priv;
1285         unsigned int priv_count = 1;
1286
1287         memset(&priv, 0, sizeof(priv));
1288
1289         /* only impersonation tokens may be used with this function */
1290         if (token->primary)
1291         {
1292             set_error( STATUS_NO_IMPERSONATION_TOKEN );
1293             release_object( token );
1294             return;
1295         }
1296         /* anonymous impersonation tokens can't be used */
1297         if (token->impersonation_level <= SecurityAnonymous)
1298         {
1299             set_error( STATUS_BAD_IMPERSONATION_LEVEL );
1300             release_object( token );
1301             return;
1302         }
1303
1304         mapping.GenericRead = req->mapping_read;
1305         mapping.GenericWrite = req->mapping_write;
1306         mapping.GenericExecute = req->mapping_execute;
1307         mapping.GenericAll = req->mapping_all;
1308
1309         status = token_access_check(
1310             token, sd, req->desired_access, &priv, &priv_count, &mapping,
1311             &reply->access_granted, &reply->access_status );
1312
1313         reply->privileges_len = priv_count*sizeof(LUID_AND_ATTRIBUTES);
1314
1315         if ((priv_count > 0) && (reply->privileges_len <= get_reply_max_size()))
1316         {
1317             LUID_AND_ATTRIBUTES *privs = set_reply_data_size( priv_count * sizeof(*privs) );
1318             memcpy( privs, &priv, sizeof(priv) );
1319         }
1320
1321         set_error( status );
1322         release_object( token );
1323     }
1324 }
1325
1326 /* retrieves the SID of the user that the token represents */
1327 DECL_HANDLER(get_token_user)
1328 {
1329     struct token *token;
1330
1331     reply->user_len = 0;
1332
1333     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1334                                                  TOKEN_QUERY,
1335                                                  &token_ops )))
1336     {
1337         const SID *user = token->user;
1338
1339         reply->user_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
1340         if (reply->user_len <= get_reply_max_size())
1341         {
1342             SID *user_reply = set_reply_data_size( reply->user_len );
1343             if (user_reply)
1344                 memcpy( user_reply, user, reply->user_len );
1345         }
1346         else set_error( STATUS_BUFFER_TOO_SMALL );
1347
1348         release_object( token );
1349     }
1350 }
1351
1352 /* retrieves the groups that the user represented by the token belongs to */
1353 DECL_HANDLER(get_token_groups)
1354 {
1355     struct token *token;
1356
1357     reply->user_len = 0;
1358
1359     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1360                                                  TOKEN_QUERY,
1361                                                  &token_ops )))
1362     {
1363         size_t size_needed = sizeof(struct token_groups);
1364         unsigned int group_count = 0;
1365         const struct group *group;
1366
1367         LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
1368         {
1369             group_count++;
1370             size_needed += FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]);
1371         }
1372         size_needed += sizeof(unsigned int) * group_count;
1373
1374         reply->user_len = size_needed;
1375
1376         if (size_needed <= get_reply_max_size())
1377         {
1378             struct token_groups *tg = set_reply_data_size( size_needed );
1379             if (tg)
1380             {
1381                 unsigned int *attr_ptr = (unsigned int *)(tg + 1);
1382                 SID *sid_ptr = (SID *)(attr_ptr + group_count);
1383
1384                 tg->count = group_count;
1385
1386                 LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
1387                 {
1388
1389                     *attr_ptr = 0;
1390                     if (group->mandatory) *attr_ptr |= SE_GROUP_MANDATORY;
1391                     if (group->def) *attr_ptr |= SE_GROUP_ENABLED_BY_DEFAULT;
1392                     if (group->enabled) *attr_ptr |= SE_GROUP_ENABLED;
1393                     if (group->owner) *attr_ptr |= SE_GROUP_OWNER;
1394                     if (group->deny_only) *attr_ptr |= SE_GROUP_USE_FOR_DENY_ONLY;
1395                     if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
1396
1397                     memcpy(sid_ptr, &group->sid, FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]));
1398
1399                     sid_ptr = (SID *)((char *)sid_ptr + FIELD_OFFSET(SID, SubAuthority[group->sid.SubAuthorityCount]));
1400                     attr_ptr++;
1401                 }
1402             }
1403         }
1404         else set_error( STATUS_BUFFER_TOO_SMALL );
1405
1406         release_object( token );
1407     }
1408 }
1409
1410 DECL_HANDLER(get_token_impersonation_level)
1411 {
1412     struct token *token;
1413
1414     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1415                                                  TOKEN_QUERY,
1416                                                  &token_ops )))
1417     {
1418         if (token->primary)
1419             set_error( STATUS_INVALID_PARAMETER );
1420         else
1421             reply->impersonation_level = token->impersonation_level;
1422
1423         release_object( token );
1424     }
1425 }
1426
1427 DECL_HANDLER(get_token_statistics)
1428 {
1429     struct token *token;
1430
1431     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
1432                                                  TOKEN_QUERY,
1433                                                  &token_ops )))
1434     {
1435         reply->token_id = token->token_id;
1436         reply->modified_id = token->modified_id;
1437         reply->primary = token->primary;
1438         reply->impersonation_level = token->impersonation_level;
1439         reply->group_count = list_count( &token->groups );
1440         reply->privilege_count = list_count( &token->privileges );
1441
1442         release_object( token );
1443     }
1444 }
1445
1446 DECL_HANDLER(set_security_object)
1447 {
1448     data_size_t sd_size = get_req_data_size();
1449     const struct security_descriptor *sd = get_req_data();
1450     struct object *obj;
1451     unsigned int access = 0;
1452
1453     if (!sd_is_valid( sd, sd_size ))
1454     {
1455         set_error( STATUS_ACCESS_VIOLATION );
1456         return;
1457     }
1458
1459     if (req->security_info & OWNER_SECURITY_INFORMATION ||
1460         req->security_info & GROUP_SECURITY_INFORMATION)
1461         access |= WRITE_OWNER;
1462     if (req->security_info & SACL_SECURITY_INFORMATION)
1463         access |= ACCESS_SYSTEM_SECURITY;
1464     if (req->security_info & DACL_SECURITY_INFORMATION)
1465         access |= WRITE_DAC;
1466
1467     if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return;
1468
1469     set_object_sd( obj, sd, req->security_info );
1470     release_object( obj );
1471 }