From 5af809abfd5c13c6a3aec9f72c1651d6fb871da2 Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Tue, 2 Oct 2007 15:54:51 +0100 Subject: [PATCH] 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. --- server/handle.c | 27 +++++++++ server/object.c | 89 ++++++++++++++++++++++++++++++ server/object.h | 1 + server/security.h | 53 ++++++++++++++++++ server/token.c | 160 +++--------------------------------------------------- 5 files changed, 177 insertions(+), 153 deletions(-) diff --git a/server/handle.c b/server/handle.c index 4b35e8b346b..39911fb3e85 100644 --- a/server/handle.c +++ b/server/handle.c @@ -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 ); +} diff --git a/server/object.c b/server/object.c index 7f44b71ed1d..d10b878f062 100644 --- a/server/object.c +++ b/server/object.c @@ -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 ) { diff --git a/server/object.h b/server/object.h index ffb248687ff..c40b633fdbe 100644 --- a/server/object.h +++ b/server/object.h @@ -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 ); diff --git a/server/security.h b/server/security.h index f0c1b8c8aaf..88b437d6c49 100644 --- a/server/security.h +++ b/server/security.h @@ -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; +} diff --git a/server/token.c b/server/token.c index 655e597dd4a..f5a95bc56d5 100644 --- a/server/token.c +++ b/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; - - 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; - } - } + return token->user; +} - 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 ); -} -- 2.11.4.GIT