- Avoid evil signed bitfields.
- Fix bug with using wrong revision in security_sid_alloc. - Add all builtin groups present in the Administrator token on Windows to the default token.
This commit is contained in:
parent
9c01e4274f
commit
9b82644d00
143
server/token.c
143
server/token.c
|
@ -57,6 +57,16 @@ const LUID SeManageVolumePrivilege = { 28, 0 };
|
||||||
const LUID SeImpersonatePrivilege = { 29, 0 };
|
const LUID SeImpersonatePrivilege = { 29, 0 };
|
||||||
const LUID SeCreateGlobalPrivilege = { 30, 0 };
|
const LUID SeCreateGlobalPrivilege = { 30, 0 };
|
||||||
|
|
||||||
|
static const SID world_sid = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } };
|
||||||
|
static const SID local_sid = { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } };
|
||||||
|
static const SID interactive_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } };
|
||||||
|
static const SID authenticated_user_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } };
|
||||||
|
static const SID local_system_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } };
|
||||||
|
static PSID security_world_sid = (PSID)&world_sid;
|
||||||
|
static PSID security_local_sid = (PSID)&local_sid;
|
||||||
|
static PSID security_interactive_sid = (PSID)&interactive_sid;
|
||||||
|
static PSID security_authenticated_user_sid = (PSID)&authenticated_user_sid;
|
||||||
|
|
||||||
struct token
|
struct token
|
||||||
{
|
{
|
||||||
struct object obj; /* object header */
|
struct object obj; /* object header */
|
||||||
|
@ -76,13 +86,13 @@ struct privilege
|
||||||
struct sid_and_attributes
|
struct sid_and_attributes
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
int enabled : 1; /* is the sid currently enabled? */
|
unsigned enabled : 1; /* is the sid currently enabled? */
|
||||||
int def : 1; /* is the sid enabled by default? */
|
unsigned def : 1; /* is the sid enabled by default? */
|
||||||
int logon : 1; /* is this a logon sid? */
|
unsigned logon : 1; /* is this a logon sid? */
|
||||||
int mandatory: 1; /* is this sid always enabled? */
|
unsigned mandatory: 1; /* is this sid always enabled? */
|
||||||
int owner : 1; /* can this sid be an owner of an object? */
|
unsigned owner : 1; /* can this sid be an owner of an object? */
|
||||||
int resource : 1; /* is this a domain-local group? */
|
unsigned resource : 1; /* is this a domain-local group? */
|
||||||
int deny_only: 1; /* is this a sid that should be use for denying only? */
|
unsigned deny_only: 1; /* is this a sid that should be use for denying only? */
|
||||||
SID sid;
|
SID sid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,7 +124,7 @@ static SID *security_sid_alloc( const SID_IDENTIFIER_AUTHORITY *idauthority, int
|
||||||
int i;
|
int i;
|
||||||
SID *sid = mem_alloc( FIELD_OFFSET(SID, SubAuthority[subauthcount]) );
|
SID *sid = mem_alloc( FIELD_OFFSET(SID, SubAuthority[subauthcount]) );
|
||||||
if (!sid) return NULL;
|
if (!sid) return NULL;
|
||||||
sid->Revision = MAX_ACL_REVISION;
|
sid->Revision = SID_REVISION;
|
||||||
sid->SubAuthorityCount = subauthcount;
|
sid->SubAuthorityCount = subauthcount;
|
||||||
sid->IdentifierAuthority = *idauthority;
|
sid->IdentifierAuthority = *idauthority;
|
||||||
for (i = 0; i < subauthcount; i++)
|
for (i = 0; i < subauthcount; i++)
|
||||||
|
@ -342,7 +352,9 @@ static void token_destroy( struct object *obj )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct token *create_token( const SID *user, const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count )
|
static struct token *create_token( const SID *user,
|
||||||
|
const SID_AND_ATTRIBUTES *groups, unsigned int group_count,
|
||||||
|
const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count )
|
||||||
{
|
{
|
||||||
struct token *token = alloc_object( &token_ops );
|
struct token *token = alloc_object( &token_ops );
|
||||||
if (token)
|
if (token)
|
||||||
|
@ -358,7 +370,21 @@ static struct token *create_token( const SID *user, const LUID_AND_ATTRIBUTES *p
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: copy groups */
|
/* copy groups */
|
||||||
|
for (i = 0; i < group_count; i++)
|
||||||
|
{
|
||||||
|
size_t size = FIELD_OFFSET( struct sid_and_attributes, sid.SubAuthority[((const SID *)groups[i].Sid)->SubAuthorityCount] );
|
||||||
|
struct sid_and_attributes *group = mem_alloc( size );
|
||||||
|
memcpy( &group->sid, groups[i].Sid, FIELD_OFFSET( SID, SubAuthority[((const SID *)groups[i].Sid)->SubAuthorityCount] ) );
|
||||||
|
group->enabled = TRUE;
|
||||||
|
group->def = TRUE;
|
||||||
|
group->logon = FALSE;
|
||||||
|
group->mandatory = (groups[i].Attributes & SE_GROUP_MANDATORY) ? TRUE : FALSE;
|
||||||
|
group->owner = FALSE;
|
||||||
|
group->resource = FALSE;
|
||||||
|
group->deny_only = FALSE;
|
||||||
|
list_add_tail( &token->groups, &group->entry );
|
||||||
|
}
|
||||||
|
|
||||||
/* copy privileges */
|
/* copy privileges */
|
||||||
for (i = 0; i < priv_count; i++)
|
for (i = 0; i < priv_count; i++)
|
||||||
|
@ -385,41 +411,66 @@ struct sid_data
|
||||||
|
|
||||||
struct token *token_create_admin( void )
|
struct token *token_create_admin( void )
|
||||||
{
|
{
|
||||||
struct token *token;
|
struct token *token = NULL;
|
||||||
const LUID_AND_ATTRIBUTES admin_privs[] =
|
static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY };
|
||||||
|
static const unsigned int alias_admins_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS };
|
||||||
|
static const unsigned int alias_users_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS };
|
||||||
|
PSID alias_admins_sid;
|
||||||
|
PSID alias_users_sid;
|
||||||
|
|
||||||
|
alias_admins_sid = security_sid_alloc( &nt_authority, sizeof(alias_admins_subauth)/sizeof(alias_admins_subauth[0]),
|
||||||
|
alias_admins_subauth );
|
||||||
|
alias_users_sid = security_sid_alloc( &nt_authority, sizeof(alias_users_subauth)/sizeof(alias_users_subauth[0]),
|
||||||
|
alias_users_subauth );
|
||||||
|
|
||||||
|
if (alias_admins_sid && alias_users_sid)
|
||||||
{
|
{
|
||||||
{ SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED },
|
const LUID_AND_ATTRIBUTES admin_privs[] =
|
||||||
{ SeSecurityPrivilege , 0 },
|
{
|
||||||
{ SeBackupPrivilege , 0 },
|
{ SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED },
|
||||||
{ SeRestorePrivilege , 0 },
|
{ SeSecurityPrivilege , 0 },
|
||||||
{ SeSystemtimePrivilege , 0 },
|
{ SeBackupPrivilege , 0 },
|
||||||
{ SeShutdownPrivilege , 0 },
|
{ SeRestorePrivilege , 0 },
|
||||||
{ SeRemoteShutdownPrivilege , 0 },
|
{ SeSystemtimePrivilege , 0 },
|
||||||
{ SeTakeOwnershipPrivilege , 0 },
|
{ SeShutdownPrivilege , 0 },
|
||||||
{ SeDebugPrivilege , 0 },
|
{ SeRemoteShutdownPrivilege , 0 },
|
||||||
{ SeSystemEnvironmentPrivilege , 0 },
|
{ SeTakeOwnershipPrivilege , 0 },
|
||||||
{ SeSystemProfilePrivilege , 0 },
|
{ SeDebugPrivilege , 0 },
|
||||||
{ SeProfileSingleProcessPrivilege, 0 },
|
{ SeSystemEnvironmentPrivilege , 0 },
|
||||||
{ SeIncreaseBasePriorityPrivilege, 0 },
|
{ SeSystemProfilePrivilege , 0 },
|
||||||
{ SeLoadDriverPrivilege , 0 },
|
{ SeProfileSingleProcessPrivilege, 0 },
|
||||||
{ SeCreatePagefilePrivilege , 0 },
|
{ SeIncreaseBasePriorityPrivilege, 0 },
|
||||||
{ SeIncreaseQuotaPrivilege , 0 },
|
{ SeLoadDriverPrivilege , 0 },
|
||||||
{ SeUndockPrivilege , 0 },
|
{ SeCreatePagefilePrivilege , 0 },
|
||||||
{ SeManageVolumePrivilege , 0 },
|
{ SeIncreaseQuotaPrivilege , 0 },
|
||||||
{ SeImpersonatePrivilege , SE_PRIVILEGE_ENABLED },
|
{ SeUndockPrivilege , 0 },
|
||||||
{ SeCreateGlobalPrivilege , SE_PRIVILEGE_ENABLED },
|
{ SeManageVolumePrivilege , 0 },
|
||||||
};
|
{ SeImpersonatePrivilege , SE_PRIVILEGE_ENABLED },
|
||||||
static const struct sid_data well_known_sid_data[] =
|
{ SeCreateGlobalPrivilege , SE_PRIVILEGE_ENABLED },
|
||||||
{
|
};
|
||||||
{ { SECURITY_NT_AUTHORITY }, 1, { SECURITY_LOCAL_SYSTEM_RID } }, /* LOCAL_SYSTEM */
|
/* note: we don't include non-builtin groups here for the user -
|
||||||
};
|
* telling us these is the job of a client-side program */
|
||||||
SID *local_system_sid = security_sid_alloc(
|
const SID_AND_ATTRIBUTES admin_groups[] =
|
||||||
&well_known_sid_data[0].idauth,
|
{
|
||||||
well_known_sid_data[0].count,
|
{ security_world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
||||||
well_known_sid_data[0].subauth );
|
{ security_local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
||||||
if (!local_system_sid) return NULL;
|
{ security_interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
||||||
token = create_token( local_system_sid, admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]) );
|
{ security_authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
||||||
free( local_system_sid );
|
{ alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
||||||
|
{ alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
||||||
|
};
|
||||||
|
/* note: we just set the user sid to be the local system builtin sid -
|
||||||
|
* telling us what this should be is the job of a client-side program */
|
||||||
|
token = create_token( &local_system_sid,
|
||||||
|
admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]),
|
||||||
|
admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alias_admins_sid)
|
||||||
|
free( alias_admins_sid );
|
||||||
|
if (alias_users_sid)
|
||||||
|
free( alias_users_sid );
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,12 +879,14 @@ DECL_HANDLER(duplicate_token)
|
||||||
&token_ops )))
|
&token_ops )))
|
||||||
{
|
{
|
||||||
/* FIXME: use req->primary and req->impersonation_level */
|
/* FIXME: use req->primary and req->impersonation_level */
|
||||||
struct token *token = create_token( src_token->user, NULL, 0 );
|
struct token *token = create_token( src_token->user, NULL, 0, NULL, 0 );
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
struct privilege *privilege;
|
struct privilege *privilege;
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
|
|
||||||
|
/* FIXME: copy groups */
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
|
LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
|
||||||
privilege_add( token, &privilege->luid, privilege->enabled );
|
privilege_add( token, &privilege->luid, privilege->enabled );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue