diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 00471154d9a..2f1d6f6f25e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -385,6 +385,14 @@ struct acl unsigned short pad2; }; +struct sid +{ + unsigned char revision; + unsigned char sub_count; + unsigned char id_auth[6]; + unsigned int sub_auth[15]; +}; + typedef struct { unsigned int read; @@ -4411,7 +4419,7 @@ struct filter_token_request unsigned int flags; data_size_t privileges_size; /* VARARG(privileges,luid_attr,privileges_size); */ - /* VARARG(disable_sids,SID); */ + /* VARARG(disable_sids,sid); */ }; struct filter_token_reply { @@ -4450,7 +4458,7 @@ struct get_token_sid_reply { struct reply_header __header; data_size_t sid_len; - /* VARARG(sid,SID); */ + /* VARARG(sid,sid); */ char __pad_12[4]; }; @@ -6261,7 +6269,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 741 +#define SERVER_PROTOCOL_VERSION 742 /* ### protocol_version end ### */ diff --git a/server/change.c b/server/change.c index a01d6894151..6477b457f74 100644 --- a/server/change.c +++ b/server/change.c @@ -364,7 +364,7 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ) { struct dir *dir = (struct dir *)obj; - const SID *owner; + const struct sid *owner; struct stat st; mode_t mode; int unix_fd; @@ -383,7 +383,7 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd, set_error( STATUS_INVALID_SECURITY_DESCR ); return 0; } - if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) )) + if (!obj->sd || !equal_sid( owner, sd_get_owner( obj->sd ) )) { /* FIXME: get Unix uid and call fchown */ } diff --git a/server/file.c b/server/file.c index f2f4f87b48b..eb2dc5696ed 100644 --- a/server/file.c +++ b/server/file.c @@ -243,7 +243,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si if (sd) { - const SID *owner = sd_get_owner( sd ); + const struct sid *owner = sd_get_owner( sd ); if (!owner) owner = token_get_user( current->process->token ); mode = sd_to_mode( sd, owner ); @@ -306,7 +306,7 @@ static struct fd *file_get_fd( struct object *obj ) return (struct fd *)grab_object( file->fd ); } -struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ) +struct security_descriptor *mode_to_sd( mode_t mode, const struct sid *user, const struct sid *group ) { struct security_descriptor *sd; unsigned char flags; @@ -314,25 +314,21 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID struct ace *ace; struct acl *dacl; char *ptr; - const SID *world_sid = security_world_sid; - const SID *local_system_sid = security_local_system_sid; - dacl_size = sizeof(*dacl) + sizeof(*ace) + security_sid_len( local_system_sid ); - if (mode & S_IRWXU) dacl_size += sizeof(*ace) + security_sid_len( user ); + dacl_size = sizeof(*dacl) + sizeof(*ace) + sid_len( &local_system_sid ); + if (mode & S_IRWXU) dacl_size += sizeof(*ace) + sid_len( user ); if ((!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) || (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) || (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))) - dacl_size += sizeof(*ace) + security_sid_len( user ); - if (mode & S_IRWXO) dacl_size += sizeof(*ace) + security_sid_len( world_sid ); + dacl_size += sizeof(*ace) + sid_len( user ); + if (mode & S_IRWXO) dacl_size += sizeof(*ace) + sid_len( &world_sid ); - sd = mem_alloc( sizeof(struct security_descriptor) + - security_sid_len( user ) + security_sid_len( group ) + - dacl_size ); + sd = mem_alloc( sizeof(*sd) + sid_len( user ) + sid_len( group ) + dacl_size ); if (!sd) return sd; sd->control = SE_DACL_PRESENT; - sd->owner_len = security_sid_len( user ); - sd->group_len = security_sid_len( group ); + sd->owner_len = sid_len( user ); + sd->group_len = sid_len( group ); sd->sacl_len = 0; sd->dacl_len = dacl_size; @@ -358,7 +354,7 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID flags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0; /* always give FILE_ALL_ACCESS for Local System */ - ace = set_ace( (struct ace *)(dacl + 1), local_system_sid, + ace = set_ace( (struct ace *)(dacl + 1), &local_system_sid, ACCESS_ALLOWED_ACE_TYPE, flags, FILE_ALL_ACCESS ); if (mode & S_IRWXU) @@ -383,7 +379,7 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID if (mode & S_IRWXO) { /* appropriate access rights for Everyone */ - ace = set_ace( ace_next( ace ), world_sid, ACCESS_ALLOWED_ACE_TYPE, flags, 0 ); + ace = set_ace( ace_next( ace ), &world_sid, ACCESS_ALLOWED_ACE_TYPE, flags, 0 ); if (mode & S_IROTH) ace->mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE; if (mode & S_IWOTH) ace->mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD; } @@ -433,7 +429,7 @@ static mode_t file_access_to_mode( unsigned int access ) return mode; } -mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) +mode_t sd_to_mode( const struct security_descriptor *sd, const struct sid *owner ) { mode_t new_mode = 0; mode_t bits_to_set = ~0; @@ -448,7 +444,7 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) for (i = 0; i < dacl->count; i++, ace = ace_next( ace )) { - const SID *sid = (const SID *)(ace + 1); + const struct sid *sid = (const struct sid *)(ace + 1); if (ace->flags & INHERIT_ONLY_ACE) continue; @@ -456,7 +452,7 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) switch (ace->type) { case ACCESS_DENIED_ACE_TYPE: - if (security_equal_sid( sid, security_world_sid )) + if (equal_sid( sid, &world_sid )) { bits_to_set &= ~((mode << 6) | (mode << 3) | mode); /* all */ } @@ -465,13 +461,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) { bits_to_set &= ~((mode << 6) | (mode << 3)); /* user + group */ } - else if (security_equal_sid( sid, owner )) + else if (equal_sid( sid, owner )) { bits_to_set &= ~(mode << 6); /* user only */ } break; case ACCESS_ALLOWED_ACE_TYPE: - if (security_equal_sid( sid, security_world_sid )) + if (equal_sid( sid, &world_sid )) { mode = (mode << 6) | (mode << 3) | mode; /* all */ new_mode |= mode & bits_to_set; @@ -484,7 +480,7 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) new_mode |= mode & bits_to_set; bits_to_set &= ~mode; } - else if (security_equal_sid( sid, owner )) + else if (equal_sid( sid, owner )) { mode = (mode << 6); /* user only */ new_mode |= mode & bits_to_set; @@ -505,7 +501,7 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd unsigned int set_info ) { struct file *file = (struct file *)obj; - const SID *owner; + const struct sid *owner; struct stat st; mode_t mode; int unix_fd; @@ -524,7 +520,7 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd set_error( STATUS_INVALID_SECURITY_DESCR ); return 0; } - if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) )) + if (!obj->sd || !equal_sid( owner, sd_get_owner( obj->sd ) )) { /* FIXME: get Unix uid and call fchown */ } diff --git a/server/file.h b/server/file.h index 1d830cd3d6f..9f9d4cd4e1a 100644 --- a/server/file.h +++ b/server/file.h @@ -164,8 +164,8 @@ extern int get_file_unix_fd( struct file *file ); extern struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing ); extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigned int sharing ); extern void file_set_error(void); -extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); -extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ); +extern struct security_descriptor *mode_to_sd( mode_t mode, const struct sid *user, const struct sid *group ); +extern mode_t sd_to_mode( const struct security_descriptor *sd, const struct sid *owner ); extern int is_file_executable( const char *name ); /* file mapping functions */ diff --git a/server/handle.c b/server/handle.c index c62dd6068a4..38ad80da267 100644 --- a/server/handle.c +++ b/server/handle.c @@ -737,7 +737,7 @@ DECL_HANDLER(get_security_object) unsigned int access = READ_CONTROL; struct security_descriptor req_sd; int present; - const SID *owner, *group; + const struct sid *owner, *group; const struct acl *sacl, *dacl; struct acl *label_acl = NULL; diff --git a/server/object.c b/server/object.c index 7b57a38aa84..907bc087444 100644 --- a/server/object.c +++ b/server/object.c @@ -543,7 +543,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri { struct security_descriptor new_sd, *new_sd_ptr; int present; - const SID *owner = NULL, *group = NULL; + const struct sid *owner = NULL, *group = NULL; const struct acl *sacl, *dacl; struct acl *replaced_sacl = NULL; char *ptr; @@ -565,7 +565,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri else if (token) { owner = token_get_user( token ); - new_sd.owner_len = security_sid_len( owner ); + new_sd.owner_len = sid_len( owner ); } else new_sd.owner_len = 0; @@ -582,7 +582,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri else if (token) { group = token_get_primary_group( token ); - new_sd.group_len = security_sid_len( group ); + new_sd.group_len = sid_len( group ); } else new_sd.group_len = 0; diff --git a/server/process.c b/server/process.c index 8aea9deaa0e..65e2aa70de2 100644 --- a/server/process.c +++ b/server/process.c @@ -735,7 +735,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla /* Assign a high security label to the token. The default would be medium * but Wine provides admin access to all applications right now so high * makes more sense for the time being. */ - if (!token_assign_label( process->token, security_high_label_sid )) + if (!token_assign_label( process->token, &high_label_sid )) goto error; set_fd_events( process->msg_fd, POLLIN ); /* start listening to events */ @@ -825,8 +825,9 @@ static struct security_descriptor *process_get_sd( struct object *obj ) { struct ace *ace; struct acl *dacl; - size_t users_sid_len = security_sid_len( security_domain_users_sid ); - size_t admins_sid_len = security_sid_len( security_builtin_admins_sid ); + struct sid *sid; + size_t users_sid_len = sid_len( &domain_users_sid ); + size_t admins_sid_len = sid_len( &builtin_admins_sid ); size_t dacl_len = sizeof(*dacl) + 2 * sizeof(*ace) + users_sid_len + admins_sid_len; process_default_sd = mem_alloc( sizeof(*process_default_sd) + admins_sid_len + users_sid_len @@ -836,8 +837,9 @@ static struct security_descriptor *process_get_sd( struct object *obj ) process_default_sd->group_len = users_sid_len; process_default_sd->sacl_len = 0; process_default_sd->dacl_len = dacl_len; - memcpy( process_default_sd + 1, security_builtin_admins_sid, admins_sid_len ); - memcpy( (char *)(process_default_sd + 1) + admins_sid_len, security_domain_users_sid, users_sid_len ); + sid = (struct sid *)(process_default_sd + 1); + sid = copy_sid( sid, &builtin_admins_sid ); + sid = copy_sid( sid, &domain_users_sid ); dacl = (struct acl *)((char *)(process_default_sd + 1) + admins_sid_len + users_sid_len); dacl->revision = ACL_REVISION; @@ -845,9 +847,9 @@ static struct security_descriptor *process_get_sd( struct object *obj ) dacl->size = dacl_len; dacl->count = 2; dacl->pad2 = 0; - ace = set_ace( ace_first( dacl ), security_domain_users_sid, ACCESS_ALLOWED_ACE_TYPE, + ace = set_ace( ace_first( dacl ), &domain_users_sid, ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, GENERIC_READ ); - set_ace( ace_next( ace ), security_builtin_admins_sid, ACCESS_ALLOWED_ACE_TYPE, 0, PROCESS_ALL_ACCESS ); + set_ace( ace_next( ace ), &builtin_admins_sid, ACCESS_ALLOWED_ACE_TYPE, 0, PROCESS_ALL_ACCESS ); } return process_default_sd; } diff --git a/server/protocol.def b/server/protocol.def index 8082efcb602..abd93a70768 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -401,6 +401,14 @@ struct acl unsigned short pad2; }; +struct sid +{ + unsigned char revision; + unsigned char sub_count; + unsigned char id_auth[6]; + unsigned int sub_auth[15]; +}; + typedef struct { unsigned int read; @@ -418,8 +426,8 @@ struct security_descriptor data_size_t group_len; data_size_t sacl_len; data_size_t dacl_len; - /* VARARG(owner,SID); */ - /* VARARG(group,SID); */ + /* VARARG(owner,sid); */ + /* VARARG(group,sid); */ /* VARARG(sacl,acl); */ /* VARARG(dacl,acl); */ }; @@ -451,7 +459,7 @@ struct token_groups { unsigned int count; /* unsigned int attributes[count]; */ - /* VARARG(sids,SID); */ + /* VARARG(sids,sid); */ }; enum select_op @@ -3138,7 +3146,7 @@ enum caret_state unsigned int flags; /* flags */ data_size_t privileges_size; /* size of privileges */ VARARG(privileges,luid_attr,privileges_size); /* privileges to remove from new token */ - VARARG(disable_sids,SID); /* array of groups to remove from new token */ + VARARG(disable_sids,sid); /* array of groups to remove from new token */ @REPLY obj_handle_t new_handle; /* filtered handle */ @END @@ -3160,7 +3168,7 @@ enum caret_state unsigned int which_sid; /* which SID to retrieve from the token */ @REPLY data_size_t sid_len; /* length needed to store sid */ - VARARG(sid,SID); /* the sid specified by which_sid from the token */ + VARARG(sid,sid); /* the sid specified by which_sid from the token */ @END @REQ(get_token_groups) diff --git a/server/registry.c b/server/registry.c index 8187c12d5ce..93e8a309593 100644 --- a/server/registry.c +++ b/server/registry.c @@ -371,8 +371,9 @@ static struct security_descriptor *key_get_sd( struct object *obj ) { struct acl *dacl; struct ace *ace; - size_t users_sid_len = security_sid_len( security_builtin_users_sid ); - size_t admins_sid_len = security_sid_len( security_builtin_admins_sid ); + struct sid *sid; + size_t users_sid_len = sid_len( &builtin_users_sid ); + size_t admins_sid_len = sid_len( &builtin_admins_sid ); size_t dacl_len = sizeof(*dacl) + 2 * sizeof(*ace) + users_sid_len + admins_sid_len; key_default_sd = mem_alloc( sizeof(*key_default_sd) + 2 * admins_sid_len + dacl_len ); @@ -381,8 +382,9 @@ static struct security_descriptor *key_get_sd( struct object *obj ) key_default_sd->group_len = admins_sid_len; key_default_sd->sacl_len = 0; key_default_sd->dacl_len = dacl_len; - memcpy( key_default_sd + 1, security_builtin_admins_sid, admins_sid_len ); - memcpy( (char *)(key_default_sd + 1) + admins_sid_len, security_builtin_admins_sid, admins_sid_len ); + sid = (struct sid *)(key_default_sd + 1); + sid = copy_sid( sid, &builtin_admins_sid ); + sid = copy_sid( sid, &builtin_admins_sid ); dacl = (struct acl *)((char *)(key_default_sd + 1) + 2 * admins_sid_len); dacl->revision = ACL_REVISION; @@ -390,9 +392,9 @@ static struct security_descriptor *key_get_sd( struct object *obj ) dacl->size = dacl_len; dacl->count = 2; dacl->pad2 = 0; - ace = set_ace( ace_first( dacl ), security_builtin_users_sid, ACCESS_ALLOWED_ACE_TYPE, + ace = set_ace( ace_first( dacl ), &builtin_users_sid, ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, GENERIC_READ ); - set_ace( ace_next( ace ), security_builtin_admins_sid, ACCESS_ALLOWED_ACE_TYPE, 0, KEY_ALL_ACCESS ); + set_ace( ace_next( ace ), &builtin_admins_sid, ACCESS_ALLOWED_ACE_TYPE, 0, KEY_ALL_ACCESS ); } return key_default_sd; } @@ -1791,17 +1793,17 @@ static int load_init_registry_from_file( const char *filename, struct key *key ) return (f != NULL); } -static WCHAR *format_user_registry_path( const SID *sid, struct unicode_str *path ) +static WCHAR *format_user_registry_path( const struct sid *sid, struct unicode_str *path ) { - char buffer[7 + 11 + 11 + 11 * SID_MAX_SUB_AUTHORITIES], *p = buffer; + char buffer[7 + 11 + 11 + 11 * ARRAY_SIZE(sid->sub_auth)], *p = buffer; unsigned int i; - p += sprintf( p, "User\\S-%u-%u", sid->Revision, - MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5], - sid->IdentifierAuthority.Value[4] ), - MAKEWORD( sid->IdentifierAuthority.Value[3], - sid->IdentifierAuthority.Value[2] ))); - for (i = 0; i < sid->SubAuthorityCount; i++) p += sprintf( p, "-%u", sid->SubAuthority[i] ); + p += sprintf( p, "User\\S-%u-%u", sid->revision, + ((unsigned int)sid->id_auth[2] << 24) | + ((unsigned int)sid->id_auth[3] << 16) | + ((unsigned int)sid->id_auth[4] << 8) | + ((unsigned int)sid->id_auth[5]) ); + for (i = 0; i < sid->sub_count; i++) p += sprintf( p, "-%u", sid->sub_auth[i] ); return ascii_to_unicode_str( buffer, path ); } @@ -1900,7 +1902,7 @@ void init_registry(void) /* load user.reg into HKEY_CURRENT_USER */ /* FIXME: match default user in token.c. should get from process token instead */ - current_user_path = format_user_registry_path( security_local_user_sid, ¤t_user_str ); + current_user_path = format_user_registry_path( &local_user_sid, ¤t_user_str ); if (!current_user_path || !(hkcu = create_key_recursive( root_key, ¤t_user_str, current_time ))) fatal_error( "could not create HKEY_CURRENT_USER registry key\n" ); diff --git a/server/security.h b/server/security.h index 5fd9cd3269b..fa91b81b77c 100644 --- a/server/security.h +++ b/server/security.h @@ -44,13 +44,13 @@ extern const struct luid SeManageVolumePrivilege; extern const struct luid SeImpersonatePrivilege; extern const struct luid SeCreateGlobalPrivilege; -extern const PSID security_world_sid; -extern const PSID security_local_user_sid; -extern const PSID security_local_system_sid; -extern const PSID security_builtin_users_sid; -extern const PSID security_builtin_admins_sid; -extern const PSID security_domain_users_sid; -extern const PSID security_high_label_sid; +extern const struct sid world_sid; +extern const struct sid local_user_sid; +extern const struct sid local_system_sid; +extern const struct sid builtin_users_sid; +extern const struct sid builtin_admins_sid; +extern const struct sid domain_users_sid; +extern const struct sid high_label_sid; struct ace { @@ -64,19 +64,19 @@ struct ace extern struct token *get_token_obj( struct process *process, obj_handle_t handle, unsigned int access ); extern struct token *token_create_admin( unsigned primary, int impersonation_level, int elevation, unsigned int session_id ); -extern int token_assign_label( struct token *token, PSID label ); +extern int token_assign_label( struct token *token, const struct sid *label ); extern struct token *token_duplicate( struct token *src_token, unsigned primary, int impersonation_level, const struct security_descriptor *sd, const struct luid_attr *remove_privs, unsigned int remove_priv_count, - const SID *remove_groups, unsigned int remove_group_count ); + const struct sid *remove_groups, unsigned int remove_group_count ); extern int token_check_privileges( struct token *token, int all_required, const struct luid_attr *reqprivs, unsigned int count, struct luid_attr *usedprivs ); extern const struct 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 const struct sid *token_get_user( struct token *token ); +extern const struct sid *token_get_primary_group( struct token *token ); extern unsigned int token_get_session_id( struct token *token ); -extern int token_sid_present( struct token *token, const SID *sid, int deny); +extern int token_sid_present( struct token *token, const struct sid *sid, int deny ); static inline struct ace *ace_first( const struct acl *acl ) { @@ -88,35 +88,40 @@ static inline struct ace *ace_next( const struct ace *ace ) return (struct ace *)((char *)ace + ace->size); } -static inline size_t security_sid_len( const SID *sid ) +static inline size_t sid_len( const struct sid *sid ) { - return offsetof( SID, SubAuthority[sid->SubAuthorityCount] ); + return offsetof( struct sid, sub_auth[sid->sub_count] ); } -static inline int security_equal_sid( const SID *sid1, const SID *sid2 ) +static inline int equal_sid( const struct sid *sid1, const struct sid *sid2 ) { - return ((sid1->SubAuthorityCount == sid2->SubAuthorityCount) && - !memcmp( sid1, sid2, security_sid_len( sid1 ))); + return ((sid1->sub_count == sid2->sub_count) && !memcmp( sid1, sid2, sid_len( sid1 ))); } -static inline int sid_valid_size( const SID *sid, data_size_t size ) +static inline void *copy_sid( struct sid *dst, const struct sid *src ) { - return (size >= offsetof( SID, SubAuthority[0] ) && size >= security_sid_len( sid )); + memcpy( dst, src, sid_len( src )); + return (char *)dst + sid_len( src ); } -static inline struct ace *set_ace( struct ace *ace, const SID *sid, unsigned char type, +static inline int sid_valid_size( const struct sid *sid, data_size_t size ) +{ + return (size >= offsetof( struct sid, sub_auth[0] ) && size >= sid_len( sid )); +} + +static inline struct ace *set_ace( struct ace *ace, const struct sid *sid, unsigned char type, unsigned char flags, unsigned int mask ) { ace->type = type; ace->flags = flags; - ace->size = sizeof(*ace) + security_sid_len( sid ); + ace->size = sizeof(*ace) + sid_len( sid ); ace->mask = mask; - memcpy( ace + 1, sid, security_sid_len( sid )); + memcpy( ace + 1, sid, sid_len( sid )); return ace; } extern void security_set_thread_token( struct thread *thread, obj_handle_t handle ); -extern const SID *security_unix_uid_to_sid( uid_t uid ); +extern const struct sid *security_unix_uid_to_sid( uid_t uid ); extern int check_object_access( struct token *token, struct object *obj, unsigned int *access ); static inline int thread_single_check_privilege( struct thread *thread, struct luid priv ) @@ -161,19 +166,19 @@ static inline const struct acl *sd_get_sacl( const struct security_descriptor *s } /* gets the owner from a security descriptor */ -static inline const SID *sd_get_owner( const struct security_descriptor *sd ) +static inline const struct sid *sd_get_owner( const struct security_descriptor *sd ) { if (sd->owner_len) - return (const SID *)(sd + 1); + return (const struct 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 ) +static inline const struct sid *sd_get_group( const struct security_descriptor *sd ) { if (sd->group_len) - return (const SID *)((const char *)(sd + 1) + sd->owner_len); + return (const struct sid *)((const char *)(sd + 1) + sd->owner_len); else return NULL; } diff --git a/server/token.c b/server/token.c index 49168a77e10..8686d0f69a7 100644 --- a/server/token.c +++ b/server/token.c @@ -66,38 +66,23 @@ const struct luid SeCreateGlobalPrivilege = { 30, 0 }; struct sid_attrs { - const SID *sid; - unsigned int attrs; + const struct sid *sid; + unsigned int attrs; }; -#define SID_N(n) struct /* same fields as struct SID */ \ - { \ - BYTE Revision; \ - BYTE SubAuthorityCount; \ - SID_IDENTIFIER_AUTHORITY IdentifierAuthority; \ - DWORD SubAuthority[n]; \ - } +const struct sid world_sid = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, { SECURITY_WORLD_RID } }; +const struct sid local_system_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } }; +const struct sid high_label_sid = { SID_REVISION, 1, SECURITY_MANDATORY_LABEL_AUTHORITY, { SECURITY_MANDATORY_HIGH_RID } }; +const struct sid local_user_sid = { SID_REVISION, 5, SECURITY_NT_AUTHORITY, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, 1000 } }; +const struct sid builtin_admins_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } }; +const struct sid builtin_users_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } }; +const struct sid domain_users_sid = { SID_REVISION, 5, SECURITY_NT_AUTHORITY, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, DOMAIN_GROUP_RID_USERS } }; -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 anonymous_logon_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_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 const SID high_label_sid = { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY }, { SECURITY_MANDATORY_HIGH_RID } }; -static const SID_N(5) local_user_sid = { SID_REVISION, 5, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, 1000 } }; -static const SID_N(2) builtin_admins_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } }; -static const SID_N(2) builtin_users_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } }; -static const SID_N(3) builtin_logon_sid = { SID_REVISION, 3, { SECURITY_NT_AUTHORITY }, { SECURITY_LOGON_IDS_RID, 0, 0 } }; -static const SID_N(5) domain_users_sid = { SID_REVISION, 5, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, DOMAIN_GROUP_RID_USERS } }; - -const PSID security_world_sid = (PSID)&world_sid; -const PSID security_local_system_sid = (PSID)&local_system_sid; -const PSID security_local_user_sid = (PSID)&local_user_sid; -const PSID security_builtin_admins_sid = (PSID)&builtin_admins_sid; -const PSID security_builtin_users_sid = (PSID)&builtin_users_sid; -const PSID security_domain_users_sid = (PSID)&domain_users_sid; -const PSID security_high_label_sid = (PSID)&high_label_sid; +static const struct sid local_sid = { SID_REVISION, 1, SECURITY_LOCAL_SID_AUTHORITY, { SECURITY_LOCAL_RID } }; +static const struct sid interactive_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_INTERACTIVE_RID } }; +static const struct sid anonymous_logon_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_ANONYMOUS_LOGON_RID } }; +static const struct sid authenticated_user_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_AUTHENTICATED_USER_RID } }; +static const struct sid builtin_logon_sid = { SID_REVISION, 3, SECURITY_NT_AUTHORITY, { SECURITY_LOGON_IDS_RID, 0, 0 } }; static struct luid prev_luid_value = { 1000, 0 }; @@ -123,13 +108,12 @@ struct token struct luid modified_id; /* new id allocated every time token is modified */ struct list privileges; /* privileges available to the token */ struct list groups; /* groups that the user of this token belongs to (sid_and_attributes) */ - SID *user; /* SID of user this token represents */ - SID *owner; /* SID of owner (points to user or one of groups) */ - SID *primary_group; /* SID of user's primary group (points to one of groups) */ + struct sid *user; /* SID of user this token represents */ + struct sid *owner; /* SID of owner (points to user or one of groups) */ + struct sid *primary_group; /* SID of user's primary group (points to one of groups) */ unsigned int primary; /* is this a primary or impersonation token? */ unsigned int session_id; /* token session id */ struct acl *default_dacl; /* the default DACL to assign to objects created by this user */ - TOKEN_SOURCE source; /* source of the token */ int impersonation_level; /* impersonation level this token is capable of if non-primary token */ int elevation; /* elevation type */ }; @@ -152,7 +136,7 @@ struct group unsigned owner : 1; /* can this sid be an owner of an object? */ unsigned resource : 1; /* is this a domain-local group? */ unsigned deny_only: 1; /* is this a sid that should be use for denying only? */ - SID sid; + struct sid sid; }; static void token_dump( struct object *obj, int verbose ); @@ -190,19 +174,6 @@ static void token_dump( struct object *obj, int verbose ) token->token_id.low_part, token->primary, token->impersonation_level ); } -static SID *security_sid_alloc( const SID_IDENTIFIER_AUTHORITY *idauthority, int subauthcount, const unsigned int subauth[] ) -{ - int i; - SID *sid = mem_alloc( FIELD_OFFSET(SID, SubAuthority[subauthcount]) ); - if (!sid) return NULL; - sid->Revision = SID_REVISION; - sid->SubAuthorityCount = subauthcount; - sid->IdentifierAuthority = *idauthority; - for (i = 0; i < subauthcount; i++) - sid->SubAuthority[i] = subauth[i]; - return sid; -} - void security_set_thread_token( struct thread *thread, obj_handle_t handle ) { if (!handle) @@ -226,11 +197,11 @@ void security_set_thread_token( struct thread *thread, obj_handle_t handle ) } } -const SID *security_unix_uid_to_sid( uid_t uid ) +const struct sid *security_unix_uid_to_sid( uid_t uid ) { /* very simple mapping: either the current user or not the current user */ if (uid == getuid()) - return (const SID *)&local_user_sid; + return &local_user_sid; else return &anonymous_logon_sid; } @@ -260,21 +231,20 @@ static int acl_is_valid( const struct acl *acl, data_size_t size ) default: return FALSE; } - if (!sid_valid_size( (const SID *)(ace + 1), ace->size - sizeof(*ace) )) return FALSE; + if (!sid_valid_size( (const struct sid *)(ace + 1), ace->size - sizeof(*ace) )) return FALSE; } return TRUE; } -static unsigned int get_sid_count( const SID *sid, data_size_t size ) +static unsigned int get_sid_count( const struct sid *sid, data_size_t size ) { unsigned int count; - for (count = 0; size >= sizeof(SID) && security_sid_len( sid ) <= size; count++) + for (count = 0; sid_valid_size( sid, size ); count++) { - size -= security_sid_len( sid ); - sid = (const SID *)((char *)sid + security_sid_len( sid )); + size -= sid_len( sid ); + sid = (const struct sid *)((char *)sid + sid_len( sid )); } - return count; } @@ -283,8 +253,8 @@ static unsigned int get_sid_count( const SID *sid, 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; - const SID *owner; + const struct sid *group; + const struct sid *owner; const struct acl *sacl; const struct acl *dacl; int dummy; @@ -292,27 +262,15 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size ) if (size < offset) return FALSE; - if ((sd->owner_len >= FIELD_OFFSET(SID, SubAuthority[255])) || - (offset + sd->owner_len > size)) - return FALSE; + if (sd->owner_len >= offsetof(struct sid, sub_auth[255]) || offset + sd->owner_len > size) return FALSE; owner = sd_get_owner( sd ); - if (owner) - { - if ((sd->owner_len < sizeof(SID)) || (security_sid_len( owner ) > sd->owner_len)) - return FALSE; - } offset += sd->owner_len; + if (owner && !sid_valid_size( owner, sd->owner_len )) return FALSE; - if ((sd->group_len >= FIELD_OFFSET(SID, SubAuthority[255])) || - (offset + sd->group_len > size)) - return FALSE; + if (sd->group_len >= offsetof(struct sid, sub_auth[255]) || offset + sd->group_len > size) return FALSE; group = sd_get_group( sd ); - if (group) - { - if ((sd->group_len < sizeof(SID)) || (security_sid_len( group ) > sd->group_len)) - return FALSE; - } offset += sd->group_len; + if (group && !sid_valid_size( group, sd->group_len )) return FALSE; if ((sd->sacl_len >= MAX_ACL_LEN) || (offset + sd->sacl_len > size)) return FALSE; @@ -517,11 +475,10 @@ static void token_destroy( struct object *obj ) * modified_id may be NULL, indicating that a new modified_id luid should be * allocated. */ -static struct token *create_token( unsigned int primary, unsigned int session_id, const SID *user, +static struct token *create_token( unsigned int primary, unsigned int session_id, const struct sid *user, const struct sid_attrs *groups, unsigned int group_count, const struct luid_attr *privs, unsigned int priv_count, - const struct acl *default_dacl, TOKEN_SOURCE source, - const struct luid *modified_id, + const struct acl *default_dacl, const struct luid *modified_id, int impersonation_level, int elevation ) { struct token *token = alloc_object( &token_ops ); @@ -548,7 +505,7 @@ static struct token *create_token( unsigned int primary, unsigned int session_id token->elevation = elevation; /* copy user */ - token->user = memdup( user, security_sid_len( user )); + token->user = memdup( user, sid_len( user )); if (!token->user) { release_object( token ); @@ -558,7 +515,7 @@ static struct token *create_token( unsigned int primary, unsigned int session_id /* copy groups */ for (i = 0; i < group_count; i++) { - size_t size = FIELD_OFFSET( struct group, sid.SubAuthority[groups[i].sid->SubAuthorityCount] ); + size_t size = offsetof( struct group, sid.sub_auth[groups[i].sid->sub_count] ); struct group *group = mem_alloc( size ); if (!group) @@ -566,7 +523,7 @@ static struct token *create_token( unsigned int primary, unsigned int session_id release_object( token ); return NULL; } - memcpy( &group->sid, groups[i].sid, security_sid_len( groups[i].sid )); + copy_sid( &group->sid, groups[i].sid ); group->enabled = TRUE; group->def = TRUE; group->logon = (groups[i].attrs & SE_GROUP_LOGON_ID) != 0; @@ -604,20 +561,18 @@ static struct token *create_token( unsigned int primary, unsigned int session_id return NULL; } } - - token->source = source; } return token; } -static int filter_group( struct group *group, const SID *filter, unsigned int count ) +static int filter_group( struct group *group, const struct sid *filter, unsigned int count ) { unsigned int i; for (i = 0; i < count; i++) { - if (security_equal_sid( &group->sid, filter )) return 1; - filter = (const SID *)((char *)filter + security_sid_len( filter )); + if (equal_sid( &group->sid, filter )) return 1; + filter = (const struct sid *)((char *)filter + sid_len( filter )); } return 0; @@ -636,7 +591,7 @@ static int filter_privilege( struct privilege *privilege, const struct luid_attr struct token *token_duplicate( struct token *src_token, unsigned primary, int impersonation_level, const struct security_descriptor *sd, const struct luid_attr *remove_privs, unsigned int remove_priv_count, - const SID *remove_groups, unsigned int remove_group_count) + const struct sid *remove_groups, unsigned int remove_group_count) { const struct luid *modified_id = primary || (impersonation_level == src_token->impersonation_level) ? @@ -655,8 +610,7 @@ struct token *token_duplicate( struct token *src_token, unsigned primary, } token = create_token( primary, src_token->session_id, src_token->user, NULL, 0, - NULL, 0, src_token->default_dacl, - src_token->source, modified_id, + NULL, 0, src_token->default_dacl, modified_id, impersonation_level, src_token->elevation ); if (!token) return token; @@ -664,7 +618,7 @@ struct token *token_duplicate( struct token *src_token, unsigned primary, token->primary_group = NULL; LIST_FOR_EACH_ENTRY( group, &src_token->groups, struct group, entry ) { - size_t size = FIELD_OFFSET( struct group, sid.SubAuthority[group->sid.SubAuthorityCount] ); + size_t size = offsetof( struct group, sid.sub_auth[group->sid.sub_count] ); struct group *newgroup = mem_alloc( size ); if (!newgroup) { @@ -704,12 +658,12 @@ struct token *token_duplicate( struct token *src_token, unsigned primary, return token; } -static struct acl *create_default_dacl( const SID *user ) +static struct acl *create_default_dacl( const struct sid *user ) { struct ace *ace; struct acl *default_dacl; size_t default_dacl_size = sizeof(*default_dacl) + 2 * sizeof(*ace) + - sizeof(local_system_sid) + security_sid_len( user ); + sid_len( &local_system_sid ) + sid_len( user ); default_dacl = mem_alloc( default_dacl_size ); if (!default_dacl) return NULL; @@ -735,13 +689,13 @@ struct sid_data unsigned int subauth[MAX_SUBAUTH_COUNT]; }; -static struct security_descriptor *create_security_label_sd( struct token *token, PSID label_sid ) +static struct security_descriptor *create_security_label_sd( struct token *token, const struct sid *label_sid ) { - size_t sid_len = security_sid_len( label_sid ), sacl_size, sd_size; + size_t sid_size = sid_len( label_sid ), sacl_size, sd_size; struct security_descriptor *sd; struct acl *sacl; - sacl_size = sizeof(*sacl) + sizeof(struct ace) + sid_len; + sacl_size = sizeof(*sacl) + sizeof(struct ace) + sid_size; sd_size = sizeof(struct security_descriptor) + sacl_size; if (!(sd = mem_alloc( sd_size ))) return NULL; @@ -765,7 +719,7 @@ static struct security_descriptor *create_security_label_sd( struct token *token return sd; } -int token_assign_label( struct token *token, PSID label ) +int token_assign_label( struct token *token, const struct sid *label ) { struct security_descriptor *sd; int ret = 0; @@ -787,75 +741,57 @@ struct token *get_token_obj( struct process *process, obj_handle_t handle, unsig struct token *token_create_admin( unsigned primary, int impersonation_level, int elevation, unsigned int session_id ) { struct token *token = NULL; - 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 }; + struct sid alias_admins_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS }}; + struct sid alias_users_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS }}; /* on Windows, this value changes every time the user logs on */ - static const unsigned int logon_subauth[] = { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ }; - PSID alias_admins_sid; - PSID alias_users_sid; - PSID logon_sid; - const SID *user_sid = security_unix_uid_to_sid( getuid() ); + struct sid logon_sid = { SID_REVISION, 3, SECURITY_NT_AUTHORITY, { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ }}; + const struct sid *user_sid = security_unix_uid_to_sid( getuid() ); struct acl *default_dacl = create_default_dacl( user_sid ); - - alias_admins_sid = security_sid_alloc( &nt_authority, ARRAY_SIZE( alias_admins_subauth ), - alias_admins_subauth ); - alias_users_sid = security_sid_alloc( &nt_authority, ARRAY_SIZE( alias_users_subauth ), - alias_users_subauth ); - logon_sid = security_sid_alloc( &nt_authority, ARRAY_SIZE( logon_subauth ), logon_subauth ); - - if (alias_admins_sid && alias_users_sid && logon_sid && default_dacl) + const struct luid_attr admin_privs[] = { - const struct luid_attr admin_privs[] = - { - { SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED }, - { SeTcbPrivilege , 0 }, - { SeSecurityPrivilege , 0 }, - { SeBackupPrivilege , 0 }, - { SeRestorePrivilege , 0 }, - { SeSystemtimePrivilege , 0 }, - { SeShutdownPrivilege , 0 }, - { SeRemoteShutdownPrivilege , 0 }, - { SeTakeOwnershipPrivilege , 0 }, - { SeDebugPrivilege , 0 }, - { SeSystemEnvironmentPrivilege , 0 }, - { SeSystemProfilePrivilege , 0 }, - { SeProfileSingleProcessPrivilege, 0 }, - { SeIncreaseBasePriorityPrivilege, 0 }, - { SeLoadDriverPrivilege , SE_PRIVILEGE_ENABLED }, - { SeCreatePagefilePrivilege , 0 }, - { SeIncreaseQuotaPrivilege , 0 }, - { SeUndockPrivilege , 0 }, - { SeManageVolumePrivilege , 0 }, - { SeImpersonatePrivilege , SE_PRIVILEGE_ENABLED }, - { SeCreateGlobalPrivilege , SE_PRIVILEGE_ENABLED }, - }; - /* note: we don't include non-builtin groups here for the user - - * telling us these is the job of a client-side program */ - const struct sid_attrs admin_groups[] = - { - { &world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, - { &local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, - { &interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, - { &authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, - { (SID *)&domain_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER }, - { alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER }, - { alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, - { logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID }, - }; - static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}}; - token = create_token( primary, session_id, user_sid, admin_groups, ARRAY_SIZE( admin_groups ), - admin_privs, ARRAY_SIZE( admin_privs ), default_dacl, - admin_source, NULL, impersonation_level, elevation ); - /* we really need a primary group */ - assert( token->primary_group ); - } + { SeChangeNotifyPrivilege, SE_PRIVILEGE_ENABLED }, + { SeTcbPrivilege, 0 }, + { SeSecurityPrivilege, 0 }, + { SeBackupPrivilege, 0 }, + { SeRestorePrivilege, 0 }, + { SeSystemtimePrivilege, 0 }, + { SeShutdownPrivilege, 0 }, + { SeRemoteShutdownPrivilege, 0 }, + { SeTakeOwnershipPrivilege, 0 }, + { SeDebugPrivilege, 0 }, + { SeSystemEnvironmentPrivilege, 0 }, + { SeSystemProfilePrivilege, 0 }, + { SeProfileSingleProcessPrivilege, 0 }, + { SeIncreaseBasePriorityPrivilege, 0 }, + { SeLoadDriverPrivilege, SE_PRIVILEGE_ENABLED }, + { SeCreatePagefilePrivilege, 0 }, + { SeIncreaseQuotaPrivilege, 0 }, + { SeUndockPrivilege, 0 }, + { SeManageVolumePrivilege, 0 }, + { SeImpersonatePrivilege, SE_PRIVILEGE_ENABLED }, + { SeCreateGlobalPrivilege, SE_PRIVILEGE_ENABLED }, + }; + /* note: we don't include non-builtin groups here for the user - + * telling us these is the job of a client-side program */ + const struct sid_attrs admin_groups[] = + { + { &world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, + { &local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, + { &interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, + { &authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, + { &domain_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER }, + { &alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER }, + { &alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY }, + { &logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID }, + }; + + token = create_token( primary, session_id, user_sid, admin_groups, ARRAY_SIZE( admin_groups ), + admin_privs, ARRAY_SIZE( admin_privs ), default_dacl, + NULL, impersonation_level, elevation ); + /* we really need a primary group */ + assert( token->primary_group ); - free( logon_sid ); - free( alias_admins_sid ); - free( alias_users_sid ); free( default_dacl ); - return token; } @@ -944,18 +880,17 @@ int token_check_privileges( struct token *token, int all_required, const struct return (enabled_count > 0); } -int token_sid_present( struct token *token, const SID *sid, int deny ) +int token_sid_present( struct token *token, const struct sid *sid, int deny ) { struct group *group; - if (security_equal_sid( token->user, sid )) return TRUE; + if (equal_sid( token->user, sid )) return TRUE; LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry ) { if (!group->enabled) continue; if (group->deny_only && !deny) continue; - - if (security_equal_sid( &group->sid, sid )) return TRUE; + if (equal_sid( &group->sid, sid )) return TRUE; } return FALSE; @@ -982,7 +917,7 @@ static unsigned int token_access_check( struct token *token, const struct acl *dacl; int dacl_present; const struct ace *ace; - const SID *owner; + const struct sid *owner; /* assume no access rights */ *granted_access = 0; @@ -1068,7 +1003,7 @@ static unsigned int token_access_check( struct token *token, /* 4: Grant rights according to the DACL */ for (i = 0, ace = ace_first( dacl ); i < dacl->count; i++, ace = ace_next( ace )) { - const SID *sid = (const SID *)(ace + 1); + const struct sid *sid = (const struct sid *)(ace + 1); if (ace->flags & INHERIT_ONLY_ACE) continue; @@ -1123,12 +1058,12 @@ const struct acl *token_get_default_dacl( struct token *token ) return token->default_dacl; } -const SID *token_get_user( struct token *token ) +const struct sid *token_get_user( struct token *token ) { return token->user; } -const SID *token_get_primary_group( struct token *token ) +const struct sid *token_get_primary_group( struct token *token ) { return token->primary_group; } @@ -1311,11 +1246,11 @@ DECL_HANDLER(filter_token) { const struct luid_attr *filter_privileges = get_req_data(); unsigned int priv_count, group_count; - const SID *filter_groups; + const struct sid *filter_groups; struct token *token; priv_count = min( req->privileges_size, get_req_data_size() ) / sizeof(struct luid_attr); - filter_groups = (const SID *)((char *)filter_privileges + priv_count * sizeof(struct luid_attr)); + filter_groups = (const struct sid *)((char *)filter_privileges + priv_count * sizeof(struct luid_attr)); group_count = get_sid_count( filter_groups, get_req_data_size() - priv_count * sizeof(struct luid_attr) ); token = token_duplicate( src_token, src_token->primary, src_token->impersonation_level, NULL, @@ -1418,7 +1353,7 @@ DECL_HANDLER(get_token_sid) if ((token = (struct token *)get_handle_obj( current->process, req->handle, TOKEN_QUERY, &token_ops ))) { - const SID *sid = NULL; + const struct sid *sid = NULL; switch (req->which_sid) { @@ -1433,7 +1368,7 @@ DECL_HANDLER(get_token_sid) sid = token->owner; break; case TokenLogonSid: - sid = (const SID *)&builtin_logon_sid; + sid = &builtin_logon_sid; break; default: set_error( STATUS_INVALID_PARAMETER ); @@ -1442,7 +1377,7 @@ DECL_HANDLER(get_token_sid) if (sid) { - reply->sid_len = security_sid_len( sid ); + reply->sid_len = sid_len( sid ); if (reply->sid_len <= get_reply_max_size()) set_reply_data( sid, reply->sid_len ); else set_error( STATUS_BUFFER_TOO_SMALL ); } @@ -1469,7 +1404,7 @@ DECL_HANDLER(get_token_groups) LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry ) { group_count++; - sid_size += security_sid_len( &group->sid ); + sid_size += sid_len( &group->sid ); } size_needed += sid_size; /* attributes size */ @@ -1491,7 +1426,7 @@ DECL_HANDLER(get_token_groups) if (tg) { unsigned int *attr_ptr = (unsigned int *)(tg + 1); - SID *sid_ptr = (SID *)(attr_ptr + group_count); + struct sid *sid = (struct sid *)(attr_ptr + group_count); tg->count = group_count; @@ -1506,10 +1441,7 @@ DECL_HANDLER(get_token_groups) if (group->deny_only) *attr_ptr |= SE_GROUP_USE_FOR_DENY_ONLY; if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE; if (group->logon) *attr_ptr |= SE_GROUP_LOGON_ID; - - memcpy(sid_ptr, &group->sid, security_sid_len( &group->sid )); - - sid_ptr = (SID *)((char *)sid_ptr + security_sid_len( &group->sid )); + sid = copy_sid( sid, &group->sid ); attr_ptr++; } } diff --git a/server/trace.c b/server/trace.c index 9516435769b..72b404956ec 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1016,33 +1016,27 @@ static void dump_varargs_luid_attr( const char *prefix, data_size_t size ) remove_data( size ); } -static void dump_inline_sid( const char *prefix, const SID *sid, data_size_t size ) +static void dump_inline_sid( const char *prefix, const struct sid *sid, data_size_t size ) { DWORD i; - /* security check */ - if ((FIELD_OFFSET(SID, SubAuthority[0]) > size) || - (FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) > size)) + fprintf( stderr,"%s", prefix ); + if (sid_valid_size( sid, size )) { - fprintf( stderr, "" ); - return; + fprintf( stderr, "S-%u-%u", sid->revision, + ((unsigned int)sid->id_auth[2] << 24) | + ((unsigned int)sid->id_auth[3] << 16) | + ((unsigned int)sid->id_auth[4] << 8) | + ((unsigned int)sid->id_auth[5]) ); + for (i = 0; i < sid->sub_count; i++) fprintf( stderr, "-%u", sid->sub_auth[i] ); } - - fprintf( stderr,"%s{", prefix ); - fprintf( stderr, "S-%u-%u", sid->Revision, MAKELONG( - MAKEWORD( sid->IdentifierAuthority.Value[5], - sid->IdentifierAuthority.Value[4] ), - MAKEWORD( sid->IdentifierAuthority.Value[3], - sid->IdentifierAuthority.Value[2] ) ) ); - for (i = 0; i < sid->SubAuthorityCount; i++) - fprintf( stderr, "-%u", sid->SubAuthority[i] ); - fputc( '}', stderr ); + else fprintf( stderr, "" ); } -static void dump_varargs_SID( const char *prefix, data_size_t size ) +static void dump_varargs_sid( const char *prefix, data_size_t size ) { - const SID *sid = cur_data; - dump_inline_sid( prefix, sid, size ); + const struct sid *sid = cur_data; + if (size) dump_inline_sid( prefix, sid, size ); remove_data( size ); } @@ -1062,7 +1056,7 @@ static void dump_inline_acl( const char *prefix, const struct acl *acl, data_siz size -= sizeof(*acl); for (i = 0, ace = ace_first( acl ); i < acl->count; i++, ace = ace_next( ace )) { - const SID *sid = (const SID *)(ace + 1); + const struct sid *sid = (const struct sid *)(ace + 1); data_size_t sid_size; if (size < sizeof(*ace) || size < ace->size) break; @@ -1104,17 +1098,17 @@ static void dump_inline_security_descriptor( const char *prefix, const struct se { size_t offset = sizeof(struct security_descriptor); fprintf( stderr, "control=%08x", sd->control ); - if ((sd->owner_len > FIELD_OFFSET(SID, SubAuthority[255])) || (offset + sd->owner_len > size)) + if ((sd->owner_len > offsetof(struct sid, sub_auth[255])) || (offset + sd->owner_len > size)) return; if (sd->owner_len) - dump_inline_sid( ",owner=", (const SID *)((const char *)sd + offset), sd->owner_len ); + dump_inline_sid( ",owner=", (const struct sid *)((const char *)sd + offset), sd->owner_len ); else fprintf( stderr, ",owner=" ); offset += sd->owner_len; - if ((sd->group_len > FIELD_OFFSET(SID, SubAuthority[255])) || (offset + sd->group_len > size)) + if ((sd->group_len > offsetof(struct sid, sub_auth[255])) || (offset + sd->group_len > size)) return; if (sd->group_len) - dump_inline_sid( ",group=", (const SID *)((const char *)sd + offset), sd->group_len ); + dump_inline_sid( ",group=", (const struct sid *)((const char *)sd + offset), sd->group_len ); else fprintf( stderr, ",group=" ); offset += sd->group_len; @@ -1156,16 +1150,14 @@ static void dump_varargs_token_groups( const char *prefix, data_size_t size ) fputc( '[', stderr ); for (i = 0; i < tg->count; i++) { - const SID *sid = (const SID *)((const char *)cur_data + offset); + const struct sid *sid = (const struct sid *)((const char *)cur_data + offset); if (i != 0) fputc( ',', stderr ); fputc( '{', stderr ); fprintf( stderr, "attributes=%08x", attr[i] ); dump_inline_sid( ",sid=", sid, size - offset ); - if ((offset + FIELD_OFFSET(SID, SubAuthority[0]) > size) || - (offset + FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) > size)) - break; - offset += FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]); + if (!sid_valid_size( sid, size - offset )) break; + offset += sid_len( sid ); fputc( '}', stderr ); } fputc( ']', stderr ); @@ -3834,7 +3826,7 @@ static void dump_filter_token_request( const struct filter_token_request *req ) fprintf( stderr, ", flags=%08x", req->flags ); fprintf( stderr, ", privileges_size=%u", req->privileges_size ); dump_varargs_luid_attr( ", privileges=", min(cur_size,req->privileges_size) ); - dump_varargs_SID( ", disable_sids=", cur_size ); + dump_varargs_sid( ", disable_sids=", cur_size ); } static void dump_filter_token_reply( const struct filter_token_reply *req ) @@ -3867,7 +3859,7 @@ static void dump_get_token_sid_request( const struct get_token_sid_request *req static void dump_get_token_sid_reply( const struct get_token_sid_reply *req ) { fprintf( stderr, " sid_len=%u", req->sid_len ); - dump_varargs_SID( ", sid=", cur_size ); + dump_varargs_sid( ", sid=", cur_size ); } static void dump_get_token_groups_request( const struct get_token_groups_request *req )