Commit c36f81fa authored by Alexandre Julliard's avatar Alexandre Julliard

server: Define a server-side structure for ACL.

parent bf3442fa
......@@ -376,6 +376,15 @@ struct luid_attr
unsigned int attrs;
};
struct acl
{
unsigned char revision;
unsigned char pad1;
unsigned short size;
unsigned short count;
unsigned short pad2;
};
typedef struct
{
unsigned int read;
......@@ -4467,7 +4476,7 @@ struct get_token_default_dacl_reply
{
struct reply_header __header;
data_size_t acl_len;
/* VARARG(acl,ACL); */
/* VARARG(acl,acl); */
char __pad_12[4];
};
......@@ -4475,7 +4484,7 @@ struct set_token_default_dacl_request
{
struct request_header __header;
obj_handle_t handle;
/* VARARG(acl,ACL); */
/* VARARG(acl,acl); */
};
struct set_token_default_dacl_reply
{
......@@ -6252,7 +6261,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 740
#define SERVER_PROTOCOL_VERSION 741
/* ### protocol_version end ### */
......
......@@ -312,13 +312,13 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
size_t dacl_size;
ACE_HEADER *current_ace;
ACCESS_ALLOWED_ACE *aaa;
ACL *dacl;
struct acl *dacl;
SID *sid;
char *ptr;
const SID *world_sid = security_world_sid;
const SID *local_system_sid = security_local_system_sid;
dacl_size = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
dacl_size = sizeof(*dacl) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
security_sid_len( local_system_sid );
if (mode & S_IRWXU)
dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + security_sid_len( user );
......@@ -346,16 +346,18 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
memcpy( ptr, group, sd->group_len );
ptr += sd->group_len;
dacl = (ACL *)ptr;
dacl->AclRevision = ACL_REVISION;
dacl->Sbz1 = 0;
dacl->AclSize = dacl_size;
dacl->AceCount = 1 + (mode & S_IRWXU ? 1 : 0) + (mode & S_IRWXO ? 1 : 0);
dacl = (struct acl *)ptr;
dacl->revision = ACL_REVISION;
dacl->pad1 = 0;
dacl->size = dacl_size;
dacl->count = 1;
dacl->pad2 = 0;
if (mode & S_IRWXU) dacl->count++;
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->AceCount++;
dacl->Sbz2 = 0;
dacl->count++;
if (mode & S_IRWXO) dacl->count++;
/* always give FILE_ALL_ACCESS for Local System */
aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
......@@ -470,12 +472,12 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
mode_t bits_to_set = ~0;
mode_t mode;
int present;
const ACL *dacl = sd_get_dacl( sd, &present );
const struct acl *dacl = sd_get_dacl( sd, &present );
if (present && dacl)
{
const ACE_HEADER *ace = (const ACE_HEADER *)(dacl + 1);
ULONG i;
for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace ))
for (i = 0; i < dacl->count; i++, ace = ace_next( ace ))
{
const ACCESS_ALLOWED_ACE *aa_ace;
const ACCESS_DENIED_ACE *ad_ace;
......
......@@ -738,8 +738,8 @@ DECL_HANDLER(get_security_object)
struct security_descriptor req_sd;
int present;
const SID *owner, *group;
const ACL *sacl, *dacl;
ACL *label_acl = NULL;
const struct acl *sacl, *dacl;
struct acl *label_acl = NULL;
if (req->security_info & SACL_SECURITY_INFORMATION)
access |= ACCESS_SYSTEM_SECURITY;
......@@ -769,7 +769,7 @@ DECL_HANDLER(get_security_object)
else if (req->security_info & LABEL_SECURITY_INFORMATION && present && sacl)
{
if (!(label_acl = extract_security_labels( sacl ))) goto done;
req_sd.sacl_len = label_acl->AclSize;
req_sd.sacl_len = label_acl->size;
sacl = label_acl;
}
else
......
......@@ -544,8 +544,8 @@ 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 ACL *sacl, *dacl;
ACL *replaced_sacl = NULL;
const struct acl *sacl, *dacl;
struct acl *replaced_sacl = NULL;
char *ptr;
if (!set_info) return 1;
......@@ -594,11 +594,11 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
}
else if (set_info & LABEL_SECURITY_INFORMATION && present)
{
const ACL *old_sacl = NULL;
const struct acl *old_sacl = NULL;
if (obj->sd && obj->sd->control & SE_SACL_PRESENT) old_sacl = sd_get_sacl( obj->sd, &present );
if (!(replaced_sacl = replace_security_labels( old_sacl, sacl ))) return 0;
new_sd.control |= SE_SACL_PRESENT;
new_sd.sacl_len = replaced_sacl->AclSize;
new_sd.sacl_len = replaced_sacl->size;
sacl = replaced_sacl;
}
else
......@@ -633,7 +633,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri
{
dacl = token_get_default_dacl( token );
new_sd.control |= SE_DACL_PRESENT;
new_sd.dacl_len = dacl->AclSize;
new_sd.dacl_len = dacl->size;
}
else new_sd.dacl_len = 0;
}
......
......@@ -825,10 +825,10 @@ static struct security_descriptor *process_get_sd( struct object *obj )
{
size_t users_sid_len = security_sid_len( security_domain_users_sid );
size_t admins_sid_len = security_sid_len( security_builtin_admins_sid );
size_t dacl_len = sizeof(ACL) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart )
size_t dacl_len = sizeof(struct acl) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart )
+ users_sid_len + admins_sid_len;
ACCESS_ALLOWED_ACE *aaa;
ACL *dacl;
struct acl *dacl;
process_default_sd = mem_alloc( sizeof(*process_default_sd) + admins_sid_len + users_sid_len
+ dacl_len );
......@@ -840,12 +840,12 @@ static struct security_descriptor *process_get_sd( struct object *obj )
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 );
dacl = (ACL *)((char *)(process_default_sd + 1) + admins_sid_len + users_sid_len);
dacl->AclRevision = ACL_REVISION;
dacl->Sbz1 = 0;
dacl->AclSize = dacl_len;
dacl->AceCount = 2;
dacl->Sbz2 = 0;
dacl = (struct acl *)((char *)(process_default_sd + 1) + admins_sid_len + users_sid_len);
dacl->revision = ACL_REVISION;
dacl->pad1 = 0;
dacl->size = dacl_len;
dacl->count = 2;
dacl->pad2 = 0;
aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE;
......
......@@ -392,6 +392,15 @@ struct luid_attr
unsigned int attrs;
};
struct acl
{
unsigned char revision;
unsigned char pad1;
unsigned short size;
unsigned short count;
unsigned short pad2;
};
typedef struct
{
unsigned int read;
......@@ -411,8 +420,8 @@ struct security_descriptor
data_size_t dacl_len;
/* VARARG(owner,SID); */
/* VARARG(group,SID); */
/* VARARG(sacl,ACL); */
/* VARARG(dacl,ACL); */
/* VARARG(sacl,acl); */
/* VARARG(dacl,acl); */
};
struct object_attributes
......@@ -3165,12 +3174,12 @@ enum caret_state
obj_handle_t handle; /* handle to the token */
@REPLY
data_size_t acl_len; /* length needed to store access control list */
VARARG(acl,ACL); /* access control list */
VARARG(acl,acl); /* access control list */
@END
@REQ(set_token_default_dacl)
obj_handle_t handle; /* handle to the token */
VARARG(acl,ACL); /* default dacl to set */
VARARG(acl,acl); /* default dacl to set */
@END
@REQ(set_security_object)
......
......@@ -369,12 +369,12 @@ static struct security_descriptor *key_get_sd( struct object *obj )
if (!key_default_sd)
{
struct acl *dacl;
size_t users_sid_len = security_sid_len( security_builtin_users_sid );
size_t admins_sid_len = security_sid_len( security_builtin_admins_sid );
size_t dacl_len = sizeof(ACL) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart )
size_t dacl_len = sizeof(*dacl) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart )
+ users_sid_len + admins_sid_len;
ACCESS_ALLOWED_ACE *aaa;
ACL *dacl;
key_default_sd = mem_alloc( sizeof(*key_default_sd) + 2 * admins_sid_len + dacl_len );
key_default_sd->control = SE_DACL_PRESENT;
......@@ -385,12 +385,12 @@ static struct security_descriptor *key_get_sd( struct object *obj )
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 );
dacl = (ACL *)((char *)(key_default_sd + 1) + 2 * admins_sid_len);
dacl->AclRevision = ACL_REVISION;
dacl->Sbz1 = 0;
dacl->AclSize = dacl_len;
dacl->AceCount = 2;
dacl->Sbz2 = 0;
dacl = (struct acl *)((char *)(key_default_sd + 1) + 2 * admins_sid_len);
dacl->revision = ACL_REVISION;
dacl->pad1 = 0;
dacl->size = dacl_len;
dacl->count = 2;
dacl->pad2 = 0;
aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
aaa->Header.AceFlags = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE;
......
......@@ -65,7 +65,7 @@ extern struct token *token_duplicate( struct token *src_token, unsigned primary,
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 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 SID *token_get_primary_group( struct token *token );
extern unsigned int token_get_session_id( struct token *token );
......@@ -105,28 +105,28 @@ static inline int thread_single_check_privilege( struct thread *thread, struct l
/* security descriptor helper functions */
extern int sd_is_valid( const struct security_descriptor *sd, data_size_t size );
extern ACL *extract_security_labels( const ACL *sacl );
extern ACL *replace_security_labels( const ACL *old_sacl, const ACL *new_sacl );
extern struct acl *extract_security_labels( const struct acl *sacl );
extern struct acl *replace_security_labels( const struct acl *old_sacl, const struct acl *new_sacl );
/* gets the discretionary access control list from a security descriptor */
static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present )
static inline const struct acl *sd_get_dacl( const struct security_descriptor *sd, int *present )
{
*present = (sd->control & SE_DACL_PRESENT) != 0;
if (sd->dacl_len)
return (const ACL *)((const char *)(sd + 1) +
return (const struct acl *)((const char *)(sd + 1) +
sd->owner_len + sd->group_len + sd->sacl_len);
else
return NULL;
}
/* gets the system access control list from a security descriptor */
static inline const ACL *sd_get_sacl( const struct security_descriptor *sd, int *present )
static inline const struct acl *sd_get_sacl( const struct security_descriptor *sd, int *present )
{
*present = (sd->control & SE_SACL_PRESENT) != 0;
if (sd->sacl_len)
return (const ACL *)((const char *)(sd + 1) +
return (const struct acl *)((const char *)(sd + 1) +
sd->owner_len + sd->group_len);
else
return NULL;
......
......@@ -1045,7 +1045,7 @@ static void dump_varargs_SID( const char *prefix, data_size_t size )
remove_data( size );
}
static void dump_inline_acl( const char *prefix, const ACL *acl, data_size_t size )
static void dump_inline_acl( const char *prefix, const struct acl *acl, data_size_t size )
{
const ACE_HEADER *ace;
ULONG i;
......@@ -1053,14 +1053,14 @@ static void dump_inline_acl( const char *prefix, const ACL *acl, data_size_t siz
fprintf( stderr,"%s{", prefix );
if (size)
{
if (size < sizeof(ACL))
if (size < sizeof(*acl))
{
fprintf( stderr, "<invalid acl>}" );
return;
}
size -= sizeof(ACL);
size -= sizeof(*acl);
ace = (const ACE_HEADER *)(acl + 1);
for (i = 0; i < acl->AceCount; i++)
for (i = 0; i < acl->count; i++)
{
const SID *sid = NULL;
data_size_t sid_size = 0;
......@@ -1115,9 +1115,9 @@ static void dump_inline_acl( const char *prefix, const ACL *acl, data_size_t siz
fputc( '}', stderr );
}
static void dump_varargs_ACL( const char *prefix, data_size_t size )
static void dump_varargs_acl( const char *prefix, data_size_t size )
{
const ACL *acl = cur_data;
const struct acl *acl = cur_data;
dump_inline_acl( prefix, acl, size );
remove_data( size );
}
......@@ -1145,11 +1145,11 @@ static void dump_inline_security_descriptor( const char *prefix, const struct se
offset += sd->group_len;
if ((sd->sacl_len >= MAX_ACL_LEN) || (offset + sd->sacl_len > size))
return;
dump_inline_acl( ",sacl=", (const ACL *)((const char *)sd + offset), sd->sacl_len );
dump_inline_acl( ",sacl=", (const struct acl *)((const char *)sd + offset), sd->sacl_len );
offset += sd->sacl_len;
if ((sd->dacl_len >= MAX_ACL_LEN) || (offset + sd->dacl_len > size))
return;
dump_inline_acl( ",dacl=", (const ACL *)((const char *)sd + offset), sd->dacl_len );
dump_inline_acl( ",dacl=", (const struct acl *)((const char *)sd + offset), sd->dacl_len );
offset += sd->dacl_len;
}
fputc( '}', stderr );
......@@ -3914,13 +3914,13 @@ static void dump_get_token_default_dacl_request( const struct get_token_default_
static void dump_get_token_default_dacl_reply( const struct get_token_default_dacl_reply *req )
{
fprintf( stderr, " acl_len=%u", req->acl_len );
dump_varargs_ACL( ", acl=", cur_size );
dump_varargs_acl( ", acl=", cur_size );
}
static void dump_set_token_default_dacl_request( const struct set_token_default_dacl_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
dump_varargs_ACL( ", acl=", cur_size );
dump_varargs_acl( ", acl=", cur_size );
}
static void dump_set_security_object_request( const struct set_security_object_request *req )
......@@ -5400,6 +5400,7 @@ static const struct
{ "INFO_LENGTH_MISMATCH", STATUS_INFO_LENGTH_MISMATCH },
{ "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE },
{ "INSUFFICIENT_RESOURCES", STATUS_INSUFFICIENT_RESOURCES },
{ "INVALID_ACL", STATUS_INVALID_ACL },
{ "INVALID_ADDRESS", STATUS_INVALID_ADDRESS },
{ "INVALID_ADDRESS_COMPONENT", STATUS_INVALID_ADDRESS_COMPONENT },
{ "INVALID_CID", STATUS_INVALID_CID },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment