summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/acl/ntapi_acl_helper.c172
-rw-r--r--src/internal/ntapi.c1
-rw-r--r--src/internal/ntapi_fnapi.h1
3 files changed, 174 insertions, 0 deletions
diff --git a/src/acl/ntapi_acl_helper.c b/src/acl/ntapi_acl_helper.c
index 40fe4c4..024dbd4 100644
--- a/src/acl/ntapi_acl_helper.c
+++ b/src/acl/ntapi_acl_helper.c
@@ -98,3 +98,175 @@ void __stdcall __ntapi_acl_init_common_descriptor(
sd->dacl.ace_count = ace_count;
sd->dacl.sbz_2nd = 0;
}
+
+static int32_t __acl_init_common_meta_impl(
+ __out nt_sd_common_meta * meta,
+ __in nt_sd * sd)
+{
+ int i;
+ nt_sid * sid;
+ nt_acl * acl;
+ nt_access_allowed_ace * ace;
+ unsigned char * value;
+ unsigned char sacnt;
+ char * mark = (char *)sd;
+
+ meta->sd = sd;
+ meta->owner = sd->offset_owner ? (nt_sid *)(mark + sd->offset_owner) : 0;
+ meta->group = 0;
+ meta->dacl = sd->offset_dacl ? (nt_acl *)(mark + sd->offset_dacl) : 0;
+
+ meta->owner_ace = 0;
+ meta->owner_sid = 0;
+ meta->group_ace = 0;
+ meta->group_sid = 0;
+ meta->other_ace = 0;
+ meta->other_sid = 0;
+ meta->admin_ace = 0;
+ meta->admin_sid = 0;
+ meta->system_acc = 0;
+
+ if (!meta->owner)
+ return NT_STATUS_INVALID_OWNER;
+
+ if (!(acl = meta->dacl))
+ return NT_STATUS_SUCCESS;
+
+ if (acl->ace_count == 0)
+ return NT_STATUS_SUCCESS;
+
+ if (acl->ace_count > 5)
+ return NT_STATUS_NOT_SUPPORTED;
+
+ ace = (nt_access_allowed_ace *)&acl[1];
+
+ for (i=0; i<acl->ace_count; i++) {
+ if (ace->header.ace_type != NT_ACE_TYPE_ACCESS_ALLOWED)
+ return NT_STATUS_NOT_SUPPORTED;
+
+ mark = (char *)ace + ace->header.ace_size;
+ ace = (nt_access_allowed_ace *)mark;
+ }
+
+ ace = (nt_access_allowed_ace *)&acl[1];
+
+ for (i=0; i<acl->ace_count; i++) {
+ sid = (nt_sid *)&ace->sid_start;
+ value = sid->identifier_authority.value;
+
+ if (!(__ntapi->tt_sid_compare(sid,&sid_system)))
+ meta->system_acc = ace->mask;
+
+ else if (!(__ntapi->tt_sid_compare(sid,&sid_owner_rights))) {
+ if (meta->owner_ace)
+ return NT_STATUS_INVALID_ACL;
+
+ meta->owner_ace = ace;
+ meta->owner_sid = sid;
+ }
+
+ else if (!(__ntapi->tt_sid_compare(sid,&sid_auth_users))) {
+ if (meta->other_ace)
+ return NT_STATUS_INVALID_ACL;
+
+ meta->other_ace = ace;
+ meta->other_sid = sid;
+ }
+
+ else if (!(__ntapi->tt_sid_compare(sid,meta->owner))) {
+ if (meta->group_ace)
+ return NT_STATUS_INVALID_ACL;
+
+ meta->group_ace = ace;
+ meta->group_sid = sid;
+ }
+
+ else if (!(__ntapi->tt_sid_compare(sid,(nt_sid *)&sid_admins))) {
+ if (meta->admin_ace)
+ return NT_STATUS_INVALID_ACL;
+
+ meta->admin_ace = ace;
+ meta->admin_sid = sid;
+ }
+
+ else if ((value[0] == 0) && (value[1] == 0)
+ && (value[2] == 0) && (value[3] == 0)
+ && (value[4] == 0) && (value[5] == 5)
+ && (sid->sub_authority[0] == 21)
+ && ((sacnt = sid->sub_authority_count))
+ && (sid->sub_authority[sacnt - 1] == 500)) {
+ if (meta->admin_ace)
+ return NT_STATUS_INVALID_ACL;
+
+ meta->admin_ace = ace;
+ meta->admin_sid = sid;
+ }
+
+ else {
+ if (meta->group_ace)
+ return NT_STATUS_INVALID_ACL;
+
+ meta->group_ace = ace;
+ meta->group_sid = sid;
+ meta->group = sid;
+ }
+
+ mark = (char *)ace + ace->header.ace_size;
+ ace = (nt_access_allowed_ace *)mark;
+ }
+
+ return NT_STATUS_SUCCESS;
+}
+
+static int32_t __acl_init_common_meta_strict(
+ __out nt_sd_common_meta * meta,
+ __in nt_sd * sd)
+{
+ int32_t status;
+ nt_sd_common_meta m;
+
+ if ((status = __acl_init_common_meta_impl(&m,sd)))
+ return status;
+
+ meta->sd = m.sd;
+ meta->owner = m.owner;
+ meta->group = m.group;
+ meta->dacl = m.dacl;
+
+ meta->owner_ace = m.owner_ace;
+ meta->owner_sid = m.owner_sid;
+ meta->group_ace = m.group_ace;
+ meta->group_sid = m.group_sid;
+ meta->other_ace = m.other_ace;
+ meta->other_sid = m.other_sid;
+ meta->admin_ace = m.admin_ace;
+ meta->admin_sid = m.admin_sid;
+ meta->system_acc = 0;
+
+ return NT_STATUS_SUCCESS;
+}
+
+static int32_t __acl_init_common_meta_query(
+ __out nt_sd_common_meta * meta,
+ __in nt_sd * sd)
+{
+ __acl_init_common_meta_impl(meta,sd);
+ return NT_STATUS_SUCCESS;
+}
+
+int32_t __stdcall __ntapi_acl_init_common_descriptor_meta(
+ __out nt_sd_common_meta * meta,
+ __in nt_sd * sd,
+ __in uint32_t options)
+{
+ switch (options) {
+ case NT_ACL_INIT_COMMON_DESCRIPTION_META_QUERY_MODE:
+ return __acl_init_common_meta_query(meta,sd);
+
+ case NT_ACL_INIT_COMMON_DESCRIPTION_META_STRICT_MODE:
+ return __acl_init_common_meta_strict(meta,sd);
+
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+}
diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c
index aaf1b33..af9d4c0 100644
--- a/src/internal/ntapi.c
+++ b/src/internal/ntapi.c
@@ -355,6 +355,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl)
/* nt_acl.h */
__ntapi->acl_init_common_descriptor = __ntapi_acl_init_common_descriptor;
+ __ntapi->acl_init_common_descriptor_meta = __ntapi_acl_init_common_descriptor_meta;
/* nt_vfd.h */
__ntapi->vfd_dev_name_init = __ntapi_vfd_dev_name_init;
diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h
index 5aaae4c..90d9338 100644
--- a/src/internal/ntapi_fnapi.h
+++ b/src/internal/ntapi_fnapi.h
@@ -222,6 +222,7 @@ ntapi_dsr_internal_client_connect __ntapi_dsr_internal_client_connect;
/* nt_acl.h */
ntapi_acl_init_common_descriptor __ntapi_acl_init_common_descriptor;
+ntapi_acl_init_common_descriptor_meta __ntapi_acl_init_common_descriptor_meta;
/* nt_vfd.h */
ntapi_vfd_dev_name_init __ntapi_vfd_dev_name_init;