|
|
60ddd3 |
/********************************************************/
|
|
|
60ddd3 |
/* ntapi: Native API core library */
|
|
|
60ddd3 |
/* Copyright (C) 2013--2017 Z. Gilboa */
|
|
|
60ddd3 |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
60ddd3 |
/********************************************************/
|
|
|
60ddd3 |
|
|
|
60ddd3 |
#include <psxtypes/psxtypes.h>
|
|
|
60ddd3 |
#include <ntapi/nt_status.h>
|
|
|
60ddd3 |
#include <ntapi/nt_object.h>
|
|
|
60ddd3 |
#include <ntapi/nt_acl.h>
|
|
|
60ddd3 |
#include "ntapi_impl.h"
|
|
|
60ddd3 |
|
|
|
60ddd3 |
#define __SID_SYSTEM {1,1,{{0,0,0,0,0,5}},{18}}
|
|
|
60ddd3 |
#define __SID_OWNER_RIGHTS {1,1,{{0,0,0,0,0,3}},{4}}
|
|
|
60ddd3 |
#define __SID_AUTHENTICATED_USERS {1,1,{{0,0,0,0,0,5}},{11}}
|
|
|
17fbe4 |
#define __SID_ADMINISTRATORS {1,2,{{0,0,0,0,0,5}},{32,544}}
|
|
|
17fbe4 |
|
|
|
17fbe4 |
static const nt_sid sid_system = __SID_SYSTEM;
|
|
|
17fbe4 |
static const nt_sid sid_owner_rights = __SID_OWNER_RIGHTS;
|
|
|
17fbe4 |
static const nt_sid sid_auth_users = __SID_AUTHENTICATED_USERS;
|
|
|
17fbe4 |
static const nt_sid_os sid_admins = __SID_ADMINISTRATORS;
|
|
|
60ddd3 |
|
|
|
60ddd3 |
static nt_access_allowed_ace * __acl_ace_init(
|
|
|
60ddd3 |
nt_access_allowed_ace * ace,
|
|
|
60ddd3 |
uint32_t mask,
|
|
|
60ddd3 |
const nt_sid * sid,
|
|
|
51f775 |
uint32_t flags,
|
|
|
60ddd3 |
uint16_t * aces)
|
|
|
60ddd3 |
{
|
|
|
60ddd3 |
if (mask == 0)
|
|
|
60ddd3 |
return ace;
|
|
|
60ddd3 |
|
|
|
60ddd3 |
ace->mask = mask;
|
|
|
60ddd3 |
ace->header.ace_type = NT_ACE_TYPE_ACCESS_ALLOWED;
|
|
|
51f775 |
ace->header.ace_flags = flags;
|
|
|
60ddd3 |
ace->header.ace_size = sizeof(uint32_t) * sid->sub_authority_count
|
|
|
60ddd3 |
+ __offsetof(nt_access_allowed_ace,sid_start)
|
|
|
60ddd3 |
+ __offsetof(nt_sid,sub_authority);
|
|
|
60ddd3 |
|
|
|
60ddd3 |
__ntapi->tt_sid_copy(
|
|
|
60ddd3 |
(nt_sid *)&ace->sid_start,
|
|
|
60ddd3 |
sid);
|
|
|
60ddd3 |
|
|
|
60ddd3 |
(*aces)++;
|
|
|
60ddd3 |
|
|
|
60ddd3 |
return (nt_access_allowed_ace *)((size_t)ace + ace->header.ace_size);
|
|
|
60ddd3 |
}
|
|
|
60ddd3 |
|
|
|
60ddd3 |
void __stdcall __ntapi_acl_init_common_descriptor(
|
|
|
60ddd3 |
__out nt_sd_common_buffer * sd,
|
|
|
60ddd3 |
__in const nt_sid * owner,
|
|
|
60ddd3 |
__in const nt_sid * group,
|
|
|
60ddd3 |
__in const nt_sid * other,
|
|
|
17fbe4 |
__in const nt_sid * admin,
|
|
|
60ddd3 |
__in uint32_t owner_access,
|
|
|
60ddd3 |
__in uint32_t group_access,
|
|
|
60ddd3 |
__in uint32_t other_access,
|
|
|
17fbe4 |
__in uint32_t admin_access,
|
|
|
51f775 |
__in uint32_t system_access,
|
|
|
51f775 |
__in uint32_t ace_flags)
|
|
|
60ddd3 |
{
|
|
|
60ddd3 |
nt_access_allowed_ace * ace;
|
|
|
60ddd3 |
uint16_t ace_count = 0;
|
|
|
60ddd3 |
|
|
|
60ddd3 |
/* sd header */
|
|
|
60ddd3 |
sd->sd.revision = 1;
|
|
|
60ddd3 |
sd->sd.sbz_1st = 0;
|
|
|
5c3887 |
sd->sd.control = NT_SE_SELF_RELATIVE | NT_SE_DACL_PRESENT | NT_SE_DACL_PROTECTED;
|
|
|
60ddd3 |
sd->sd.offset_owner = __offsetof(nt_sd_common_buffer,owner);
|
|
|
60ddd3 |
sd->sd.offset_group = 0;
|
|
|
60ddd3 |
sd->sd.offset_dacl = __offsetof(nt_sd_common_buffer,dacl);
|
|
|
60ddd3 |
sd->sd.offset_sacl = 0;
|
|
|
60ddd3 |
|
|
|
60ddd3 |
/* owner, group, other: default sid's */
|
|
|
0a8487 |
owner = owner ? owner : __ntapi_internals()->user;
|
|
|
808392 |
group = group ? group : owner;
|
|
|
60ddd3 |
other = other ? other : &sid_auth_users;
|
|
|
60ddd3 |
|
|
|
60ddd3 |
/* owner sid */
|
|
|
60ddd3 |
__ntapi->tt_sid_copy(
|
|
|
60ddd3 |
(nt_sid *)&sd->owner,
|
|
|
60ddd3 |
owner);
|
|
|
60ddd3 |
|
|
|
83fba2 |
/* is the local system account both the owner and the group? */
|
|
|
83fba2 |
if (!__ntapi->tt_sid_compare(owner,&sid_system))
|
|
|
83fba2 |
if (!__ntapi->tt_sid_compare(group,&sid_system))
|
|
|
83fba2 |
if (system_access == owner_access)
|
|
|
83fba2 |
system_access = 0;
|
|
|
83fba2 |
|
|
|
84ee36 |
/* is the built-in administrators group both the owner and the group? */
|
|
|
84ee36 |
if (!__ntapi->tt_sid_compare(owner,(nt_sid *)&sid_admins))
|
|
|
84ee36 |
if (!__ntapi->tt_sid_compare(group,(nt_sid *)&sid_admins))
|
|
|
84ee36 |
if (admin_access == owner_access)
|
|
|
84ee36 |
admin_access = 0;
|
|
|
84ee36 |
|
|
|
60ddd3 |
/* ace's */
|
|
|
60ddd3 |
ace = (nt_access_allowed_ace *)&sd->buffer;
|
|
|
51f775 |
ace = __acl_ace_init(ace,system_access,&sid_system,ace_flags,&ace_count);
|
|
|
51f775 |
ace = __acl_ace_init(ace,owner_access,&sid_owner_rights,ace_flags,&ace_count);
|
|
|
51f775 |
ace = __acl_ace_init(ace,group_access,group,ace_flags,&ace_count);
|
|
|
51f775 |
ace = __acl_ace_init(ace,other_access,other,ace_flags,&ace_count);
|
|
|
60ddd3 |
|
|
|
17fbe4 |
if (admin_access) {
|
|
|
17fbe4 |
admin = admin ? admin : (nt_sid *)&sid_admins;
|
|
|
51f775 |
ace = __acl_ace_init(ace,admin_access,admin,ace_flags,&ace_count);
|
|
|
17fbe4 |
}
|
|
|
17fbe4 |
|
|
|
60ddd3 |
/* dacl */
|
|
|
60ddd3 |
sd->dacl.acl_revision = 0x02;
|
|
|
60ddd3 |
sd->dacl.sbz_1st = 0;
|
|
|
60ddd3 |
sd->dacl.acl_size = (uint16_t)((char *)ace - (char *)&sd->dacl);
|
|
|
60ddd3 |
sd->dacl.ace_count = ace_count;
|
|
|
60ddd3 |
sd->dacl.sbz_2nd = 0;
|
|
|
60ddd3 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
static int32_t __acl_init_common_meta_impl(
|
|
|
32ec33 |
__out nt_sd_common_meta * meta,
|
|
|
32ec33 |
__in nt_sd * sd)
|
|
|
32ec33 |
{
|
|
|
32ec33 |
int i;
|
|
|
32ec33 |
nt_sid * sid;
|
|
|
32ec33 |
nt_acl * acl;
|
|
|
32ec33 |
nt_access_allowed_ace * ace;
|
|
|
ca4b1f |
nt_access_allowed_ace * sysace;
|
|
|
ca4b1f |
nt_sid * syssid;
|
|
|
32ec33 |
unsigned char * value;
|
|
|
32ec33 |
unsigned char sacnt;
|
|
|
32ec33 |
char * mark = (char *)sd;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->sd = sd;
|
|
|
32ec33 |
meta->owner = sd->offset_owner ? (nt_sid *)(mark + sd->offset_owner) : 0;
|
|
|
32ec33 |
meta->group = 0;
|
|
|
32ec33 |
meta->dacl = sd->offset_dacl ? (nt_acl *)(mark + sd->offset_dacl) : 0;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->owner_ace = 0;
|
|
|
32ec33 |
meta->owner_sid = 0;
|
|
|
32ec33 |
meta->group_ace = 0;
|
|
|
32ec33 |
meta->group_sid = 0;
|
|
|
32ec33 |
meta->other_ace = 0;
|
|
|
32ec33 |
meta->other_sid = 0;
|
|
|
32ec33 |
meta->admin_ace = 0;
|
|
|
32ec33 |
meta->admin_sid = 0;
|
|
|
32ec33 |
meta->system_acc = 0;
|
|
|
32ec33 |
|
|
|
32ec33 |
if (!meta->owner)
|
|
|
32ec33 |
return NT_STATUS_INVALID_OWNER;
|
|
|
32ec33 |
|
|
|
32ec33 |
if (!(acl = meta->dacl))
|
|
|
32ec33 |
return NT_STATUS_SUCCESS;
|
|
|
32ec33 |
|
|
|
32ec33 |
if (acl->ace_count == 0)
|
|
|
32ec33 |
return NT_STATUS_SUCCESS;
|
|
|
32ec33 |
|
|
|
32ec33 |
if (acl->ace_count > 5)
|
|
|
32ec33 |
return NT_STATUS_NOT_SUPPORTED;
|
|
|
32ec33 |
|
|
|
32ec33 |
ace = (nt_access_allowed_ace *)&acl[1];
|
|
|
32ec33 |
|
|
|
32ec33 |
for (i=0; i<acl->ace_count; i++) {
|
|
|
32ec33 |
if (ace->header.ace_type != NT_ACE_TYPE_ACCESS_ALLOWED)
|
|
|
32ec33 |
return NT_STATUS_NOT_SUPPORTED;
|
|
|
32ec33 |
|
|
|
32ec33 |
mark = (char *)ace + ace->header.ace_size;
|
|
|
32ec33 |
ace = (nt_access_allowed_ace *)mark;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
ace = (nt_access_allowed_ace *)&acl[1];
|
|
|
32ec33 |
|
|
|
32ec33 |
for (i=0; i<acl->ace_count; i++) {
|
|
|
32ec33 |
sid = (nt_sid *)&ace->sid_start;
|
|
|
32ec33 |
value = sid->identifier_authority.value;
|
|
|
32ec33 |
|
|
|
ca4b1f |
if (!(__ntapi->tt_sid_compare(sid,&sid_system))) {
|
|
|
32ec33 |
meta->system_acc = ace->mask;
|
|
|
32ec33 |
|
|
|
ca4b1f |
sysace = ace;
|
|
|
ca4b1f |
syssid = sid;
|
|
|
ca4b1f |
|
|
|
ca4b1f |
} else if (!(__ntapi->tt_sid_compare(sid,&sid_owner_rights))) {
|
|
|
32ec33 |
if (meta->owner_ace)
|
|
|
32ec33 |
return NT_STATUS_INVALID_ACL;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->owner_ace = ace;
|
|
|
32ec33 |
meta->owner_sid = sid;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
else if (!(__ntapi->tt_sid_compare(sid,&sid_auth_users))) {
|
|
|
32ec33 |
if (meta->other_ace)
|
|
|
32ec33 |
return NT_STATUS_INVALID_ACL;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->other_ace = ace;
|
|
|
32ec33 |
meta->other_sid = sid;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
3249ab |
else if (!meta->admin_ace && !(__ntapi->tt_sid_compare(sid,(nt_sid *)&sid_admins))) {
|
|
|
3249ab |
meta->admin_ace = ace;
|
|
|
3249ab |
meta->admin_sid = sid;
|
|
|
3249ab |
}
|
|
|
3249ab |
|
|
|
32ec33 |
else if (!(__ntapi->tt_sid_compare(sid,meta->owner))) {
|
|
|
32ec33 |
if (meta->group_ace)
|
|
|
32ec33 |
return NT_STATUS_INVALID_ACL;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->group_ace = ace;
|
|
|
32ec33 |
meta->group_sid = sid;
|
|
|
9d1d3b |
meta->group = sid;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
else if ((value[0] == 0) && (value[1] == 0)
|
|
|
32ec33 |
&& (value[2] == 0) && (value[3] == 0)
|
|
|
32ec33 |
&& (value[4] == 0) && (value[5] == 5)
|
|
|
32ec33 |
&& (sid->sub_authority[0] == 21)
|
|
|
32ec33 |
&& ((sacnt = sid->sub_authority_count))
|
|
|
32ec33 |
&& (sid->sub_authority[sacnt - 1] == 500)) {
|
|
|
32ec33 |
if (meta->admin_ace)
|
|
|
32ec33 |
return NT_STATUS_INVALID_ACL;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->admin_ace = ace;
|
|
|
32ec33 |
meta->admin_sid = sid;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
else {
|
|
|
32ec33 |
if (meta->group_ace)
|
|
|
32ec33 |
return NT_STATUS_INVALID_ACL;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->group_ace = ace;
|
|
|
32ec33 |
meta->group_sid = sid;
|
|
|
32ec33 |
meta->group = sid;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
mark = (char *)ace + ace->header.ace_size;
|
|
|
32ec33 |
ace = (nt_access_allowed_ace *)mark;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
ca4b1f |
if (!meta->group_ace && meta->owner_ace) {
|
|
|
ca4b1f |
if (meta->owner_ace->mask != meta->system_acc) {
|
|
|
ca4b1f |
if (!__ntapi->tt_sid_compare(meta->owner,&sid_system)) {
|
|
|
ca4b1f |
meta->group_ace = sysace;
|
|
|
ca4b1f |
meta->group_sid = syssid;
|
|
|
ca4b1f |
meta->group = syssid;
|
|
|
ca4b1f |
meta->system_acc = meta->owner_ace->mask;
|
|
|
ca4b1f |
}
|
|
|
ca4b1f |
}
|
|
|
ca4b1f |
}
|
|
|
ca4b1f |
|
|
|
32ec33 |
return NT_STATUS_SUCCESS;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
static int32_t __acl_init_common_meta_strict(
|
|
|
32ec33 |
__out nt_sd_common_meta * meta,
|
|
|
32ec33 |
__in nt_sd * sd)
|
|
|
32ec33 |
{
|
|
|
32ec33 |
int32_t status;
|
|
|
32ec33 |
nt_sd_common_meta m;
|
|
|
32ec33 |
|
|
|
32ec33 |
if ((status = __acl_init_common_meta_impl(&m,sd)))
|
|
|
32ec33 |
return status;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->sd = m.sd;
|
|
|
32ec33 |
meta->owner = m.owner;
|
|
|
32ec33 |
meta->group = m.group;
|
|
|
32ec33 |
meta->dacl = m.dacl;
|
|
|
32ec33 |
|
|
|
32ec33 |
meta->owner_ace = m.owner_ace;
|
|
|
32ec33 |
meta->owner_sid = m.owner_sid;
|
|
|
32ec33 |
meta->group_ace = m.group_ace;
|
|
|
32ec33 |
meta->group_sid = m.group_sid;
|
|
|
32ec33 |
meta->other_ace = m.other_ace;
|
|
|
32ec33 |
meta->other_sid = m.other_sid;
|
|
|
32ec33 |
meta->admin_ace = m.admin_ace;
|
|
|
32ec33 |
meta->admin_sid = m.admin_sid;
|
|
|
a39985 |
meta->system_acc = m.system_acc;
|
|
|
32ec33 |
|
|
|
32ec33 |
return NT_STATUS_SUCCESS;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
static int32_t __acl_init_common_meta_query(
|
|
|
32ec33 |
__out nt_sd_common_meta * meta,
|
|
|
32ec33 |
__in nt_sd * sd)
|
|
|
32ec33 |
{
|
|
|
32ec33 |
__acl_init_common_meta_impl(meta,sd);
|
|
|
32ec33 |
return NT_STATUS_SUCCESS;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
|
|
|
32ec33 |
int32_t __stdcall __ntapi_acl_init_common_descriptor_meta(
|
|
|
32ec33 |
__out nt_sd_common_meta * meta,
|
|
|
32ec33 |
__in nt_sd * sd,
|
|
|
32ec33 |
__in uint32_t options)
|
|
|
32ec33 |
{
|
|
|
32ec33 |
switch (options) {
|
|
|
32ec33 |
case NT_ACL_INIT_COMMON_DESCRIPTION_META_QUERY_MODE:
|
|
|
32ec33 |
return __acl_init_common_meta_query(meta,sd);
|
|
|
32ec33 |
|
|
|
32ec33 |
case NT_ACL_INIT_COMMON_DESCRIPTION_META_STRICT_MODE:
|
|
|
32ec33 |
return __acl_init_common_meta_strict(meta,sd);
|
|
|
32ec33 |
|
|
|
32ec33 |
default:
|
|
|
32ec33 |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
32ec33 |
}
|
|
|
32ec33 |
}
|