4 * Copyright (C) 1998 Alexandre Julliard
5 * Copyright (C) 2003 Mike McCormack
6 * Copyright (C) 2005 Robert Shearman
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.
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.
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
37 #define MAX_SUBAUTH_COUNT 1
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 };
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
;
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 ACL
*default_dacl
; /* the default DACL to assign to objects created by this user */
84 unsigned enabled
: 1; /* is the privilege currently enabled? */
85 unsigned def
: 1; /* is the privilege enabled by default? */
88 struct sid_and_attributes
91 unsigned enabled
: 1; /* is the sid currently enabled? */
92 unsigned def
: 1; /* is the sid enabled by default? */
93 unsigned logon
: 1; /* is this a logon sid? */
94 unsigned mandatory
: 1; /* is this sid always enabled? */
95 unsigned owner
: 1; /* can this sid be an owner of an object? */
96 unsigned resource
: 1; /* is this a domain-local group? */
97 unsigned deny_only
: 1; /* is this a sid that should be use for denying only? */
101 static void token_dump( struct object
*obj
, int verbose
);
102 static void token_destroy( struct object
*obj
);
104 static const struct object_ops token_ops
=
106 sizeof(struct token
), /* size */
107 token_dump
, /* dump */
108 no_add_queue
, /* add_queue */
109 NULL
, /* remove_queue */
111 NULL
, /* satisfied */
112 no_signal
, /* signal */
113 no_get_fd
, /* get_fd */
114 no_close_handle
, /* close_handle */
115 token_destroy
/* destroy */
119 static void token_dump( struct object
*obj
, int verbose
)
121 fprintf( stderr
, "Security token\n" );
122 /* FIXME: dump token members */
125 static SID
*security_sid_alloc( const SID_IDENTIFIER_AUTHORITY
*idauthority
, int subauthcount
, const unsigned int subauth
[] )
128 SID
*sid
= mem_alloc( FIELD_OFFSET(SID
, SubAuthority
[subauthcount
]) );
129 if (!sid
) return NULL
;
130 sid
->Revision
= SID_REVISION
;
131 sid
->SubAuthorityCount
= subauthcount
;
132 sid
->IdentifierAuthority
= *idauthority
;
133 for (i
= 0; i
< subauthcount
; i
++)
134 sid
->SubAuthority
[i
] = subauth
[i
];
138 static inline int security_equal_sid( const SID
*sid1
, const SID
*sid2
)
140 return ((sid1
->SubAuthorityCount
== sid2
->SubAuthorityCount
) &&
141 !memcmp( sid1
, sid2
, FIELD_OFFSET(SID
, SubAuthority
[sid1
->SubAuthorityCount
]) ));
144 void security_set_thread_token( struct thread
*thread
, obj_handle_t handle
)
149 release_object( thread
->token
);
150 thread
->token
= NULL
;
154 struct token
*token
= (struct token
*)get_handle_obj( current
->process
,
161 release_object( thread
->token
);
162 thread
->token
= token
;
167 static const ACE_HEADER
*ace_next( const ACE_HEADER
*ace
)
169 return (const ACE_HEADER
*)((const char *)ace
+ ace
->AceSize
);
172 static int acl_is_valid( const ACL
*acl
, size_t size
)
175 const ACE_HEADER
*ace
;
177 if (size
< sizeof(ACL
))
180 size
= min(size
, MAX_ACL_LEN
);
184 ace
= (const ACE_HEADER
*)(acl
+ 1);
185 for (i
= 0; i
< acl
->AceCount
; i
++)
190 if (size
< sizeof(ACE_HEADER
))
192 if (size
< ace
->AceSize
)
194 size
-= ace
->AceSize
;
195 switch (ace
->AceType
)
197 case ACCESS_DENIED_ACE_TYPE
:
198 sid
= (const SID
*)&((const ACCESS_DENIED_ACE
*)ace
)->SidStart
;
199 sid_size
= ace
->AceSize
- FIELD_OFFSET(ACCESS_DENIED_ACE
, SidStart
);
201 case ACCESS_ALLOWED_ACE_TYPE
:
202 sid
= (const SID
*)&((const ACCESS_ALLOWED_ACE
*)ace
)->SidStart
;
203 sid_size
= ace
->AceSize
- FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
);
205 case SYSTEM_AUDIT_ACE_TYPE
:
206 sid
= (const SID
*)&((const SYSTEM_AUDIT_ACE
*)ace
)->SidStart
;
207 sid_size
= ace
->AceSize
- FIELD_OFFSET(SYSTEM_AUDIT_ACE
, SidStart
);
209 case SYSTEM_ALARM_ACE_TYPE
:
210 sid
= (const SID
*)&((const SYSTEM_ALARM_ACE
*)ace
)->SidStart
;
211 sid_size
= ace
->AceSize
- FIELD_OFFSET(SYSTEM_ALARM_ACE
, SidStart
);
216 if (sid_size
< FIELD_OFFSET(SID
, SubAuthority
[0]) ||
217 sid_size
< FIELD_OFFSET(SID
, SubAuthority
[sid
->SubAuthorityCount
]))
219 ace
= ace_next( ace
);
224 /* gets the discretionary access control list from a security descriptor */
225 static inline const ACL
*sd_get_dacl( const struct security_descriptor
*sd
, int *present
)
227 *present
= (sd
->control
& SE_DACL_PRESENT
? TRUE
: FALSE
);
230 return (const ACL
*)((const char *)(sd
+ 1) +
231 sd
->owner_len
+ sd
->group_len
+ sd
->sacl_len
);
236 /* gets the system access control list from a security descriptor */
237 static inline const ACL
*sd_get_sacl( const struct security_descriptor
*sd
, int *present
)
239 *present
= (sd
->control
& SE_SACL_PRESENT
? TRUE
: FALSE
);
242 return (const ACL
*)((const char *)(sd
+ 1) +
243 sd
->owner_len
+ sd
->group_len
);
248 /* gets the owner from a security descriptor */
249 static inline const SID
*sd_get_owner( const struct security_descriptor
*sd
)
252 return (const SID
*)(sd
+ 1);
257 /* gets the primary group from a security descriptor */
258 static inline const SID
*sd_get_group( const struct security_descriptor
*sd
)
261 return (const SID
*)((const char *)(sd
+ 1) + sd
->owner_len
);
266 /* checks whether all members of a security descriptor fit inside the size
267 * of memory specified */
268 static int sd_is_valid( const struct security_descriptor
*sd
, size_t size
)
270 size_t offset
= sizeof(struct security_descriptor
);
280 if ((sd
->owner_len
>= FIELD_OFFSET(SID
, SubAuthority
[255])) ||
281 (offset
+ sd
->owner_len
> size
))
283 owner
= sd_get_owner( sd
);
286 size_t needed_size
= FIELD_OFFSET(SID
, SubAuthority
[owner
->SubAuthorityCount
]);
287 if ((sd
->owner_len
< sizeof(SID
)) || (needed_size
> sd
->owner_len
))
290 offset
+= sd
->owner_len
;
292 if ((sd
->group_len
>= FIELD_OFFSET(SID
, SubAuthority
[255])) ||
293 (offset
+ sd
->group_len
> size
))
295 group
= sd_get_group( sd
);
298 size_t needed_size
= FIELD_OFFSET(SID
, SubAuthority
[group
->SubAuthorityCount
]);
299 if ((sd
->owner_len
< sizeof(SID
)) || (needed_size
> sd
->owner_len
))
302 offset
+= sd
->group_len
;
304 if ((sd
->sacl_len
>= MAX_ACL_LEN
) || (offset
+ sd
->sacl_len
> size
))
306 sacl
= sd_get_sacl( sd
, &dummy
);
307 if (sacl
&& !acl_is_valid( sacl
, sd
->sacl_len
))
309 offset
+= sd
->sacl_len
;
311 if ((sd
->dacl_len
>= MAX_ACL_LEN
) || (offset
+ sd
->dacl_len
> size
))
313 dacl
= sd_get_dacl( sd
, &dummy
);
314 if (dacl
&& !acl_is_valid( dacl
, sd
->dacl_len
))
316 offset
+= sd
->dacl_len
;
321 /* maps from generic rights to specific rights as given by a mapping */
322 static inline void map_generic_mask(unsigned int *mask
, const GENERIC_MAPPING
*mapping
)
324 if (*mask
& GENERIC_READ
) *mask
|= mapping
->GenericRead
;
325 if (*mask
& GENERIC_WRITE
) *mask
|= mapping
->GenericWrite
;
326 if (*mask
& GENERIC_EXECUTE
) *mask
|= mapping
->GenericExecute
;
327 if (*mask
& GENERIC_ALL
) *mask
|= mapping
->GenericAll
;
331 static inline int is_equal_luid( const LUID
*luid1
, const LUID
*luid2
)
333 return (luid1
->LowPart
== luid2
->LowPart
&& luid1
->HighPart
== luid2
->HighPart
);
336 static inline void luid_and_attr_from_privilege( LUID_AND_ATTRIBUTES
*out
, const struct privilege
*in
)
338 out
->Luid
= in
->luid
;
340 (in
->enabled
? SE_PRIVILEGE_ENABLED
: 0) |
341 (in
->def
? SE_PRIVILEGE_ENABLED_BY_DEFAULT
: 0);
344 static struct privilege
*privilege_add( struct token
*token
, const LUID
*luid
, int enabled
)
346 struct privilege
*privilege
= mem_alloc( sizeof(*privilege
) );
349 privilege
->luid
= *luid
;
350 privilege
->def
= privilege
->enabled
= (enabled
!= 0);
351 list_add_tail( &token
->privileges
, &privilege
->entry
);
356 static inline void privilege_remove( struct privilege
*privilege
)
358 list_remove( &privilege
->entry
);
362 static void token_destroy( struct object
*obj
)
365 struct list
*cursor
, *cursor_next
;
367 assert( obj
->ops
== &token_ops
);
368 token
= (struct token
*)obj
;
372 LIST_FOR_EACH_SAFE( cursor
, cursor_next
, &token
->privileges
)
374 struct privilege
*privilege
= LIST_ENTRY( cursor
, struct privilege
, entry
);
375 privilege_remove( privilege
);
378 LIST_FOR_EACH_SAFE( cursor
, cursor_next
, &token
->groups
)
380 struct sid_and_attributes
*group
= LIST_ENTRY( cursor
, struct sid_and_attributes
, entry
);
381 list_remove( &group
->entry
);
385 free( token
->default_dacl
);
388 /* creates a new token.
389 * groups may be NULL if group_count is 0.
390 * privs may be NULL if priv_count is 0.
391 * default_dacl may be NULL, indicating that all objects created by the user
394 static struct token
*create_token( unsigned primary
, const SID
*user
,
395 const SID_AND_ATTRIBUTES
*groups
, unsigned int group_count
,
396 const LUID_AND_ATTRIBUTES
*privs
, unsigned int priv_count
,
397 const ACL
*default_dacl
)
399 struct token
*token
= alloc_object( &token_ops
);
404 list_init( &token
->privileges
);
405 list_init( &token
->groups
);
406 token
->primary
= primary
;
409 token
->user
= memdup( user
, FIELD_OFFSET(SID
, SubAuthority
[user
->SubAuthorityCount
]) );
412 release_object( token
);
417 for (i
= 0; i
< group_count
; i
++)
419 size_t size
= FIELD_OFFSET( struct sid_and_attributes
, sid
.SubAuthority
[((const SID
*)groups
[i
].Sid
)->SubAuthorityCount
] );
420 struct sid_and_attributes
*group
= mem_alloc( size
);
421 memcpy( &group
->sid
, groups
[i
].Sid
, FIELD_OFFSET( SID
, SubAuthority
[((const SID
*)groups
[i
].Sid
)->SubAuthorityCount
] ) );
422 group
->enabled
= TRUE
;
424 group
->logon
= FALSE
;
425 group
->mandatory
= (groups
[i
].Attributes
& SE_GROUP_MANDATORY
) ? TRUE
: FALSE
;
426 group
->owner
= FALSE
;
427 group
->resource
= FALSE
;
428 group
->deny_only
= FALSE
;
429 list_add_tail( &token
->groups
, &group
->entry
);
432 /* copy privileges */
433 for (i
= 0; i
< priv_count
; i
++)
435 /* note: we don't check uniqueness: the caller must make sure
436 * privs doesn't contain any duplicate luids */
437 if (!privilege_add( token
, &privs
[i
].Luid
,
438 privs
[i
].Attributes
& SE_PRIVILEGE_ENABLED
))
440 release_object( token
);
447 token
->default_dacl
= memdup( default_dacl
, default_dacl
->AclSize
);
448 if (!token
->default_dacl
)
450 release_object( token
);
455 token
->default_dacl
= NULL
;
460 static ACL
*create_default_dacl( const SID
*user
)
462 ACCESS_ALLOWED_ACE
*aaa
;
465 size_t default_dacl_size
= sizeof(ACL
) +
466 2*(sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
)) +
467 sizeof(local_system_sid
) +
468 FIELD_OFFSET(SID
, SubAuthority
[user
->SubAuthorityCount
]);
470 default_dacl
= mem_alloc( default_dacl_size
);
471 if (!default_dacl
) return NULL
;
473 default_dacl
->AclRevision
= MAX_ACL_REVISION
;
474 default_dacl
->Sbz1
= 0;
475 default_dacl
->AclSize
= default_dacl_size
;
476 default_dacl
->AceCount
= 2;
477 default_dacl
->Sbz2
= 0;
479 /* GENERIC_ALL for Local System */
480 aaa
= (ACCESS_ALLOWED_ACE
*)(default_dacl
+ 1);
481 aaa
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
482 aaa
->Header
.AceFlags
= 0;
483 aaa
->Header
.AceSize
= (sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
)) +
484 sizeof(local_system_sid
);
485 aaa
->Mask
= GENERIC_ALL
;
486 sid
= (SID
*)&aaa
->SidStart
;
487 memcpy( sid
, &local_system_sid
, sizeof(local_system_sid
) );
489 /* GENERIC_ALL for specified user */
490 aaa
= (ACCESS_ALLOWED_ACE
*)((const char *)aaa
+ aaa
->Header
.AceSize
);
491 aaa
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
492 aaa
->Header
.AceFlags
= 0;
493 aaa
->Header
.AceSize
= (sizeof(ACCESS_ALLOWED_ACE
) - sizeof(DWORD
)) +
494 FIELD_OFFSET( SID
, SubAuthority
[user
->SubAuthorityCount
] );
495 aaa
->Mask
= GENERIC_ALL
;
496 sid
= (SID
*)&aaa
->SidStart
;
497 memcpy( sid
, user
, FIELD_OFFSET(SID
, SubAuthority
[user
->SubAuthorityCount
]) );
504 SID_IDENTIFIER_AUTHORITY idauth
;
506 unsigned int subauth
[MAX_SUBAUTH_COUNT
];
509 struct token
*token_create_admin( void )
511 struct token
*token
= NULL
;
512 static const SID_IDENTIFIER_AUTHORITY nt_authority
= { SECURITY_NT_AUTHORITY
};
513 static const unsigned int alias_admins_subauth
[] = { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
};
514 static const unsigned int alias_users_subauth
[] = { SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_USERS
};
515 PSID alias_admins_sid
;
516 PSID alias_users_sid
;
517 ACL
*default_dacl
= create_default_dacl( &local_system_sid
);
519 alias_admins_sid
= security_sid_alloc( &nt_authority
, sizeof(alias_admins_subauth
)/sizeof(alias_admins_subauth
[0]),
520 alias_admins_subauth
);
521 alias_users_sid
= security_sid_alloc( &nt_authority
, sizeof(alias_users_subauth
)/sizeof(alias_users_subauth
[0]),
522 alias_users_subauth
);
524 if (alias_admins_sid
&& alias_users_sid
&& default_dacl
)
526 const LUID_AND_ATTRIBUTES admin_privs
[] =
528 { SeChangeNotifyPrivilege
, SE_PRIVILEGE_ENABLED
},
529 { SeSecurityPrivilege
, 0 },
530 { SeBackupPrivilege
, 0 },
531 { SeRestorePrivilege
, 0 },
532 { SeSystemtimePrivilege
, 0 },
533 { SeShutdownPrivilege
, 0 },
534 { SeRemoteShutdownPrivilege
, 0 },
535 { SeTakeOwnershipPrivilege
, 0 },
536 { SeDebugPrivilege
, 0 },
537 { SeSystemEnvironmentPrivilege
, 0 },
538 { SeSystemProfilePrivilege
, 0 },
539 { SeProfileSingleProcessPrivilege
, 0 },
540 { SeIncreaseBasePriorityPrivilege
, 0 },
541 { SeLoadDriverPrivilege
, 0 },
542 { SeCreatePagefilePrivilege
, 0 },
543 { SeIncreaseQuotaPrivilege
, 0 },
544 { SeUndockPrivilege
, 0 },
545 { SeManageVolumePrivilege
, 0 },
546 { SeImpersonatePrivilege
, SE_PRIVILEGE_ENABLED
},
547 { SeCreateGlobalPrivilege
, SE_PRIVILEGE_ENABLED
},
549 /* note: we don't include non-builtin groups here for the user -
550 * telling us these is the job of a client-side program */
551 const SID_AND_ATTRIBUTES admin_groups
[] =
553 { security_world_sid
, SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
},
554 { security_local_sid
, SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
},
555 { security_interactive_sid
, SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
},
556 { security_authenticated_user_sid
, SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
},
557 { alias_admins_sid
, SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
},
558 { alias_users_sid
, SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
},
560 /* note: we just set the user sid to be the local system builtin sid -
561 * telling us what this should be is the job of a client-side program */
562 token
= create_token( TRUE
, &local_system_sid
,
563 admin_groups
, sizeof(admin_groups
)/sizeof(admin_groups
[0]),
564 admin_privs
, sizeof(admin_privs
)/sizeof(admin_privs
[0]),
568 if (alias_admins_sid
)
569 free( alias_admins_sid
);
571 free( alias_users_sid
);
573 free( default_dacl
);
578 static struct privilege
*token_find_privilege( struct token
*token
, const LUID
*luid
, int enabled_only
)
580 struct privilege
*privilege
;
581 LIST_FOR_EACH_ENTRY( privilege
, &token
->privileges
, struct privilege
, entry
)
583 if (is_equal_luid( luid
, &privilege
->luid
))
585 if (enabled_only
&& !privilege
->enabled
)
593 static unsigned int token_adjust_privileges( struct token
*token
, const LUID_AND_ATTRIBUTES
*privs
,
594 unsigned int count
, LUID_AND_ATTRIBUTES
*mod_privs
,
595 unsigned int mod_privs_count
)
598 unsigned int modified_count
= 0;
600 for (i
= 0; i
< count
; i
++)
602 struct privilege
*privilege
=
603 token_find_privilege( token
, &privs
[i
].Luid
, FALSE
);
606 set_error( STATUS_NOT_ALL_ASSIGNED
);
610 if (privs
[i
].Attributes
& SE_PRIVILEGE_REMOVE
)
611 privilege_remove( privilege
);
614 /* save previous state for caller */
617 luid_and_attr_from_privilege(mod_privs
, privilege
);
623 if (privs
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
624 privilege
->enabled
= TRUE
;
626 privilege
->enabled
= FALSE
;
629 return modified_count
;
632 static void token_disable_privileges( struct token
*token
)
634 struct privilege
*privilege
;
635 LIST_FOR_EACH_ENTRY( privilege
, &token
->privileges
, struct privilege
, entry
)
636 privilege
->enabled
= FALSE
;
639 int token_check_privileges( struct token
*token
, int all_required
,
640 const LUID_AND_ATTRIBUTES
*reqprivs
,
641 unsigned int count
, LUID_AND_ATTRIBUTES
*usedprivs
)
644 unsigned int enabled_count
= 0;
646 for (i
= 0; i
< count
; i
++)
648 struct privilege
*privilege
=
649 token_find_privilege( token
, &reqprivs
[i
].Luid
, TRUE
);
652 usedprivs
[i
] = reqprivs
[i
];
654 if (privilege
&& privilege
->enabled
)
658 usedprivs
[i
].Attributes
|= SE_PRIVILEGE_USED_FOR_ACCESS
;
663 return (enabled_count
== count
);
665 return (enabled_count
> 0);
668 static int token_sid_present( struct token
*token
, const SID
*sid
, int deny
)
670 struct sid_and_attributes
*group
;
672 if (security_equal_sid( token
->user
, sid
)) return TRUE
;
674 LIST_FOR_EACH_ENTRY( group
, &token
->groups
, struct sid_and_attributes
, entry
)
676 if (!group
->enabled
) continue;
677 if (group
->deny_only
&& !deny
) continue;
679 if (security_equal_sid( &group
->sid
, sid
)) return TRUE
;
685 /* checks access to a security descriptor. sd must have been validated by caller.
686 * it returns STATUS_SUCCESS if access was granted to the object, or an error
687 * status code if not, giving the reason. errors not relating to giving access
688 * to the object are returned in the status parameter. granted_access and
689 * status always have a valid value stored in them on return. */
690 static unsigned int token_access_check( struct token
*token
,
691 const struct security_descriptor
*sd
,
692 unsigned int desired_access
,
693 LUID_AND_ATTRIBUTES
*privs
,
694 unsigned int *priv_count
,
695 const GENERIC_MAPPING
*mapping
,
696 unsigned int *granted_access
,
697 unsigned int *status
)
699 unsigned int current_access
= 0;
700 unsigned int denied_access
= 0;
704 const ACE_HEADER
*ace
;
707 /* assume success, but no access rights */
708 *status
= STATUS_SUCCESS
;
711 /* fail if desired_access contains generic rights */
712 if (desired_access
& (GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
|GENERIC_ALL
))
715 *status
= STATUS_GENERIC_NOT_MAPPED
;
716 return STATUS_ACCESS_DENIED
;
719 dacl
= sd_get_dacl( sd
, &dacl_present
);
720 owner
= sd_get_owner( sd
);
721 if (!owner
|| !sd_get_group( sd
))
724 *status
= STATUS_INVALID_SECURITY_DESCR
;
725 return STATUS_ACCESS_DENIED
;
728 /* 1: Grant desired access if the object is unprotected */
732 *granted_access
= desired_access
;
733 return STATUS_SUCCESS
;
738 return STATUS_ACCESS_DENIED
;
741 /* 2: Check if caller wants access to system security part. Note: access
742 * is only granted if specifically asked for */
743 if (desired_access
& ACCESS_SYSTEM_SECURITY
)
745 const LUID_AND_ATTRIBUTES security_priv
= { SeSecurityPrivilege
, 0 };
746 LUID_AND_ATTRIBUTES retpriv
= security_priv
;
747 if (token_check_privileges( token
, TRUE
, &security_priv
, 1, &retpriv
))
751 /* assumes that there will only be one privilege to return */
752 if (*priv_count
>= 1)
760 return STATUS_BUFFER_TOO_SMALL
;
763 current_access
|= ACCESS_SYSTEM_SECURITY
;
764 if (desired_access
== current_access
)
766 *granted_access
= current_access
;
767 return STATUS_SUCCESS
;
773 return STATUS_PRIVILEGE_NOT_HELD
;
776 else if (priv_count
) *priv_count
= 0;
778 /* 3: Check whether the token is the owner */
779 /* NOTE: SeTakeOwnershipPrivilege is not checked for here - it is instead
780 * checked when a "set owner" call is made, overriding the access rights
781 * determined here. */
782 if (token_sid_present( token
, owner
, FALSE
))
784 current_access
|= (READ_CONTROL
| WRITE_DAC
);
785 if (desired_access
== current_access
)
787 *granted_access
= current_access
;
788 return STATUS_SUCCESS
;
792 /* 4: Grant rights according to the DACL */
793 ace
= (const ACE_HEADER
*)(dacl
+ 1);
794 for (i
= 0; i
< dacl
->AceCount
; i
++)
796 const ACCESS_ALLOWED_ACE
*aa_ace
;
797 const ACCESS_DENIED_ACE
*ad_ace
;
799 switch (ace
->AceType
)
801 case ACCESS_DENIED_ACE_TYPE
:
802 ad_ace
= (const ACCESS_DENIED_ACE
*)ace
;
803 sid
= (const SID
*)&ad_ace
->SidStart
;
804 if (token_sid_present( token
, sid
, TRUE
))
806 unsigned int access
= ad_ace
->Mask
;
807 map_generic_mask(&access
, mapping
);
808 if (desired_access
& MAXIMUM_ALLOWED
)
809 denied_access
|= access
;
812 denied_access
|= (access
& ~current_access
);
813 if (desired_access
& access
)
816 return STATUS_SUCCESS
;
821 case ACCESS_ALLOWED_ACE_TYPE
:
822 aa_ace
= (const ACCESS_ALLOWED_ACE
*)ace
;
823 sid
= (const SID
*)&aa_ace
->SidStart
;
824 if (token_sid_present( token
, sid
, FALSE
))
826 unsigned int access
= aa_ace
->Mask
;
827 map_generic_mask(&access
, mapping
);
828 if (desired_access
& MAXIMUM_ALLOWED
)
829 current_access
|= access
;
831 current_access
|= (access
& ~denied_access
);
836 /* don't bother carrying on checking if we've already got all of
838 if (desired_access
== *granted_access
)
841 ace
= ace_next( ace
);
844 if (desired_access
& MAXIMUM_ALLOWED
)
846 *granted_access
= current_access
& ~denied_access
;
848 return STATUS_SUCCESS
;
850 return STATUS_ACCESS_DENIED
;
854 if ((current_access
& desired_access
) == desired_access
)
856 *granted_access
= current_access
& desired_access
;
857 return STATUS_SUCCESS
;
860 return STATUS_ACCESS_DENIED
;
864 const ACL
*token_get_default_dacl( struct token
*token
)
866 return token
->default_dacl
;
869 /* open a security token */
870 DECL_HANDLER(open_token
)
872 if (req
->flags
& OPEN_TOKEN_THREAD
)
874 struct thread
*thread
= get_thread_from_handle( req
->handle
, 0 );
878 reply
->token
= alloc_handle( current
->process
, thread
->token
, TOKEN_ALL_ACCESS
, 0);
880 set_error(STATUS_NO_TOKEN
);
881 release_object( thread
);
886 struct process
*process
= get_process_from_handle( req
->handle
, 0 );
890 reply
->token
= alloc_handle( current
->process
, process
->token
, TOKEN_ALL_ACCESS
, 0);
892 set_error(STATUS_NO_TOKEN
);
893 release_object( process
);
898 /* adjust the privileges held by a token */
899 DECL_HANDLER(adjust_token_privileges
)
902 unsigned int access
= TOKEN_ADJUST_PRIVILEGES
;
904 if (req
->get_modified_state
) access
|= TOKEN_QUERY
;
906 if ((token
= (struct token
*)get_handle_obj( current
->process
, req
->handle
,
907 access
, &token_ops
)))
909 const LUID_AND_ATTRIBUTES
*privs
= get_req_data();
910 LUID_AND_ATTRIBUTES
*modified_privs
= NULL
;
911 unsigned int priv_count
= get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES
);
912 unsigned int modified_priv_count
= 0;
914 if (req
->get_modified_state
&& !req
->disable_all
)
917 /* count modified privs */
918 for (i
= 0; i
< priv_count
; i
++)
920 struct privilege
*privilege
=
921 token_find_privilege( token
, &privs
[i
].Luid
, FALSE
);
922 if (privilege
&& req
->get_modified_state
)
923 modified_priv_count
++;
925 reply
->len
= modified_priv_count
;
926 modified_priv_count
= min( modified_priv_count
, get_reply_max_size() / sizeof(*modified_privs
) );
927 if (modified_priv_count
)
928 modified_privs
= set_reply_data_size( modified_priv_count
* sizeof(*modified_privs
) );
930 reply
->len
= modified_priv_count
* sizeof(*modified_privs
);
932 if (req
->disable_all
)
933 token_disable_privileges( token
);
935 modified_priv_count
= token_adjust_privileges( token
, privs
,
936 priv_count
, modified_privs
, modified_priv_count
);
938 release_object( token
);
942 /* retrieves the list of privileges that may be held be the token */
943 DECL_HANDLER(get_token_privileges
)
947 if ((token
= (struct token
*)get_handle_obj( current
->process
, req
->handle
,
952 LUID_AND_ATTRIBUTES
*privs
;
953 struct privilege
*privilege
;
955 LIST_FOR_EACH_ENTRY( privilege
, &token
->privileges
, struct privilege
, entry
)
958 reply
->len
= priv_count
* sizeof(*privs
);
959 if (reply
->len
<= get_reply_max_size())
961 privs
= set_reply_data_size( priv_count
* sizeof(*privs
) );
965 LIST_FOR_EACH_ENTRY( privilege
, &token
->privileges
, struct privilege
, entry
)
967 luid_and_attr_from_privilege( &privs
[i
], privilege
);
973 set_error(STATUS_BUFFER_TOO_SMALL
);
975 release_object( token
);
979 /* creates a duplicate of the token */
980 DECL_HANDLER(duplicate_token
)
982 struct token
*src_token
;
983 if ((src_token
= (struct token
*)get_handle_obj( current
->process
, req
->handle
,
987 /* FIXME: use req->impersonation_level */
988 struct token
*token
= create_token( req
->primary
, src_token
->user
, NULL
, 0, NULL
, 0, src_token
->default_dacl
);
991 struct privilege
*privilege
;
992 struct sid_and_attributes
*group
;
996 LIST_FOR_EACH_ENTRY( group
, &src_token
->groups
, struct sid_and_attributes
, entry
)
998 size_t size
= FIELD_OFFSET( struct sid_and_attributes
, sid
.SubAuthority
[group
->sid
.SubAuthorityCount
] );
999 struct sid_and_attributes
*newgroup
= mem_alloc( size
);
1000 memcpy( newgroup
, group
, size
);
1001 list_add_tail( &token
->groups
, &newgroup
->entry
);
1004 /* copy privileges */
1005 LIST_FOR_EACH_ENTRY( privilege
, &src_token
->privileges
, struct privilege
, entry
)
1006 privilege_add( token
, &privilege
->luid
, privilege
->enabled
);
1008 access
= req
->access
;
1009 if (access
& MAXIMUM_ALLOWED
) access
= TOKEN_ALL_ACCESS
; /* FIXME: needs general solution */
1010 reply
->new_handle
= alloc_handle( current
->process
, token
, access
, req
->inherit
);
1011 release_object( token
);
1013 release_object( src_token
);
1017 /* checks the specified privileges are held by the token */
1018 DECL_HANDLER(check_token_privileges
)
1020 struct token
*token
;
1022 if ((token
= (struct token
*)get_handle_obj( current
->process
, req
->handle
,
1026 unsigned int count
= get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES
);
1027 if (get_reply_max_size() >= count
* sizeof(LUID_AND_ATTRIBUTES
))
1029 LUID_AND_ATTRIBUTES
*usedprivs
= set_reply_data_size( count
* sizeof(*usedprivs
) );
1030 reply
->has_privileges
= token_check_privileges( token
, req
->all_required
, get_req_data(), count
, usedprivs
);
1033 set_error( STATUS_BUFFER_OVERFLOW
);
1034 release_object( token
);
1038 /* checks that a user represented by a token is allowed to access an object
1039 * represented by a security descriptor */
1040 DECL_HANDLER(access_check
)
1042 size_t sd_size
= get_req_data_size();
1043 const struct security_descriptor
*sd
= get_req_data();
1044 struct token
*token
;
1046 if (!sd_is_valid( sd
, sd_size
))
1048 set_error( STATUS_ACCESS_VIOLATION
);
1052 if ((token
= (struct token
*)get_handle_obj( current
->process
, req
->handle
,
1056 GENERIC_MAPPING mapping
;
1057 unsigned int status
;
1058 LUID_AND_ATTRIBUTES priv
;
1059 unsigned int priv_count
= 1;
1061 memset(&priv
, 0, sizeof(priv
));
1063 /* only impersonation tokens may be used with this function */
1066 set_error( STATUS_NO_IMPERSONATION_TOKEN
);
1067 release_object( token
);
1071 mapping
.GenericRead
= req
->mapping_read
;
1072 mapping
.GenericWrite
= req
->mapping_write
;
1073 mapping
.GenericExecute
= req
->mapping_execute
;
1074 mapping
.GenericAll
= req
->mapping_all
;
1076 reply
->access_status
= token_access_check(
1077 token
, sd
, req
->desired_access
, &priv
, &priv_count
, &mapping
,
1078 &reply
->access_granted
, &status
);
1080 reply
->privileges_len
= priv_count
*sizeof(LUID_AND_ATTRIBUTES
);
1082 if ((priv_count
> 0) && (reply
->privileges_len
<= get_reply_max_size()))
1084 LUID_AND_ATTRIBUTES
*privs
= set_reply_data_size( priv_count
* sizeof(*privs
) );
1085 memcpy( privs
, &priv
, sizeof(priv
) );
1088 if (status
!= STATUS_SUCCESS
)
1089 set_error( status
);
1091 release_object( token
);