Correct a crash if the length buffer is NULL.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24
25 #include <assert.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #include "windef.h"
30
31 #include "handle.h"
32 #include "thread.h"
33 #include "process.h"
34 #include "request.h"
35 #include "security.h"
36
37 #define MAX_SUBAUTH_COUNT 1
38
39 const LUID SeIncreaseQuotaPrivilege        = {  5, 0 };
40 const LUID SeSecurityPrivilege             = {  8, 0 };
41 const LUID SeTakeOwnershipPrivilege        = {  9, 0 };
42 const LUID SeLoadDriverPrivilege           = { 10, 0 };
43 const LUID SeSystemProfilePrivilege        = { 11, 0 };
44 const LUID SeSystemtimePrivilege           = { 12, 0 };
45 const LUID SeProfileSingleProcessPrivilege = { 13, 0 };
46 const LUID SeIncreaseBasePriorityPrivilege = { 14, 0 };
47 const LUID SeCreatePagefilePrivilege       = { 15, 0 };
48 const LUID SeBackupPrivilege               = { 17, 0 };
49 const LUID SeRestorePrivilege              = { 18, 0 };
50 const LUID SeShutdownPrivilege             = { 19, 0 };
51 const LUID SeDebugPrivilege                = { 20, 0 };
52 const LUID SeSystemEnvironmentPrivilege    = { 22, 0 };
53 const LUID SeChangeNotifyPrivilege         = { 23, 0 };
54 const LUID SeRemoteShutdownPrivilege       = { 24, 0 };
55 const LUID SeUndockPrivilege               = { 25, 0 };
56 const LUID SeManageVolumePrivilege         = { 28, 0 };
57 const LUID SeImpersonatePrivilege          = { 29, 0 };
58 const LUID SeCreateGlobalPrivilege         = { 30, 0 };
59
60 struct token
61 {
62     struct object  obj;             /* object header */
63     struct list    privileges;      /* privileges available to the token */
64     struct list    groups;          /* groups that the user of this token belongs to (sid_and_attributes) */
65     SID           *user;            /* SID of user this token represents */
66 };
67
68 struct privilege
69 {
70     struct list entry;
71     LUID        luid;
72     unsigned    enabled  : 1; /* is the privilege currently enabled? */
73     unsigned    def      : 1; /* is the privilege enabled by default? */
74 };
75
76 struct sid_and_attributes
77 {
78     struct list entry;
79     int         enabled  : 1; /* is the sid currently enabled? */
80     int         def      : 1; /* is the sid enabled by default? */
81     int         logon    : 1; /* is this a logon sid? */
82     int         mandatory: 1; /* is this sid always enabled? */
83     int         owner    : 1; /* can this sid be an owner of an object? */
84     int         resource : 1; /* is this a domain-local group? */
85     int         deny_only: 1; /* is this a sid that should be use for denying only? */
86     SID         sid;
87 };
88
89 static void token_dump( struct object *obj, int verbose );
90 static void token_destroy( struct object *obj );
91
92 static const struct object_ops token_ops =
93 {
94     sizeof(struct token),      /* size */
95     token_dump,                /* dump */
96     no_add_queue,              /* add_queue */
97     NULL,                      /* remove_queue */
98     NULL,                      /* signaled */
99     NULL,                      /* satisfied */
100     no_signal,                 /* signal */
101     no_get_fd,                 /* get_fd */
102     token_destroy              /* destroy */
103 };
104
105
106 static void token_dump( struct object *obj, int verbose )
107 {
108     fprintf( stderr, "Security token\n" );
109     /* FIXME: dump token members */
110 }
111
112 static SID *security_sid_alloc( const SID_IDENTIFIER_AUTHORITY *idauthority, int subauthcount, const unsigned int subauth[] )
113 {
114     int i;
115     SID *sid = mem_alloc( FIELD_OFFSET(SID, SubAuthority[subauthcount]) );
116     if (!sid) return NULL;
117     sid->Revision = MAX_ACL_REVISION;
118     sid->SubAuthorityCount = subauthcount;
119     sid->IdentifierAuthority = *idauthority;
120     for (i = 0; i < subauthcount; i++)
121         sid->SubAuthority[i] = subauth[i];
122     return sid;
123 }
124
125 static inline int security_equal_sid( const SID *sid1, const SID *sid2 )
126 {
127     return ((sid1->SubAuthorityCount == sid2->SubAuthorityCount) &&
128         !memcmp( sid1, sid2, FIELD_OFFSET(SID, SubAuthority[sid1->SubAuthorityCount]) ));
129 }
130
131 static const ACE_HEADER *ace_next( const ACE_HEADER *ace )
132 {
133     return (const ACE_HEADER *)((const char *)ace + ace->AceSize);
134 }
135
136 static int acl_is_valid( const ACL *acl, size_t size )
137 {
138     ULONG i;
139     const ACE_HEADER *ace;
140
141     if (size < sizeof(ACL))
142         return FALSE;
143
144     size = min(size, MAX_ACL_LEN);
145
146     size -= sizeof(ACL);
147
148     ace = (const ACE_HEADER *)(acl + 1);
149     for (i = 0; i < acl->AceCount; i++)
150     {
151         const SID *sid;
152
153         if (size < sizeof(ACE_HEADER))
154             return FALSE;
155         if (size < ace->AceSize)
156             return FALSE;
157         size -= ace->AceSize;
158         switch (ace->AceType)
159         {
160         case ACCESS_DENIED_ACE_TYPE:
161             sid = (const SID *)&((const ACCESS_DENIED_ACE *)ace)->SidStart;
162             break;
163         case ACCESS_ALLOWED_ACE_TYPE:
164             sid = (const SID *)&((const ACCESS_ALLOWED_ACE *)ace)->SidStart;
165             break;
166         case SYSTEM_AUDIT_ACE_TYPE:
167             sid = (const SID *)&((const SYSTEM_AUDIT_ACE *)ace)->SidStart;
168             break;
169         case SYSTEM_ALARM_ACE_TYPE:
170             sid = (const SID *)&((const SYSTEM_ALARM_ACE *)ace)->SidStart;
171             break;
172         default:
173             return FALSE;
174         }
175         if (size < sizeof(SID) ||
176             size < FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]))
177             return FALSE;
178         ace = ace_next( ace );
179     }
180     return TRUE;
181 }
182
183 /* gets the discretionary access control list from a security descriptor */
184 static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present )
185 {
186     *present = (sd->control & SE_DACL_PRESENT ? TRUE : FALSE);
187
188     if (sd->dacl_len)
189         return (const ACL *)((const char *)(sd + 1) +
190             sd->owner_len + sd->group_len + sd->sacl_len);
191     else
192         return NULL;
193 }
194
195 /* gets the system access control list from a security descriptor */
196 static inline const ACL *sd_get_sacl( const struct security_descriptor *sd, int *present )
197 {
198     *present = (sd->control & SE_SACL_PRESENT ? TRUE : FALSE);
199
200     if (sd->sacl_len)
201         return (const ACL *)((const char *)(sd + 1) +
202             sd->owner_len + sd->group_len);
203     else
204         return NULL;
205 }
206
207 /* gets the owner from a security descriptor */
208 static inline const SID *sd_get_owner( const struct security_descriptor *sd )
209 {
210     if (sd->owner_len)
211         return (const SID *)(sd + 1);
212     else
213         return NULL;
214 }
215
216 /* gets the primary group from a security descriptor */
217 static inline const SID *sd_get_group( const struct security_descriptor *sd )
218 {
219     if (sd->group_len)
220         return (const SID *)((const char *)(sd + 1) + sd->owner_len);
221     else
222         return NULL;
223 }
224
225 /* checks whether all members of a security descriptor fit inside the size
226  * of memory specified */
227 static int sd_is_valid( const struct security_descriptor *sd, size_t size )
228 {
229     size_t offset = sizeof(struct security_descriptor);
230     const SID *group;
231     const SID *owner;
232     const ACL *sacl;
233     const ACL *dacl;
234     int dummy;
235
236     if (size < offset)
237         return FALSE;
238
239     if ((sd->owner_len >= FIELD_OFFSET(SID, SubAuthority[255])) ||
240         (offset + sd->owner_len > size))
241         return FALSE;
242     owner = sd_get_owner( sd );
243     if (owner)
244     {
245         size_t needed_size = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
246         if ((sd->owner_len < sizeof(SID)) || (needed_size > sd->owner_len))
247             return FALSE;
248     }
249     offset += sd->owner_len;
250
251     if ((sd->group_len >= FIELD_OFFSET(SID, SubAuthority[255])) ||
252         (offset + sd->group_len > size))
253         return FALSE;
254     group = sd_get_group( sd );
255     if (group)
256     {
257         size_t needed_size = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
258         if ((sd->owner_len < sizeof(SID)) || (needed_size > sd->owner_len))
259             return FALSE;
260     }
261     offset += sd->group_len;
262
263     if ((sd->sacl_len >= MAX_ACL_LEN) || (offset + sd->sacl_len > size))
264         return FALSE;
265     sacl = sd_get_sacl( sd, &dummy );
266     if (sacl && !acl_is_valid( sacl, sd->sacl_len ))
267         return FALSE;
268     offset += sd->sacl_len;
269
270     if ((sd->dacl_len >= MAX_ACL_LEN) || (offset + sd->dacl_len > size))
271         return FALSE;
272     dacl = sd_get_dacl( sd, &dummy );
273     if (dacl && !acl_is_valid( dacl, sd->dacl_len ))
274         return FALSE;
275     offset += sd->dacl_len;
276
277     return TRUE;
278 }
279
280 /* maps from generic rights to specific rights as given by a mapping */
281 static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
282 {
283     if (*mask & GENERIC_READ) *mask |= mapping->GenericRead;
284     if (*mask & GENERIC_WRITE) *mask |= mapping->GenericWrite;
285     if (*mask & GENERIC_EXECUTE) *mask |= mapping->GenericExecute;
286     if (*mask & GENERIC_ALL) *mask |= mapping->GenericAll;
287     *mask &= 0x0FFFFFFF;
288 }
289
290 static inline int is_equal_luid( const LUID *luid1, const LUID *luid2 )
291 {
292     return (luid1->LowPart == luid2->LowPart && luid1->HighPart == luid2->HighPart);
293 }
294
295 static inline void luid_and_attr_from_privilege( LUID_AND_ATTRIBUTES *out, const struct privilege *in)
296 {
297     out->Luid = in->luid;
298     out->Attributes =
299         (in->enabled ? SE_PRIVILEGE_ENABLED : 0) |
300         (in->def ? SE_PRIVILEGE_ENABLED_BY_DEFAULT : 0);
301 }
302
303 static struct privilege *privilege_add( struct token *token, const LUID *luid, int enabled )
304 {
305     struct privilege *privilege = mem_alloc( sizeof(*privilege) );
306     if (privilege)
307     {
308         privilege->luid = *luid;
309         privilege->def = privilege->enabled = (enabled != 0);
310         list_add_tail( &token->privileges, &privilege->entry );
311     }
312     return privilege;
313 }
314
315 static inline void privilege_remove( struct privilege *privilege )
316 {
317     list_remove( &privilege->entry );
318     free( privilege );
319 }
320
321 static void token_destroy( struct object *obj )
322 {
323     struct token* token;
324     struct list *cursor, *cursor_next;
325
326     assert( obj->ops == &token_ops );
327     token = (struct token *)obj;
328
329     free( token->user );
330
331     LIST_FOR_EACH_SAFE( cursor, cursor_next, &token->privileges )
332     {
333         struct privilege *privilege = LIST_ENTRY( cursor, struct privilege, entry );
334         privilege_remove( privilege );
335     }
336
337     LIST_FOR_EACH_SAFE( cursor, cursor_next, &token->groups )
338     {
339         struct sid_and_attributes *group = LIST_ENTRY( cursor, struct sid_and_attributes, entry );
340         list_remove( &group->entry );
341         free( group );
342     }
343 }
344
345 static struct token *create_token( const SID *user, const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count )
346 {
347     struct token *token = alloc_object( &token_ops );
348     if (token)
349     {
350         int i;
351         list_init( &token->privileges );
352         list_init( &token->groups );
353         /* copy user */
354         token->user = memdup( user, FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) );
355         if (!token->user)
356         {
357             release_object( token );
358             return NULL;
359         }
360
361         /* FIXME: copy groups */
362
363         /* copy privileges */
364         for (i = 0; i < priv_count; i++)
365         {
366             /* note: we don't check uniqueness: the caller must make sure
367              * privs doesn't contain any duplicate luids */
368             if (!privilege_add( token, &privs[i].Luid,
369                                 privs[i].Attributes & SE_PRIVILEGE_ENABLED ))
370             {
371                 release_object( token );
372                 return NULL;
373             }
374         }
375     }
376     return token;
377 }
378
379 struct sid_data
380 {
381     SID_IDENTIFIER_AUTHORITY idauth;
382     int count;
383     unsigned int subauth[MAX_SUBAUTH_COUNT];
384 };
385
386 struct token *token_create_admin( void )
387 {
388     struct token *token;
389     const LUID_AND_ATTRIBUTES admin_privs[] =
390     {
391         { SeChangeNotifyPrivilege        , SE_PRIVILEGE_ENABLED },
392         { SeSecurityPrivilege            , 0                    },
393         { SeBackupPrivilege              , 0                    },
394         { SeRestorePrivilege             , 0                    },
395         { SeSystemtimePrivilege          , 0                    },
396         { SeShutdownPrivilege            , 0                    },
397         { SeRemoteShutdownPrivilege      , 0                    },
398         { SeTakeOwnershipPrivilege       , 0                    },
399         { SeDebugPrivilege               , 0                    },
400         { SeSystemEnvironmentPrivilege   , 0                    },
401         { SeSystemProfilePrivilege       , 0                    },
402         { SeProfileSingleProcessPrivilege, 0                    },
403         { SeIncreaseBasePriorityPrivilege, 0                    },
404         { SeLoadDriverPrivilege          , 0                    },
405         { SeCreatePagefilePrivilege      , 0                    },
406         { SeIncreaseQuotaPrivilege       , 0                    },
407         { SeUndockPrivilege              , 0                    },
408         { SeManageVolumePrivilege        , 0                    },
409         { SeImpersonatePrivilege         , SE_PRIVILEGE_ENABLED },
410         { SeCreateGlobalPrivilege        , SE_PRIVILEGE_ENABLED },
411     };
412     static const struct sid_data well_known_sid_data[] =
413     {
414         { { SECURITY_NT_AUTHORITY }, 1, { SECURITY_LOCAL_SYSTEM_RID } }, /* LOCAL_SYSTEM */
415     };
416     SID *local_system_sid = security_sid_alloc(
417         &well_known_sid_data[0].idauth,
418         well_known_sid_data[0].count,
419         well_known_sid_data[0].subauth );
420     if (!local_system_sid) return NULL;
421     token = create_token( local_system_sid, admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]) );
422     free( local_system_sid );
423     return token;
424 }
425
426 static struct privilege *token_find_privilege( struct token *token, const LUID *luid, int enabled_only)
427 {
428     struct privilege *privilege;
429     LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
430     {
431         if (is_equal_luid( luid, &privilege->luid ))
432         {
433             if (enabled_only && !privilege->enabled)
434                 return NULL;
435             return privilege;
436         }
437     }
438     return NULL;
439 }
440
441 static unsigned int token_adjust_privileges( struct token *token, const LUID_AND_ATTRIBUTES *privs,
442                                              unsigned int count, LUID_AND_ATTRIBUTES *mod_privs,
443                                              unsigned int mod_privs_count)
444 {
445     int i;
446     unsigned int modified_count = 0;
447
448     for (i = 0; i < count; i++)
449     {
450         struct privilege *privilege =
451             token_find_privilege( token, &privs[i].Luid, FALSE );
452         if (!privilege)
453         {
454             set_error( STATUS_NOT_ALL_ASSIGNED );
455             continue;
456         }
457
458         if (privs[i].Attributes & SE_PRIVILEGE_REMOVE)
459             privilege_remove( privilege );
460         else
461         {
462             /* save previous state for caller */
463             if (mod_privs_count)
464             {
465                 luid_and_attr_from_privilege(mod_privs, privilege);
466                 mod_privs++;
467                 mod_privs_count--;
468                 modified_count++;
469             }
470
471             if (privs[i].Attributes & SE_PRIVILEGE_ENABLED)
472                 privilege->enabled = TRUE;
473             else
474                 privilege->enabled = FALSE;
475         }
476     }
477     return modified_count;
478 }
479
480 static void token_disable_privileges( struct token *token )
481 {
482     struct privilege *privilege;
483     LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
484         privilege->enabled = FALSE;
485 }
486
487 int token_check_privileges( struct token *token, int all_required,
488                             const LUID_AND_ATTRIBUTES *reqprivs,
489                             unsigned int count, LUID_AND_ATTRIBUTES *usedprivs)
490 {
491     int i;
492     unsigned int enabled_count = 0;
493
494     for (i = 0; i < count; i++)
495     {
496         struct privilege *privilege = 
497             token_find_privilege( token, &reqprivs[i].Luid, TRUE );
498
499         if (usedprivs)
500             usedprivs[i] = reqprivs[i];
501
502         if (privilege && privilege->enabled)
503         {
504             enabled_count++;
505             if (usedprivs)
506                 usedprivs[i].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
507         }
508     }
509
510     if (all_required)
511         return (enabled_count == count);
512     else
513         return (enabled_count > 0);
514 }
515
516 static int token_sid_present( struct token *token, const SID *sid, int deny )
517 {
518     struct sid_and_attributes *group;
519
520     if (security_equal_sid( token->user, sid )) return TRUE;
521
522     LIST_FOR_EACH_ENTRY( group, &token->groups, struct sid_and_attributes, entry )
523     {
524         if (!group->enabled) continue;
525         if (group->deny_only && !deny) continue;
526
527         if (security_equal_sid( &group->sid, sid )) return TRUE;
528     }
529
530     return FALSE;
531 }
532
533 /* checks access to a security descriptor. sd must have been validated by caller.
534  * it returns STATUS_SUCCESS if access was granted to the object, or an error
535  * status code if not, giving the reason. errors not relating to giving access
536  * to the object are returned in the status parameter. granted_access and
537  * status always have a valid value stored in them on return. */
538 static unsigned int token_access_check( struct token *token,
539                                  const struct security_descriptor *sd,
540                                  unsigned int desired_access,
541                                  LUID_AND_ATTRIBUTES *privs,
542                                  unsigned int *priv_count,
543                                  const GENERIC_MAPPING *mapping,
544                                  unsigned int *granted_access,
545                                  unsigned int *status )
546 {
547     unsigned int current_access = 0;
548     unsigned int denied_access = 0;
549     ULONG i;
550     const ACL *dacl;
551     int dacl_present;
552     const ACE_HEADER *ace;
553     const SID *owner;
554
555     /* assume success, but no access rights */
556     *status = STATUS_SUCCESS;
557     *granted_access = 0;
558
559     /* fail if desired_access contains generic rights */
560     if (desired_access & (GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|GENERIC_ALL))
561     {
562         *priv_count = 0;
563         *status = STATUS_GENERIC_NOT_MAPPED;
564         return STATUS_ACCESS_DENIED;
565     }
566
567     dacl = sd_get_dacl( sd, &dacl_present );
568     owner = sd_get_owner( sd );
569     if (!owner || !sd_get_group( sd ))
570     {
571         *priv_count = 0;
572         *status = STATUS_INVALID_SECURITY_DESCR;
573         return STATUS_ACCESS_DENIED;
574     }
575
576     /* 1: Grant desired access if the object is unprotected */
577     if (!dacl_present)
578     {
579         *priv_count = 0;
580         *granted_access = desired_access;
581         return STATUS_SUCCESS;
582     }
583     if (!dacl)
584     {
585         *priv_count = 0;
586         return STATUS_ACCESS_DENIED;
587     }
588
589     /* 2: Check if caller wants access to system security part. Note: access
590      * is only granted if specifically asked for */
591     if (desired_access & ACCESS_SYSTEM_SECURITY)
592     {
593         const LUID_AND_ATTRIBUTES security_priv = { SeSecurityPrivilege, 0 };
594         LUID_AND_ATTRIBUTES retpriv = security_priv;
595         if (token_check_privileges( token, TRUE, &security_priv, 1, &retpriv ))
596         {
597             if (priv_count)
598             {
599                 /* assumes that there will only be one privilege to return */
600                 if (*priv_count >= 1)
601                 {
602                     *priv_count = 1;
603                     *privs = retpriv;
604                 }
605                 else
606                 {
607                     *priv_count = 1;
608                     return STATUS_BUFFER_TOO_SMALL;
609                 }
610             }
611             current_access |= ACCESS_SYSTEM_SECURITY;
612             if (desired_access == current_access)
613             {
614                 *granted_access = current_access;
615                 return STATUS_SUCCESS;
616             }
617         }
618         else
619         {
620             *priv_count = 0;
621             return STATUS_PRIVILEGE_NOT_HELD;
622         }
623     }
624     else if (priv_count) *priv_count = 0;
625
626     /* 3: Check whether the token is the owner */
627     /* NOTE: SeTakeOwnershipPrivilege is not checked for here - it is instead
628      * checked when a "set owner" call is made, overriding the access rights
629      * determined here. */
630     if (token_sid_present( token, owner, FALSE ))
631     {
632         current_access |= (READ_CONTROL | WRITE_DAC);
633         if (desired_access == current_access)
634         {
635             *granted_access = current_access;
636             return STATUS_SUCCESS;
637         }
638     }
639
640     /* 4: Grant rights according to the DACL */
641     ace = (const ACE_HEADER *)(dacl + 1);
642     for (i = 0; i < dacl->AceCount; i++)
643     {
644         const ACCESS_ALLOWED_ACE *aa_ace;
645         const ACCESS_DENIED_ACE *ad_ace;
646         const SID *sid;
647         switch (ace->AceType)
648         {
649         case ACCESS_DENIED_ACE_TYPE:
650             ad_ace = (const ACCESS_DENIED_ACE *)ace;
651             sid = (const SID *)&ad_ace->SidStart;
652             if (token_sid_present( token, sid, TRUE ))
653             {
654                 unsigned int access = ad_ace->Mask;
655                 map_generic_mask(&access, mapping);
656                 if (desired_access & MAXIMUM_ALLOWED)
657                     denied_access |= access;
658                 else
659                 {
660                     denied_access |= (access & ~current_access);
661                     if (desired_access & access)
662                     {
663                         *granted_access = 0;
664                         return STATUS_SUCCESS;
665                     }
666                 }
667             }
668             break;
669         case ACCESS_ALLOWED_ACE_TYPE:
670             aa_ace = (const ACCESS_ALLOWED_ACE *)ace;
671             sid = (const SID *)&aa_ace->SidStart;
672             if (token_sid_present( token, sid, FALSE ))
673             {
674                 unsigned int access = aa_ace->Mask;
675                 map_generic_mask(&access, mapping);
676                 if (desired_access & MAXIMUM_ALLOWED)
677                     current_access |= access;
678                 else
679                     current_access |= (access & ~denied_access);
680             }
681             break;
682         }
683
684         /* don't bother carrying on checking if we've already got all of
685             * rights we need */
686         if (desired_access == *granted_access)
687             break;
688
689         ace = ace_next( ace );
690     }
691
692     if (desired_access & MAXIMUM_ALLOWED)
693     {
694         *granted_access = current_access & ~denied_access;
695         if (*granted_access)
696             return STATUS_SUCCESS;
697         else
698             return STATUS_ACCESS_DENIED;
699     }
700     else
701     {
702         if ((current_access & desired_access) == desired_access)
703         {
704             *granted_access = current_access & desired_access;
705             return STATUS_SUCCESS;
706         }
707         else
708             return STATUS_ACCESS_DENIED;
709     }
710 }
711
712 /* open a security token */
713 DECL_HANDLER(open_token)
714 {
715     if( req->flags & OPEN_TOKEN_THREAD )
716     {
717         struct thread *thread = get_thread_from_handle( req->handle, 0 );
718         if (thread)
719         {
720             if (thread->token)
721                 reply->token = alloc_handle( current->process, thread->token, TOKEN_ALL_ACCESS, 0);
722             else
723                 set_error(STATUS_NO_TOKEN);
724             release_object( thread );
725         }
726     }
727     else
728     {
729         struct process *process = get_process_from_handle( req->handle, 0 );
730         if (process)
731         {
732             if (process->token)
733                 reply->token = alloc_handle( current->process, process->token, TOKEN_ALL_ACCESS, 0);
734             else
735                 set_error(STATUS_NO_TOKEN);
736             release_object( process );
737         }
738     }
739 }
740
741 /* adjust the privileges held by a token */
742 DECL_HANDLER(adjust_token_privileges)
743 {
744     struct token *token;
745     unsigned int access = TOKEN_ADJUST_PRIVILEGES;
746
747     if (req->get_modified_state) access |= TOKEN_QUERY;
748
749     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
750                                                  access, &token_ops )))
751     {
752         const LUID_AND_ATTRIBUTES *privs = get_req_data();
753         LUID_AND_ATTRIBUTES *modified_privs = NULL;
754         unsigned int priv_count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
755         unsigned int modified_priv_count = 0;
756
757         if (req->get_modified_state && !req->disable_all)
758         {
759             int i;
760             /* count modified privs */
761             for (i = 0; i < priv_count; i++)
762             {
763                 struct privilege *privilege =
764                     token_find_privilege( token, &privs[i].Luid, FALSE );
765                 if (privilege && req->get_modified_state)
766                     modified_priv_count++;
767             }
768             reply->len = modified_priv_count;
769             modified_priv_count = min( modified_priv_count, get_reply_max_size() / sizeof(*modified_privs) );
770             if (modified_priv_count)
771                 modified_privs = set_reply_data_size( modified_priv_count * sizeof(*modified_privs) );
772         }
773         reply->len = modified_priv_count * sizeof(*modified_privs);
774
775         if (req->disable_all)
776             token_disable_privileges( token );
777         else
778             modified_priv_count = token_adjust_privileges( token, privs,
779                 priv_count, modified_privs, modified_priv_count );
780
781         release_object( token );
782     }
783 }
784
785 /* retrieves the list of privileges that may be held be the token */
786 DECL_HANDLER(get_token_privileges)
787 {
788     struct token *token;
789
790     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
791                                                  TOKEN_QUERY,
792                                                  &token_ops )))
793     {
794         int priv_count = 0;
795         LUID_AND_ATTRIBUTES *privs;
796         struct privilege *privilege;
797
798         LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
799             priv_count++;
800
801         reply->len = priv_count * sizeof(*privs);
802         if (reply->len <= get_reply_max_size())
803         {
804             privs = set_reply_data_size( priv_count * sizeof(*privs) );
805             if (privs)
806             {
807                 int i = 0;
808                 LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry )
809                 {
810                     luid_and_attr_from_privilege( &privs[i], privilege );
811                     i++;
812                 }
813             }
814         }
815         else
816             set_error(STATUS_BUFFER_TOO_SMALL);
817
818         release_object( token );
819     }
820 }
821
822 /* creates a duplicate of the token */
823 DECL_HANDLER(duplicate_token)
824 {
825     struct token *src_token;
826     if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
827                                                      TOKEN_DUPLICATE,
828                                                      &token_ops )))
829     {
830         /* FIXME: use req->primary and req->impersonation_level */
831         struct token *token = create_token( src_token->user, NULL, 0 );
832         if (token)
833         {
834             struct privilege *privilege;
835             unsigned int access;
836
837             LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
838                 privilege_add( token, &privilege->luid, privilege->enabled );
839
840             access = req->access;
841             if (access & MAXIMUM_ALLOWED) access = TOKEN_ALL_ACCESS; /* FIXME: needs general solution */
842             reply->new_handle = alloc_handle( current->process, token, access, req->inherit);
843             release_object( token );
844         }
845         release_object( src_token );
846     }
847 }
848
849 /* checks the specified privileges are held by the token */
850 DECL_HANDLER(check_token_privileges)
851 {
852     struct token *token;
853
854     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
855                                                  TOKEN_QUERY,
856                                                  &token_ops )))
857     {
858         unsigned int count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES);
859         if (get_reply_max_size() >= count * sizeof(LUID_AND_ATTRIBUTES))
860         {
861             LUID_AND_ATTRIBUTES *usedprivs = set_reply_data_size( count * sizeof(*usedprivs) );
862             reply->has_privileges = token_check_privileges( token, req->all_required, get_req_data(), count, usedprivs );
863         }
864         else
865             set_error( STATUS_BUFFER_OVERFLOW );
866         release_object( token );
867     }
868 }
869
870 /* checks that a user represented by a token is allowed to access an object
871  * represented by a security descriptor */
872 DECL_HANDLER(access_check)
873 {
874     size_t sd_size = get_req_data_size();
875     const struct security_descriptor *sd = get_req_data();
876     struct token *token;
877
878     if (!sd_is_valid( sd, sd_size ))
879     {
880         set_error( STATUS_ACCESS_VIOLATION );
881         return;
882     }
883
884     if ((token = (struct token *)get_handle_obj( current->process, req->handle,
885                                                  TOKEN_QUERY,
886                                                  &token_ops )))
887     {
888         GENERIC_MAPPING mapping;
889         unsigned int status;
890         LUID_AND_ATTRIBUTES priv;
891         unsigned int priv_count = 1;
892
893         memset(&priv, 0, sizeof(priv));
894
895         /* FIXME: check token is an impersonation token, if not return
896          * STATUS_NO_IMPERSONATION_TOKEN */
897
898         mapping.GenericRead = req->mapping_read;
899         mapping.GenericWrite = req->mapping_write;
900         mapping.GenericExecute = req->mapping_execute;
901         mapping.GenericAll = req->mapping_all;
902
903         reply->access_status = token_access_check(
904             token, sd, req->desired_access, &priv, &priv_count, &mapping,
905             &reply->access_granted, &status );
906
907         reply->privileges_len = priv_count*sizeof(LUID_AND_ATTRIBUTES);
908
909         if ((priv_count > 0) && (reply->privileges_len <= get_reply_max_size()))
910         {
911             LUID_AND_ATTRIBUTES *privs = set_reply_data_size( priv_count * sizeof(*privs) );
912             memcpy( privs, &priv, sizeof(priv) );
913         }
914
915         if (status != STATUS_SUCCESS)
916             set_error( status );
917
918         release_object( token );
919     }
920 }