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