server: Move set_security_object to handle.c and set_object_sd to object.c.
These both don't operate on tokens so token.c is not the right place for them to be implemented.
This commit is contained in:
parent
3d3369a77c
commit
5af809abfd
|
@ -588,3 +588,30 @@ DECL_HANDLER(get_object_info)
|
|||
reply->ref_count = obj->refcount;
|
||||
release_object( obj );
|
||||
}
|
||||
|
||||
DECL_HANDLER(set_security_object)
|
||||
{
|
||||
data_size_t sd_size = get_req_data_size();
|
||||
const struct security_descriptor *sd = get_req_data();
|
||||
struct object *obj;
|
||||
unsigned int access = 0;
|
||||
|
||||
if (!sd_is_valid( sd, sd_size ))
|
||||
{
|
||||
set_error( STATUS_ACCESS_VIOLATION );
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->security_info & OWNER_SECURITY_INFORMATION ||
|
||||
req->security_info & GROUP_SECURITY_INFORMATION)
|
||||
access |= WRITE_OWNER;
|
||||
if (req->security_info & SACL_SECURITY_INFORMATION)
|
||||
access |= ACCESS_SYSTEM_SECURITY;
|
||||
if (req->security_info & DACL_SECURITY_INFORMATION)
|
||||
access |= WRITE_DAC;
|
||||
|
||||
if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return;
|
||||
|
||||
set_object_sd( obj, sd, req->security_info );
|
||||
release_object( obj );
|
||||
}
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
#include "winternl.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "process.h"
|
||||
#include "thread.h"
|
||||
#include "unicode.h"
|
||||
#include "security.h"
|
||||
|
||||
|
||||
struct object_name
|
||||
|
@ -365,6 +367,93 @@ unsigned int no_map_access( struct object *obj, unsigned int access )
|
|||
return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
|
||||
}
|
||||
|
||||
void set_object_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
unsigned int set_info )
|
||||
{
|
||||
struct security_descriptor new_sd, *new_sd_ptr;
|
||||
int present;
|
||||
const SID *owner, *group;
|
||||
const ACL *sacl, *dacl;
|
||||
char *ptr;
|
||||
|
||||
if (!set_info) return;
|
||||
|
||||
new_sd.control = sd->control & ~SE_SELF_RELATIVE;
|
||||
|
||||
owner = sd_get_owner( sd );
|
||||
if (set_info & OWNER_SECURITY_INFORMATION && owner)
|
||||
new_sd.owner_len = sd->owner_len;
|
||||
else
|
||||
{
|
||||
owner = token_get_user( current->process->token );
|
||||
new_sd.owner_len = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
|
||||
new_sd.control |= SE_OWNER_DEFAULTED;
|
||||
}
|
||||
|
||||
group = sd_get_group( sd );
|
||||
if (set_info & GROUP_SECURITY_INFORMATION && group)
|
||||
new_sd.group_len = sd->group_len;
|
||||
else
|
||||
{
|
||||
group = token_get_primary_group( current->process->token );
|
||||
new_sd.group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
|
||||
new_sd.control |= SE_GROUP_DEFAULTED;
|
||||
}
|
||||
|
||||
new_sd.control |= SE_SACL_PRESENT;
|
||||
sacl = sd_get_sacl( sd, &present );
|
||||
if (set_info & SACL_SECURITY_INFORMATION && present)
|
||||
new_sd.sacl_len = sd->sacl_len;
|
||||
else
|
||||
{
|
||||
if (obj->sd) sacl = sd_get_sacl( obj->sd, &present );
|
||||
|
||||
if (obj->sd && present)
|
||||
new_sd.sacl_len = obj->sd->sacl_len;
|
||||
else
|
||||
{
|
||||
new_sd.sacl_len = 0;
|
||||
new_sd.control |= SE_SACL_DEFAULTED;
|
||||
}
|
||||
}
|
||||
|
||||
new_sd.control |= SE_DACL_PRESENT;
|
||||
dacl = sd_get_dacl( sd, &present );
|
||||
if (set_info & DACL_SECURITY_INFORMATION && present)
|
||||
new_sd.dacl_len = sd->dacl_len;
|
||||
else
|
||||
{
|
||||
if (obj->sd) dacl = sd_get_dacl( obj->sd, &present );
|
||||
|
||||
if (obj->sd && present)
|
||||
new_sd.dacl_len = obj->sd->dacl_len;
|
||||
else
|
||||
{
|
||||
dacl = token_get_default_dacl( current->process->token );
|
||||
new_sd.dacl_len = dacl->AclSize;
|
||||
new_sd.control |= SE_DACL_DEFAULTED;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len +
|
||||
new_sd.sacl_len + new_sd.dacl_len );
|
||||
if (!ptr) return;
|
||||
new_sd_ptr = (struct security_descriptor*)ptr;
|
||||
|
||||
memcpy( ptr, &new_sd, sizeof(new_sd) );
|
||||
ptr += sizeof(new_sd);
|
||||
memcpy( ptr, owner, new_sd.owner_len );
|
||||
ptr += new_sd.owner_len;
|
||||
memcpy( ptr, group, new_sd.group_len );
|
||||
ptr += new_sd.group_len;
|
||||
memcpy( ptr, sacl, new_sd.sacl_len );
|
||||
ptr += new_sd.sacl_len;
|
||||
memcpy( ptr, dacl, new_sd.dacl_len );
|
||||
|
||||
free( obj->sd );
|
||||
obj->sd = new_sd_ptr;
|
||||
}
|
||||
|
||||
struct object *no_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
{
|
||||
|
|
|
@ -127,6 +127,7 @@ extern int no_satisfied( struct object *obj, struct thread *thread );
|
|||
extern int no_signal( struct object *obj, unsigned int access );
|
||||
extern struct fd *no_get_fd( struct object *obj );
|
||||
extern unsigned int no_map_access( struct object *obj, unsigned int access );
|
||||
extern void set_object_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
||||
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes );
|
||||
extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing,
|
||||
unsigned int options );
|
||||
|
|
|
@ -41,6 +41,9 @@ extern const LUID SeCreateGlobalPrivilege;
|
|||
|
||||
extern const PSID security_interactive_sid;
|
||||
|
||||
|
||||
/* token functions */
|
||||
|
||||
extern struct token *token_create_admin(void);
|
||||
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
|
||||
SECURITY_IMPERSONATION_LEVEL impersonation_level );
|
||||
|
@ -48,6 +51,9 @@ extern int token_check_privileges( struct token *token, int all_required,
|
|||
const LUID_AND_ATTRIBUTES *reqprivs,
|
||||
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
|
||||
extern const ACL *token_get_default_dacl( struct token *token );
|
||||
extern const SID *token_get_user( struct token *token );
|
||||
extern const SID *token_get_primary_group( struct token *token );
|
||||
|
||||
extern void security_set_thread_token( struct thread *thread, obj_handle_t handle );
|
||||
extern int check_object_access( struct object *obj, unsigned int *access );
|
||||
|
||||
|
@ -60,3 +66,50 @@ static inline int thread_single_check_privilege( struct thread *thread, const LU
|
|||
|
||||
return token_check_privileges( token, TRUE, &privs, 1, NULL );
|
||||
}
|
||||
|
||||
|
||||
/* security descriptor helper functions */
|
||||
|
||||
extern int sd_is_valid( const struct security_descriptor *sd, data_size_t size );
|
||||
|
||||
/* gets the discretionary access control list from a security descriptor */
|
||||
static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present )
|
||||
{
|
||||
*present = (sd->control & SE_DACL_PRESENT ? TRUE : FALSE);
|
||||
|
||||
if (sd->dacl_len)
|
||||
return (const ACL *)((const char *)(sd + 1) +
|
||||
sd->owner_len + sd->group_len + sd->sacl_len);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets the system access control list from a security descriptor */
|
||||
static inline const ACL *sd_get_sacl( const struct security_descriptor *sd, int *present )
|
||||
{
|
||||
*present = (sd->control & SE_SACL_PRESENT ? TRUE : FALSE);
|
||||
|
||||
if (sd->sacl_len)
|
||||
return (const ACL *)((const char *)(sd + 1) +
|
||||
sd->owner_len + sd->group_len);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets the owner from a security descriptor */
|
||||
static inline const SID *sd_get_owner( const struct security_descriptor *sd )
|
||||
{
|
||||
if (sd->owner_len)
|
||||
return (const SID *)(sd + 1);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets the primary group from a security descriptor */
|
||||
static inline const SID *sd_get_group( const struct security_descriptor *sd )
|
||||
{
|
||||
if (sd->group_len)
|
||||
return (const SID *)((const char *)(sd + 1) + sd->owner_len);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
|
160
server/token.c
160
server/token.c
|
@ -248,51 +248,9 @@ static int acl_is_valid( const ACL *acl, data_size_t size )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* gets the discretionary access control list from a security descriptor */
|
||||
static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present )
|
||||
{
|
||||
*present = (sd->control & SE_DACL_PRESENT ? TRUE : FALSE);
|
||||
|
||||
if (sd->dacl_len)
|
||||
return (const ACL *)((const char *)(sd + 1) +
|
||||
sd->owner_len + sd->group_len + sd->sacl_len);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets the system access control list from a security descriptor */
|
||||
static inline const ACL *sd_get_sacl( const struct security_descriptor *sd, int *present )
|
||||
{
|
||||
*present = (sd->control & SE_SACL_PRESENT ? TRUE : FALSE);
|
||||
|
||||
if (sd->sacl_len)
|
||||
return (const ACL *)((const char *)(sd + 1) +
|
||||
sd->owner_len + sd->group_len);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets the owner from a security descriptor */
|
||||
static inline const SID *sd_get_owner( const struct security_descriptor *sd )
|
||||
{
|
||||
if (sd->owner_len)
|
||||
return (const SID *)(sd + 1);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* gets the primary group from a security descriptor */
|
||||
static inline const SID *sd_get_group( const struct security_descriptor *sd )
|
||||
{
|
||||
if (sd->group_len)
|
||||
return (const SID *)((const char *)(sd + 1) + sd->owner_len);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* checks whether all members of a security descriptor fit inside the size
|
||||
* of memory specified */
|
||||
static int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
|
||||
int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
|
||||
{
|
||||
size_t offset = sizeof(struct security_descriptor);
|
||||
const SID *group;
|
||||
|
@ -984,91 +942,14 @@ const ACL *token_get_default_dacl( struct token *token )
|
|||
return token->default_dacl;
|
||||
}
|
||||
|
||||
static void set_object_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
unsigned int set_info )
|
||||
const SID *token_get_user( struct token *token )
|
||||
{
|
||||
struct security_descriptor new_sd, *pnew_sd;
|
||||
int present;
|
||||
const SID *owner, *group;
|
||||
const ACL *sacl, *dacl;
|
||||
char *ptr;
|
||||
return token->user;
|
||||
}
|
||||
|
||||
if (!set_info) return;
|
||||
|
||||
new_sd.control = sd->control & ~SE_SELF_RELATIVE;
|
||||
|
||||
owner = sd_get_owner( sd );
|
||||
if (set_info & OWNER_SECURITY_INFORMATION && owner)
|
||||
new_sd.owner_len = sd->owner_len;
|
||||
else
|
||||
{
|
||||
owner = current->process->token->user;
|
||||
new_sd.owner_len = FIELD_OFFSET(SID, SubAuthority[owner->SubAuthorityCount]);
|
||||
new_sd.control |= SE_OWNER_DEFAULTED;
|
||||
}
|
||||
|
||||
group = sd_get_group( sd );
|
||||
if (set_info & GROUP_SECURITY_INFORMATION && group)
|
||||
new_sd.group_len = sd->group_len;
|
||||
else
|
||||
{
|
||||
group = current->process->token->primary_group;
|
||||
new_sd.group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
|
||||
new_sd.control |= SE_GROUP_DEFAULTED;
|
||||
}
|
||||
|
||||
new_sd.control |= SE_SACL_PRESENT;
|
||||
sacl = sd_get_sacl( sd, &present );
|
||||
if (set_info & SACL_SECURITY_INFORMATION && present)
|
||||
new_sd.sacl_len = sd->sacl_len;
|
||||
else
|
||||
{
|
||||
if (obj->sd) sacl = sd_get_sacl( obj->sd, &present );
|
||||
|
||||
if (obj->sd && present)
|
||||
new_sd.sacl_len = obj->sd->sacl_len;
|
||||
else
|
||||
{
|
||||
new_sd.sacl_len = 0;
|
||||
new_sd.control |= SE_SACL_DEFAULTED;
|
||||
}
|
||||
}
|
||||
|
||||
new_sd.control |= SE_DACL_PRESENT;
|
||||
dacl = sd_get_dacl( sd, &present );
|
||||
if (set_info & DACL_SECURITY_INFORMATION && present)
|
||||
new_sd.dacl_len = sd->dacl_len;
|
||||
else
|
||||
{
|
||||
if (obj->sd) dacl = sd_get_dacl( obj->sd, &present );
|
||||
|
||||
if (obj->sd && present)
|
||||
new_sd.dacl_len = obj->sd->dacl_len;
|
||||
else
|
||||
{
|
||||
dacl = token_get_default_dacl( current->process->token );
|
||||
new_sd.dacl_len = dacl->AclSize;
|
||||
new_sd.control |= SE_DACL_DEFAULTED;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len +
|
||||
new_sd.sacl_len + new_sd.dacl_len );
|
||||
if (!ptr) return;
|
||||
pnew_sd = (struct security_descriptor*)ptr;
|
||||
|
||||
memcpy( ptr, &new_sd, sizeof(new_sd) );
|
||||
ptr += sizeof(new_sd);
|
||||
memcpy( ptr, owner, new_sd.owner_len );
|
||||
ptr += new_sd.owner_len;
|
||||
memcpy( ptr, group, new_sd.group_len );
|
||||
ptr += new_sd.group_len;
|
||||
memcpy( ptr, sacl, new_sd.sacl_len );
|
||||
ptr += new_sd.sacl_len;
|
||||
memcpy( ptr, dacl, new_sd.dacl_len );
|
||||
|
||||
free( obj->sd );
|
||||
obj->sd = pnew_sd;
|
||||
const SID *token_get_primary_group( struct token *token )
|
||||
{
|
||||
return token->primary_group;
|
||||
}
|
||||
|
||||
int check_object_access(struct object *obj, unsigned int *access)
|
||||
|
@ -1442,30 +1323,3 @@ DECL_HANDLER(get_token_statistics)
|
|||
release_object( token );
|
||||
}
|
||||
}
|
||||
|
||||
DECL_HANDLER(set_security_object)
|
||||
{
|
||||
data_size_t sd_size = get_req_data_size();
|
||||
const struct security_descriptor *sd = get_req_data();
|
||||
struct object *obj;
|
||||
unsigned int access = 0;
|
||||
|
||||
if (!sd_is_valid( sd, sd_size ))
|
||||
{
|
||||
set_error( STATUS_ACCESS_VIOLATION );
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->security_info & OWNER_SECURITY_INFORMATION ||
|
||||
req->security_info & GROUP_SECURITY_INFORMATION)
|
||||
access |= WRITE_OWNER;
|
||||
if (req->security_info & SACL_SECURITY_INFORMATION)
|
||||
access |= ACCESS_SYSTEM_SECURITY;
|
||||
if (req->security_info & DACL_SECURITY_INFORMATION)
|
||||
access |= WRITE_DAC;
|
||||
|
||||
if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return;
|
||||
|
||||
set_object_sd( obj, sd, req->security_info );
|
||||
release_object( obj );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue