server: Define a server-side structure for SID.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
841b8862fb
commit
990cc1c64b
|
@ -385,6 +385,14 @@ struct acl
|
||||||
unsigned short pad2;
|
unsigned short pad2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sid
|
||||||
|
{
|
||||||
|
unsigned char revision;
|
||||||
|
unsigned char sub_count;
|
||||||
|
unsigned char id_auth[6];
|
||||||
|
unsigned int sub_auth[15];
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned int read;
|
unsigned int read;
|
||||||
|
@ -4411,7 +4419,7 @@ struct filter_token_request
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
data_size_t privileges_size;
|
data_size_t privileges_size;
|
||||||
/* VARARG(privileges,luid_attr,privileges_size); */
|
/* VARARG(privileges,luid_attr,privileges_size); */
|
||||||
/* VARARG(disable_sids,SID); */
|
/* VARARG(disable_sids,sid); */
|
||||||
};
|
};
|
||||||
struct filter_token_reply
|
struct filter_token_reply
|
||||||
{
|
{
|
||||||
|
@ -4450,7 +4458,7 @@ struct get_token_sid_reply
|
||||||
{
|
{
|
||||||
struct reply_header __header;
|
struct reply_header __header;
|
||||||
data_size_t sid_len;
|
data_size_t sid_len;
|
||||||
/* VARARG(sid,SID); */
|
/* VARARG(sid,sid); */
|
||||||
char __pad_12[4];
|
char __pad_12[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6261,7 +6269,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 741
|
#define SERVER_PROTOCOL_VERSION 742
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,7 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||||
unsigned int set_info )
|
unsigned int set_info )
|
||||||
{
|
{
|
||||||
struct dir *dir = (struct dir *)obj;
|
struct dir *dir = (struct dir *)obj;
|
||||||
const SID *owner;
|
const struct sid *owner;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
int unix_fd;
|
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 );
|
set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||||
return 0;
|
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 */
|
/* FIXME: get Unix uid and call fchown */
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||||
|
|
||||||
if (sd)
|
if (sd)
|
||||||
{
|
{
|
||||||
const SID *owner = sd_get_owner( sd );
|
const struct sid *owner = sd_get_owner( sd );
|
||||||
if (!owner)
|
if (!owner)
|
||||||
owner = token_get_user( current->process->token );
|
owner = token_get_user( current->process->token );
|
||||||
mode = sd_to_mode( sd, owner );
|
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 );
|
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;
|
struct security_descriptor *sd;
|
||||||
unsigned char flags;
|
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 ace *ace;
|
||||||
struct acl *dacl;
|
struct acl *dacl;
|
||||||
char *ptr;
|
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 );
|
dacl_size = sizeof(*dacl) + sizeof(*ace) + sid_len( &local_system_sid );
|
||||||
if (mode & S_IRWXU) dacl_size += sizeof(*ace) + security_sid_len( user );
|
if (mode & S_IRWXU) dacl_size += sizeof(*ace) + sid_len( user );
|
||||||
if ((!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) ||
|
if ((!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) ||
|
||||||
(!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) ||
|
(!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) ||
|
||||||
(!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))))
|
(!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))))
|
||||||
dacl_size += sizeof(*ace) + security_sid_len( user );
|
dacl_size += sizeof(*ace) + sid_len( user );
|
||||||
if (mode & S_IRWXO) dacl_size += sizeof(*ace) + security_sid_len( world_sid );
|
if (mode & S_IRWXO) dacl_size += sizeof(*ace) + sid_len( &world_sid );
|
||||||
|
|
||||||
sd = mem_alloc( sizeof(struct security_descriptor) +
|
sd = mem_alloc( sizeof(*sd) + sid_len( user ) + sid_len( group ) + dacl_size );
|
||||||
security_sid_len( user ) + security_sid_len( group ) +
|
|
||||||
dacl_size );
|
|
||||||
if (!sd) return sd;
|
if (!sd) return sd;
|
||||||
|
|
||||||
sd->control = SE_DACL_PRESENT;
|
sd->control = SE_DACL_PRESENT;
|
||||||
sd->owner_len = security_sid_len( user );
|
sd->owner_len = sid_len( user );
|
||||||
sd->group_len = security_sid_len( group );
|
sd->group_len = sid_len( group );
|
||||||
sd->sacl_len = 0;
|
sd->sacl_len = 0;
|
||||||
sd->dacl_len = dacl_size;
|
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;
|
flags = (mode & S_IFDIR) ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0;
|
||||||
|
|
||||||
/* always give FILE_ALL_ACCESS for Local System */
|
/* 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 );
|
ACCESS_ALLOWED_ACE_TYPE, flags, FILE_ALL_ACCESS );
|
||||||
|
|
||||||
if (mode & S_IRWXU)
|
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)
|
if (mode & S_IRWXO)
|
||||||
{
|
{
|
||||||
/* appropriate access rights for Everyone */
|
/* 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_IROTH) ace->mask |= FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
|
||||||
if (mode & S_IWOTH) ace->mask |= FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD;
|
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;
|
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 new_mode = 0;
|
||||||
mode_t bits_to_set = ~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 ))
|
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;
|
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)
|
switch (ace->type)
|
||||||
{
|
{
|
||||||
case ACCESS_DENIED_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 */
|
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 */
|
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 */
|
bits_to_set &= ~(mode << 6); /* user only */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACCESS_ALLOWED_ACE_TYPE:
|
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 */
|
mode = (mode << 6) | (mode << 3) | mode; /* all */
|
||||||
new_mode |= mode & bits_to_set;
|
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;
|
new_mode |= mode & bits_to_set;
|
||||||
bits_to_set &= ~mode;
|
bits_to_set &= ~mode;
|
||||||
}
|
}
|
||||||
else if (security_equal_sid( sid, owner ))
|
else if (equal_sid( sid, owner ))
|
||||||
{
|
{
|
||||||
mode = (mode << 6); /* user only */
|
mode = (mode << 6); /* user only */
|
||||||
new_mode |= mode & bits_to_set;
|
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 )
|
unsigned int set_info )
|
||||||
{
|
{
|
||||||
struct file *file = (struct file *)obj;
|
struct file *file = (struct file *)obj;
|
||||||
const SID *owner;
|
const struct sid *owner;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
int unix_fd;
|
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 );
|
set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||||
return 0;
|
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 */
|
/* FIXME: get Unix uid and call fchown */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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( 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 struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigned int sharing );
|
||||||
extern void file_set_error(void);
|
extern void file_set_error(void);
|
||||||
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
|
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 SID *owner );
|
extern mode_t sd_to_mode( const struct security_descriptor *sd, const struct sid *owner );
|
||||||
extern int is_file_executable( const char *name );
|
extern int is_file_executable( const char *name );
|
||||||
|
|
||||||
/* file mapping functions */
|
/* file mapping functions */
|
||||||
|
|
|
@ -737,7 +737,7 @@ DECL_HANDLER(get_security_object)
|
||||||
unsigned int access = READ_CONTROL;
|
unsigned int access = READ_CONTROL;
|
||||||
struct security_descriptor req_sd;
|
struct security_descriptor req_sd;
|
||||||
int present;
|
int present;
|
||||||
const SID *owner, *group;
|
const struct sid *owner, *group;
|
||||||
const struct acl *sacl, *dacl;
|
const struct acl *sacl, *dacl;
|
||||||
struct acl *label_acl = NULL;
|
struct acl *label_acl = NULL;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
struct security_descriptor new_sd, *new_sd_ptr;
|
||||||
int present;
|
int present;
|
||||||
const SID *owner = NULL, *group = NULL;
|
const struct sid *owner = NULL, *group = NULL;
|
||||||
const struct acl *sacl, *dacl;
|
const struct acl *sacl, *dacl;
|
||||||
struct acl *replaced_sacl = NULL;
|
struct acl *replaced_sacl = NULL;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
@ -565,7 +565,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
|
||||||
else if (token)
|
else if (token)
|
||||||
{
|
{
|
||||||
owner = token_get_user( 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;
|
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)
|
else if (token)
|
||||||
{
|
{
|
||||||
group = token_get_primary_group( 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;
|
else new_sd.group_len = 0;
|
||||||
|
|
||||||
|
|
|
@ -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
|
/* 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
|
* but Wine provides admin access to all applications right now so high
|
||||||
* makes more sense for the time being. */
|
* 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;
|
goto error;
|
||||||
|
|
||||||
set_fd_events( process->msg_fd, POLLIN ); /* start listening to events */
|
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 ace *ace;
|
||||||
struct acl *dacl;
|
struct acl *dacl;
|
||||||
size_t users_sid_len = security_sid_len( security_domain_users_sid );
|
struct sid *sid;
|
||||||
size_t admins_sid_len = security_sid_len( security_builtin_admins_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;
|
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
|
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->group_len = users_sid_len;
|
||||||
process_default_sd->sacl_len = 0;
|
process_default_sd->sacl_len = 0;
|
||||||
process_default_sd->dacl_len = dacl_len;
|
process_default_sd->dacl_len = dacl_len;
|
||||||
memcpy( process_default_sd + 1, security_builtin_admins_sid, admins_sid_len );
|
sid = (struct sid *)(process_default_sd + 1);
|
||||||
memcpy( (char *)(process_default_sd + 1) + admins_sid_len, security_domain_users_sid, users_sid_len );
|
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 = (struct acl *)((char *)(process_default_sd + 1) + admins_sid_len + users_sid_len);
|
||||||
dacl->revision = ACL_REVISION;
|
dacl->revision = ACL_REVISION;
|
||||||
|
@ -845,9 +847,9 @@ static struct security_descriptor *process_get_sd( struct object *obj )
|
||||||
dacl->size = dacl_len;
|
dacl->size = dacl_len;
|
||||||
dacl->count = 2;
|
dacl->count = 2;
|
||||||
dacl->pad2 = 0;
|
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 );
|
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;
|
return process_default_sd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,6 +401,14 @@ struct acl
|
||||||
unsigned short pad2;
|
unsigned short pad2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sid
|
||||||
|
{
|
||||||
|
unsigned char revision;
|
||||||
|
unsigned char sub_count;
|
||||||
|
unsigned char id_auth[6];
|
||||||
|
unsigned int sub_auth[15];
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned int read;
|
unsigned int read;
|
||||||
|
@ -418,8 +426,8 @@ struct security_descriptor
|
||||||
data_size_t group_len;
|
data_size_t group_len;
|
||||||
data_size_t sacl_len;
|
data_size_t sacl_len;
|
||||||
data_size_t dacl_len;
|
data_size_t dacl_len;
|
||||||
/* VARARG(owner,SID); */
|
/* VARARG(owner,sid); */
|
||||||
/* VARARG(group,SID); */
|
/* VARARG(group,sid); */
|
||||||
/* VARARG(sacl,acl); */
|
/* VARARG(sacl,acl); */
|
||||||
/* VARARG(dacl,acl); */
|
/* VARARG(dacl,acl); */
|
||||||
};
|
};
|
||||||
|
@ -451,7 +459,7 @@ struct token_groups
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
/* unsigned int attributes[count]; */
|
/* unsigned int attributes[count]; */
|
||||||
/* VARARG(sids,SID); */
|
/* VARARG(sids,sid); */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum select_op
|
enum select_op
|
||||||
|
@ -3138,7 +3146,7 @@ enum caret_state
|
||||||
unsigned int flags; /* flags */
|
unsigned int flags; /* flags */
|
||||||
data_size_t privileges_size; /* size of privileges */
|
data_size_t privileges_size; /* size of privileges */
|
||||||
VARARG(privileges,luid_attr,privileges_size); /* privileges to remove from new token */
|
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
|
@REPLY
|
||||||
obj_handle_t new_handle; /* filtered handle */
|
obj_handle_t new_handle; /* filtered handle */
|
||||||
@END
|
@END
|
||||||
|
@ -3160,7 +3168,7 @@ enum caret_state
|
||||||
unsigned int which_sid; /* which SID to retrieve from the token */
|
unsigned int which_sid; /* which SID to retrieve from the token */
|
||||||
@REPLY
|
@REPLY
|
||||||
data_size_t sid_len; /* length needed to store sid */
|
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
|
@END
|
||||||
|
|
||||||
@REQ(get_token_groups)
|
@REQ(get_token_groups)
|
||||||
|
|
|
@ -371,8 +371,9 @@ static struct security_descriptor *key_get_sd( struct object *obj )
|
||||||
{
|
{
|
||||||
struct acl *dacl;
|
struct acl *dacl;
|
||||||
struct ace *ace;
|
struct ace *ace;
|
||||||
size_t users_sid_len = security_sid_len( security_builtin_users_sid );
|
struct sid *sid;
|
||||||
size_t admins_sid_len = security_sid_len( security_builtin_admins_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;
|
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 );
|
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->group_len = admins_sid_len;
|
||||||
key_default_sd->sacl_len = 0;
|
key_default_sd->sacl_len = 0;
|
||||||
key_default_sd->dacl_len = dacl_len;
|
key_default_sd->dacl_len = dacl_len;
|
||||||
memcpy( key_default_sd + 1, security_builtin_admins_sid, admins_sid_len );
|
sid = (struct sid *)(key_default_sd + 1);
|
||||||
memcpy( (char *)(key_default_sd + 1) + admins_sid_len, security_builtin_admins_sid, admins_sid_len );
|
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 = (struct acl *)((char *)(key_default_sd + 1) + 2 * admins_sid_len);
|
||||||
dacl->revision = ACL_REVISION;
|
dacl->revision = ACL_REVISION;
|
||||||
|
@ -390,9 +392,9 @@ static struct security_descriptor *key_get_sd( struct object *obj )
|
||||||
dacl->size = dacl_len;
|
dacl->size = dacl_len;
|
||||||
dacl->count = 2;
|
dacl->count = 2;
|
||||||
dacl->pad2 = 0;
|
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 );
|
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;
|
return key_default_sd;
|
||||||
}
|
}
|
||||||
|
@ -1791,17 +1793,17 @@ static int load_init_registry_from_file( const char *filename, struct key *key )
|
||||||
return (f != NULL);
|
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;
|
unsigned int i;
|
||||||
|
|
||||||
p += sprintf( p, "User\\S-%u-%u", sid->Revision,
|
p += sprintf( p, "User\\S-%u-%u", sid->revision,
|
||||||
MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5],
|
((unsigned int)sid->id_auth[2] << 24) |
|
||||||
sid->IdentifierAuthority.Value[4] ),
|
((unsigned int)sid->id_auth[3] << 16) |
|
||||||
MAKEWORD( sid->IdentifierAuthority.Value[3],
|
((unsigned int)sid->id_auth[4] << 8) |
|
||||||
sid->IdentifierAuthority.Value[2] )));
|
((unsigned int)sid->id_auth[5]) );
|
||||||
for (i = 0; i < sid->SubAuthorityCount; i++) p += sprintf( p, "-%u", sid->SubAuthority[i] );
|
for (i = 0; i < sid->sub_count; i++) p += sprintf( p, "-%u", sid->sub_auth[i] );
|
||||||
return ascii_to_unicode_str( buffer, path );
|
return ascii_to_unicode_str( buffer, path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1900,7 +1902,7 @@ void init_registry(void)
|
||||||
/* load user.reg into HKEY_CURRENT_USER */
|
/* load user.reg into HKEY_CURRENT_USER */
|
||||||
|
|
||||||
/* FIXME: match default user in token.c. should get from process token instead */
|
/* 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 ||
|
if (!current_user_path ||
|
||||||
!(hkcu = create_key_recursive( root_key, ¤t_user_str, current_time )))
|
!(hkcu = create_key_recursive( root_key, ¤t_user_str, current_time )))
|
||||||
fatal_error( "could not create HKEY_CURRENT_USER registry key\n" );
|
fatal_error( "could not create HKEY_CURRENT_USER registry key\n" );
|
||||||
|
|
|
@ -44,13 +44,13 @@ extern const struct luid SeManageVolumePrivilege;
|
||||||
extern const struct luid SeImpersonatePrivilege;
|
extern const struct luid SeImpersonatePrivilege;
|
||||||
extern const struct luid SeCreateGlobalPrivilege;
|
extern const struct luid SeCreateGlobalPrivilege;
|
||||||
|
|
||||||
extern const PSID security_world_sid;
|
extern const struct sid world_sid;
|
||||||
extern const PSID security_local_user_sid;
|
extern const struct sid local_user_sid;
|
||||||
extern const PSID security_local_system_sid;
|
extern const struct sid local_system_sid;
|
||||||
extern const PSID security_builtin_users_sid;
|
extern const struct sid builtin_users_sid;
|
||||||
extern const PSID security_builtin_admins_sid;
|
extern const struct sid builtin_admins_sid;
|
||||||
extern const PSID security_domain_users_sid;
|
extern const struct sid domain_users_sid;
|
||||||
extern const PSID security_high_label_sid;
|
extern const struct sid high_label_sid;
|
||||||
|
|
||||||
struct ace
|
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 *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 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,
|
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
|
||||||
int impersonation_level, const struct security_descriptor *sd,
|
int impersonation_level, const struct security_descriptor *sd,
|
||||||
const struct luid_attr *remove_privs, unsigned int remove_priv_count,
|
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,
|
extern int token_check_privileges( struct token *token, int all_required,
|
||||||
const struct luid_attr *reqprivs,
|
const struct luid_attr *reqprivs,
|
||||||
unsigned int count, struct luid_attr *usedprivs );
|
unsigned int count, struct luid_attr *usedprivs );
|
||||||
extern const struct acl *token_get_default_dacl( struct token *token );
|
extern const struct acl *token_get_default_dacl( struct token *token );
|
||||||
extern const SID *token_get_user( struct token *token );
|
extern const struct sid *token_get_user( struct token *token );
|
||||||
extern const SID *token_get_primary_group( 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 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 )
|
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);
|
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) &&
|
return ((sid1->sub_count == sid2->sub_count) && !memcmp( sid1, sid2, sid_len( sid1 )));
|
||||||
!memcmp( sid1, sid2, security_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 )
|
unsigned char flags, unsigned int mask )
|
||||||
{
|
{
|
||||||
ace->type = type;
|
ace->type = type;
|
||||||
ace->flags = flags;
|
ace->flags = flags;
|
||||||
ace->size = sizeof(*ace) + security_sid_len( sid );
|
ace->size = sizeof(*ace) + sid_len( sid );
|
||||||
ace->mask = mask;
|
ace->mask = mask;
|
||||||
memcpy( ace + 1, sid, security_sid_len( sid ));
|
memcpy( ace + 1, sid, sid_len( sid ));
|
||||||
return ace;
|
return ace;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void security_set_thread_token( struct thread *thread, obj_handle_t handle );
|
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 );
|
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 )
|
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 */
|
/* 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)
|
if (sd->owner_len)
|
||||||
return (const SID *)(sd + 1);
|
return (const struct sid *)(sd + 1);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gets the primary group from a security descriptor */
|
/* 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)
|
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
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
286
server/token.c
286
server/token.c
|
@ -66,38 +66,23 @@ const struct luid SeCreateGlobalPrivilege = { 30, 0 };
|
||||||
|
|
||||||
struct sid_attrs
|
struct sid_attrs
|
||||||
{
|
{
|
||||||
const SID *sid;
|
const struct sid *sid;
|
||||||
unsigned int attrs;
|
unsigned int attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SID_N(n) struct /* same fields as struct SID */ \
|
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 } };
|
||||||
BYTE Revision; \
|
const struct sid high_label_sid = { SID_REVISION, 1, SECURITY_MANDATORY_LABEL_AUTHORITY, { SECURITY_MANDATORY_HIGH_RID } };
|
||||||
BYTE SubAuthorityCount; \
|
const struct sid local_user_sid = { SID_REVISION, 5, SECURITY_NT_AUTHORITY, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, 1000 } };
|
||||||
SID_IDENTIFIER_AUTHORITY IdentifierAuthority; \
|
const struct sid builtin_admins_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } };
|
||||||
DWORD SubAuthority[n]; \
|
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 struct sid local_sid = { SID_REVISION, 1, SECURITY_LOCAL_SID_AUTHORITY, { SECURITY_LOCAL_RID } };
|
||||||
static const 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 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 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 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 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 struct luid prev_luid_value = { 1000, 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 luid modified_id; /* new id allocated every time token is modified */
|
||||||
struct list privileges; /* privileges available to the token */
|
struct list privileges; /* privileges available to the token */
|
||||||
struct list groups; /* groups that the user of this token belongs to (sid_and_attributes) */
|
struct list groups; /* groups that the user of this token belongs to (sid_and_attributes) */
|
||||||
SID *user; /* SID of user this token represents */
|
struct sid *user; /* SID of user this token represents */
|
||||||
SID *owner; /* SID of owner (points to user or one of groups) */
|
struct 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 *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 primary; /* is this a primary or impersonation token? */
|
||||||
unsigned int session_id; /* token session id */
|
unsigned int session_id; /* token session id */
|
||||||
struct acl *default_dacl; /* the default DACL to assign to objects created by this user */
|
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 impersonation_level; /* impersonation level this token is capable of if non-primary token */
|
||||||
int elevation; /* elevation type */
|
int elevation; /* elevation type */
|
||||||
};
|
};
|
||||||
|
@ -152,7 +136,7 @@ struct group
|
||||||
unsigned owner : 1; /* can this sid be an owner of an object? */
|
unsigned owner : 1; /* can this sid be an owner of an object? */
|
||||||
unsigned resource : 1; /* is this a domain-local group? */
|
unsigned resource : 1; /* is this a domain-local group? */
|
||||||
unsigned 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;
|
struct sid sid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void token_dump( struct object *obj, int verbose );
|
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 );
|
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 )
|
void security_set_thread_token( struct thread *thread, obj_handle_t handle )
|
||||||
{
|
{
|
||||||
if (!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 */
|
/* very simple mapping: either the current user or not the current user */
|
||||||
if (uid == getuid())
|
if (uid == getuid())
|
||||||
return (const SID *)&local_user_sid;
|
return &local_user_sid;
|
||||||
else
|
else
|
||||||
return &anonymous_logon_sid;
|
return &anonymous_logon_sid;
|
||||||
}
|
}
|
||||||
|
@ -260,21 +231,20 @@ static int acl_is_valid( const struct acl *acl, data_size_t size )
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
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;
|
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;
|
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 );
|
size -= sid_len( sid );
|
||||||
sid = (const SID *)((char *)sid + security_sid_len( sid ));
|
sid = (const struct sid *)((char *)sid + sid_len( sid ));
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
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 )
|
int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
|
||||||
{
|
{
|
||||||
size_t offset = sizeof(struct security_descriptor);
|
size_t offset = sizeof(struct security_descriptor);
|
||||||
const SID *group;
|
const struct sid *group;
|
||||||
const SID *owner;
|
const struct sid *owner;
|
||||||
const struct acl *sacl;
|
const struct acl *sacl;
|
||||||
const struct acl *dacl;
|
const struct acl *dacl;
|
||||||
int dummy;
|
int dummy;
|
||||||
|
@ -292,27 +262,15 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
|
||||||
if (size < offset)
|
if (size < offset)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((sd->owner_len >= FIELD_OFFSET(SID, SubAuthority[255])) ||
|
if (sd->owner_len >= offsetof(struct sid, sub_auth[255]) || offset + sd->owner_len > size) return FALSE;
|
||||||
(offset + sd->owner_len > size))
|
|
||||||
return FALSE;
|
|
||||||
owner = sd_get_owner( sd );
|
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;
|
offset += sd->owner_len;
|
||||||
|
if (owner && !sid_valid_size( owner, sd->owner_len )) return FALSE;
|
||||||
|
|
||||||
if ((sd->group_len >= FIELD_OFFSET(SID, SubAuthority[255])) ||
|
if (sd->group_len >= offsetof(struct sid, sub_auth[255]) || offset + sd->group_len > size) return FALSE;
|
||||||
(offset + sd->group_len > size))
|
|
||||||
return FALSE;
|
|
||||||
group = sd_get_group( sd );
|
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;
|
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))
|
if ((sd->sacl_len >= MAX_ACL_LEN) || (offset + sd->sacl_len > size))
|
||||||
return FALSE;
|
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
|
* modified_id may be NULL, indicating that a new modified_id luid should be
|
||||||
* allocated.
|
* 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 sid_attrs *groups, unsigned int group_count,
|
||||||
const struct luid_attr *privs, unsigned int priv_count,
|
const struct luid_attr *privs, unsigned int priv_count,
|
||||||
const struct acl *default_dacl, TOKEN_SOURCE source,
|
const struct acl *default_dacl, const struct luid *modified_id,
|
||||||
const struct luid *modified_id,
|
|
||||||
int impersonation_level, int elevation )
|
int impersonation_level, int elevation )
|
||||||
{
|
{
|
||||||
struct token *token = alloc_object( &token_ops );
|
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;
|
token->elevation = elevation;
|
||||||
|
|
||||||
/* copy user */
|
/* copy user */
|
||||||
token->user = memdup( user, security_sid_len( user ));
|
token->user = memdup( user, sid_len( user ));
|
||||||
if (!token->user)
|
if (!token->user)
|
||||||
{
|
{
|
||||||
release_object( token );
|
release_object( token );
|
||||||
|
@ -558,7 +515,7 @@ static struct token *create_token( unsigned int primary, unsigned int session_id
|
||||||
/* copy groups */
|
/* copy groups */
|
||||||
for (i = 0; i < group_count; i++)
|
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 );
|
struct group *group = mem_alloc( size );
|
||||||
|
|
||||||
if (!group)
|
if (!group)
|
||||||
|
@ -566,7 +523,7 @@ static struct token *create_token( unsigned int primary, unsigned int session_id
|
||||||
release_object( token );
|
release_object( token );
|
||||||
return NULL;
|
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->enabled = TRUE;
|
||||||
group->def = TRUE;
|
group->def = TRUE;
|
||||||
group->logon = (groups[i].attrs & SE_GROUP_LOGON_ID) != 0;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token->source = source;
|
|
||||||
}
|
}
|
||||||
return token;
|
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;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (security_equal_sid( &group->sid, filter )) return 1;
|
if (equal_sid( &group->sid, filter )) return 1;
|
||||||
filter = (const SID *)((char *)filter + security_sid_len( filter ));
|
filter = (const struct sid *)((char *)filter + sid_len( filter ));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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,
|
struct token *token_duplicate( struct token *src_token, unsigned primary,
|
||||||
int impersonation_level, const struct security_descriptor *sd,
|
int impersonation_level, const struct security_descriptor *sd,
|
||||||
const struct luid_attr *remove_privs, unsigned int remove_priv_count,
|
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 =
|
const struct luid *modified_id =
|
||||||
primary || (impersonation_level == src_token->impersonation_level) ?
|
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,
|
token = create_token( primary, src_token->session_id, src_token->user, NULL, 0,
|
||||||
NULL, 0, src_token->default_dacl,
|
NULL, 0, src_token->default_dacl, modified_id,
|
||||||
src_token->source, modified_id,
|
|
||||||
impersonation_level, src_token->elevation );
|
impersonation_level, src_token->elevation );
|
||||||
if (!token) return token;
|
if (!token) return token;
|
||||||
|
|
||||||
|
@ -664,7 +618,7 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
|
||||||
token->primary_group = NULL;
|
token->primary_group = NULL;
|
||||||
LIST_FOR_EACH_ENTRY( group, &src_token->groups, struct group, entry )
|
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 );
|
struct group *newgroup = mem_alloc( size );
|
||||||
if (!newgroup)
|
if (!newgroup)
|
||||||
{
|
{
|
||||||
|
@ -704,12 +658,12 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
|
||||||
return token;
|
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 ace *ace;
|
||||||
struct acl *default_dacl;
|
struct acl *default_dacl;
|
||||||
size_t default_dacl_size = sizeof(*default_dacl) + 2 * sizeof(*ace) +
|
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 );
|
default_dacl = mem_alloc( default_dacl_size );
|
||||||
if (!default_dacl) return NULL;
|
if (!default_dacl) return NULL;
|
||||||
|
@ -735,13 +689,13 @@ struct sid_data
|
||||||
unsigned int subauth[MAX_SUBAUTH_COUNT];
|
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 security_descriptor *sd;
|
||||||
struct acl *sacl;
|
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;
|
sd_size = sizeof(struct security_descriptor) + sacl_size;
|
||||||
if (!(sd = mem_alloc( sd_size )))
|
if (!(sd = mem_alloc( sd_size )))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -765,7 +719,7 @@ static struct security_descriptor *create_security_label_sd( struct token *token
|
||||||
return sd;
|
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;
|
struct security_descriptor *sd;
|
||||||
int ret = 0;
|
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_create_admin( unsigned primary, int impersonation_level, int elevation, unsigned int session_id )
|
||||||
{
|
{
|
||||||
struct token *token = NULL;
|
struct token *token = NULL;
|
||||||
static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY };
|
struct sid alias_admins_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS }};
|
||||||
static const unsigned int alias_admins_subauth[] = { 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 }};
|
||||||
static const unsigned int alias_users_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS };
|
|
||||||
/* on Windows, this value changes every time the user logs on */
|
/* 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 */ };
|
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 */ }};
|
||||||
PSID alias_admins_sid;
|
const struct sid *user_sid = security_unix_uid_to_sid( getuid() );
|
||||||
PSID alias_users_sid;
|
|
||||||
PSID logon_sid;
|
|
||||||
const SID *user_sid = security_unix_uid_to_sid( getuid() );
|
|
||||||
struct acl *default_dacl = create_default_dacl( user_sid );
|
struct acl *default_dacl = create_default_dacl( user_sid );
|
||||||
|
const struct luid_attr admin_privs[] =
|
||||||
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[] =
|
{ SeChangeNotifyPrivilege, SE_PRIVILEGE_ENABLED },
|
||||||
{
|
{ SeTcbPrivilege, 0 },
|
||||||
{ SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED },
|
{ SeSecurityPrivilege, 0 },
|
||||||
{ SeTcbPrivilege , 0 },
|
{ SeBackupPrivilege, 0 },
|
||||||
{ SeSecurityPrivilege , 0 },
|
{ SeRestorePrivilege, 0 },
|
||||||
{ SeBackupPrivilege , 0 },
|
{ SeSystemtimePrivilege, 0 },
|
||||||
{ SeRestorePrivilege , 0 },
|
{ SeShutdownPrivilege, 0 },
|
||||||
{ SeSystemtimePrivilege , 0 },
|
{ SeRemoteShutdownPrivilege, 0 },
|
||||||
{ SeShutdownPrivilege , 0 },
|
{ SeTakeOwnershipPrivilege, 0 },
|
||||||
{ SeRemoteShutdownPrivilege , 0 },
|
{ SeDebugPrivilege, 0 },
|
||||||
{ SeTakeOwnershipPrivilege , 0 },
|
{ SeSystemEnvironmentPrivilege, 0 },
|
||||||
{ SeDebugPrivilege , 0 },
|
{ SeSystemProfilePrivilege, 0 },
|
||||||
{ SeSystemEnvironmentPrivilege , 0 },
|
{ SeProfileSingleProcessPrivilege, 0 },
|
||||||
{ SeSystemProfilePrivilege , 0 },
|
{ SeIncreaseBasePriorityPrivilege, 0 },
|
||||||
{ SeProfileSingleProcessPrivilege, 0 },
|
{ SeLoadDriverPrivilege, SE_PRIVILEGE_ENABLED },
|
||||||
{ SeIncreaseBasePriorityPrivilege, 0 },
|
{ SeCreatePagefilePrivilege, 0 },
|
||||||
{ SeLoadDriverPrivilege , SE_PRIVILEGE_ENABLED },
|
{ SeIncreaseQuotaPrivilege, 0 },
|
||||||
{ SeCreatePagefilePrivilege , 0 },
|
{ SeUndockPrivilege, 0 },
|
||||||
{ SeIncreaseQuotaPrivilege , 0 },
|
{ SeManageVolumePrivilege, 0 },
|
||||||
{ SeUndockPrivilege , 0 },
|
{ SeImpersonatePrivilege, SE_PRIVILEGE_ENABLED },
|
||||||
{ SeManageVolumePrivilege , 0 },
|
{ SeCreateGlobalPrivilege, SE_PRIVILEGE_ENABLED },
|
||||||
{ 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 */
|
||||||
/* note: we don't include non-builtin groups here for the user -
|
const struct sid_attrs admin_groups[] =
|
||||||
* 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 },
|
||||||
{ &world_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 },
|
||||||
{ &local_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 },
|
||||||
{ &interactive_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 },
|
||||||
{ &authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
|
{ &alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER },
|
||||||
{ (SID *)&domain_users_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 },
|
||||||
{ alias_admins_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER },
|
{ &logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID },
|
||||||
{ 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 ),
|
||||||
static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
|
admin_privs, ARRAY_SIZE( admin_privs ), default_dacl,
|
||||||
token = create_token( primary, session_id, user_sid, admin_groups, ARRAY_SIZE( admin_groups ),
|
NULL, impersonation_level, elevation );
|
||||||
admin_privs, ARRAY_SIZE( admin_privs ), default_dacl,
|
/* we really need a primary group */
|
||||||
admin_source, NULL, impersonation_level, elevation );
|
assert( token->primary_group );
|
||||||
/* we really need a primary group */
|
|
||||||
assert( token->primary_group );
|
|
||||||
}
|
|
||||||
|
|
||||||
free( logon_sid );
|
|
||||||
free( alias_admins_sid );
|
|
||||||
free( alias_users_sid );
|
|
||||||
free( default_dacl );
|
free( default_dacl );
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,18 +880,17 @@ int token_check_privileges( struct token *token, int all_required, const struct
|
||||||
return (enabled_count > 0);
|
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;
|
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 )
|
LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry )
|
||||||
{
|
{
|
||||||
if (!group->enabled) continue;
|
if (!group->enabled) continue;
|
||||||
if (group->deny_only && !deny) continue;
|
if (group->deny_only && !deny) continue;
|
||||||
|
if (equal_sid( &group->sid, sid )) return TRUE;
|
||||||
if (security_equal_sid( &group->sid, sid )) return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -982,7 +917,7 @@ static unsigned int token_access_check( struct token *token,
|
||||||
const struct acl *dacl;
|
const struct acl *dacl;
|
||||||
int dacl_present;
|
int dacl_present;
|
||||||
const struct ace *ace;
|
const struct ace *ace;
|
||||||
const SID *owner;
|
const struct sid *owner;
|
||||||
|
|
||||||
/* assume no access rights */
|
/* assume no access rights */
|
||||||
*granted_access = 0;
|
*granted_access = 0;
|
||||||
|
@ -1068,7 +1003,7 @@ static unsigned int token_access_check( struct token *token,
|
||||||
/* 4: Grant rights according to the DACL */
|
/* 4: Grant rights according to the DACL */
|
||||||
for (i = 0, ace = ace_first( dacl ); i < dacl->count; i++, ace = ace_next( ace ))
|
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;
|
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;
|
return token->default_dacl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SID *token_get_user( struct token *token )
|
const struct sid *token_get_user( struct token *token )
|
||||||
{
|
{
|
||||||
return token->user;
|
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;
|
return token->primary_group;
|
||||||
}
|
}
|
||||||
|
@ -1311,11 +1246,11 @@ DECL_HANDLER(filter_token)
|
||||||
{
|
{
|
||||||
const struct luid_attr *filter_privileges = get_req_data();
|
const struct luid_attr *filter_privileges = get_req_data();
|
||||||
unsigned int priv_count, group_count;
|
unsigned int priv_count, group_count;
|
||||||
const SID *filter_groups;
|
const struct sid *filter_groups;
|
||||||
struct token *token;
|
struct token *token;
|
||||||
|
|
||||||
priv_count = min( req->privileges_size, get_req_data_size() ) / sizeof(struct luid_attr);
|
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) );
|
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,
|
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 )))
|
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)
|
switch (req->which_sid)
|
||||||
{
|
{
|
||||||
|
@ -1433,7 +1368,7 @@ DECL_HANDLER(get_token_sid)
|
||||||
sid = token->owner;
|
sid = token->owner;
|
||||||
break;
|
break;
|
||||||
case TokenLogonSid:
|
case TokenLogonSid:
|
||||||
sid = (const SID *)&builtin_logon_sid;
|
sid = &builtin_logon_sid;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
set_error( STATUS_INVALID_PARAMETER );
|
||||||
|
@ -1442,7 +1377,7 @@ DECL_HANDLER(get_token_sid)
|
||||||
|
|
||||||
if (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 );
|
if (reply->sid_len <= get_reply_max_size()) set_reply_data( sid, reply->sid_len );
|
||||||
else set_error( STATUS_BUFFER_TOO_SMALL );
|
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 )
|
LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
|
||||||
{
|
{
|
||||||
group_count++;
|
group_count++;
|
||||||
sid_size += security_sid_len( &group->sid );
|
sid_size += sid_len( &group->sid );
|
||||||
}
|
}
|
||||||
size_needed += sid_size;
|
size_needed += sid_size;
|
||||||
/* attributes size */
|
/* attributes size */
|
||||||
|
@ -1491,7 +1426,7 @@ DECL_HANDLER(get_token_groups)
|
||||||
if (tg)
|
if (tg)
|
||||||
{
|
{
|
||||||
unsigned int *attr_ptr = (unsigned int *)(tg + 1);
|
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;
|
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->deny_only) *attr_ptr |= SE_GROUP_USE_FOR_DENY_ONLY;
|
||||||
if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
|
if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
|
||||||
if (group->logon) *attr_ptr |= SE_GROUP_LOGON_ID;
|
if (group->logon) *attr_ptr |= SE_GROUP_LOGON_ID;
|
||||||
|
sid = copy_sid( sid, &group->sid );
|
||||||
memcpy(sid_ptr, &group->sid, security_sid_len( &group->sid ));
|
|
||||||
|
|
||||||
sid_ptr = (SID *)((char *)sid_ptr + security_sid_len( &group->sid ));
|
|
||||||
attr_ptr++;
|
attr_ptr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1016,33 +1016,27 @@ static void dump_varargs_luid_attr( const char *prefix, data_size_t size )
|
||||||
remove_data( 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;
|
DWORD i;
|
||||||
|
|
||||||
/* security check */
|
fprintf( stderr,"%s", prefix );
|
||||||
if ((FIELD_OFFSET(SID, SubAuthority[0]) > size) ||
|
if (sid_valid_size( sid, size ))
|
||||||
(FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) > size))
|
|
||||||
{
|
{
|
||||||
fprintf( stderr, "<invalid sid>" );
|
fprintf( stderr, "S-%u-%u", sid->revision,
|
||||||
return;
|
((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] );
|
||||||
}
|
}
|
||||||
|
else fprintf( stderr, "<invalid>" );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
const struct sid *sid = cur_data;
|
||||||
dump_inline_sid( prefix, sid, size );
|
if (size) dump_inline_sid( prefix, sid, size );
|
||||||
remove_data( 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);
|
size -= sizeof(*acl);
|
||||||
for (i = 0, ace = ace_first( acl ); i < acl->count; i++, ace = ace_next( ace ))
|
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;
|
data_size_t sid_size;
|
||||||
|
|
||||||
if (size < sizeof(*ace) || size < ace->size) break;
|
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);
|
size_t offset = sizeof(struct security_descriptor);
|
||||||
fprintf( stderr, "control=%08x", sd->control );
|
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;
|
return;
|
||||||
if (sd->owner_len)
|
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
|
else
|
||||||
fprintf( stderr, ",owner=<not present>" );
|
fprintf( stderr, ",owner=<not present>" );
|
||||||
offset += sd->owner_len;
|
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;
|
return;
|
||||||
if (sd->group_len)
|
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
|
else
|
||||||
fprintf( stderr, ",group=<not present>" );
|
fprintf( stderr, ",group=<not present>" );
|
||||||
offset += sd->group_len;
|
offset += sd->group_len;
|
||||||
|
@ -1156,16 +1150,14 @@ static void dump_varargs_token_groups( const char *prefix, data_size_t size )
|
||||||
fputc( '[', stderr );
|
fputc( '[', stderr );
|
||||||
for (i = 0; i < tg->count; i++)
|
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)
|
if (i != 0)
|
||||||
fputc( ',', stderr );
|
fputc( ',', stderr );
|
||||||
fputc( '{', stderr );
|
fputc( '{', stderr );
|
||||||
fprintf( stderr, "attributes=%08x", attr[i] );
|
fprintf( stderr, "attributes=%08x", attr[i] );
|
||||||
dump_inline_sid( ",sid=", sid, size - offset );
|
dump_inline_sid( ",sid=", sid, size - offset );
|
||||||
if ((offset + FIELD_OFFSET(SID, SubAuthority[0]) > size) ||
|
if (!sid_valid_size( sid, size - offset )) break;
|
||||||
(offset + FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) > size))
|
offset += sid_len( sid );
|
||||||
break;
|
|
||||||
offset += FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
|
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
}
|
}
|
||||||
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, ", flags=%08x", req->flags );
|
||||||
fprintf( stderr, ", privileges_size=%u", req->privileges_size );
|
fprintf( stderr, ", privileges_size=%u", req->privileges_size );
|
||||||
dump_varargs_luid_attr( ", privileges=", min(cur_size,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 )
|
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 )
|
static void dump_get_token_sid_reply( const struct get_token_sid_reply *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " sid_len=%u", req->sid_len );
|
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 )
|
static void dump_get_token_groups_request( const struct get_token_groups_request *req )
|
||||||
|
|
Loading…
Reference in New Issue