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