| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static const nt_sid sid_system = __SID_SYSTEM; |
| static const nt_sid sid_owner_rights = __SID_OWNER_RIGHTS; |
| static const nt_sid sid_auth_users = __SID_AUTHENTICATED_USERS; |
| static const nt_sid_os sid_admins = __SID_ADMINISTRATORS; |
| |
| static nt_access_allowed_ace * __acl_ace_init( |
| nt_access_allowed_ace * ace, |
| uint32_t mask, |
| const nt_sid * sid, |
| uint16_t * aces) |
| { |
| if (mask == 0) |
| return ace; |
| |
| ace->mask = mask; |
| ace->header.ace_type = NT_ACE_TYPE_ACCESS_ALLOWED; |
| ace->header.ace_flags = 0; |
| ace->header.ace_size = sizeof(uint32_t) * sid->sub_authority_count |
| + __offsetof(nt_access_allowed_ace,sid_start) |
| + __offsetof(nt_sid,sub_authority); |
| |
| __ntapi->tt_sid_copy( |
| (nt_sid *)&ace->sid_start, |
| sid); |
| |
| (*aces)++; |
| |
| return (nt_access_allowed_ace *)((size_t)ace + ace->header.ace_size); |
| } |
| |
| void __stdcall __ntapi_acl_init_common_descriptor( |
| __out nt_sd_common_buffer * sd, |
| __in const nt_sid * owner, |
| __in const nt_sid * group, |
| __in const nt_sid * other, |
| __in const nt_sid * admin, |
| __in uint32_t owner_access, |
| __in uint32_t group_access, |
| __in uint32_t other_access, |
| __in uint32_t admin_access, |
| __in uint32_t system_access) |
| { |
| nt_access_allowed_ace * ace; |
| uint16_t ace_count = 0; |
| |
| |
| sd->sd.revision = 1; |
| sd->sd.sbz_1st = 0; |
| sd->sd.control = NT_SE_SELF_RELATIVE | NT_SE_DACL_PRESENT | NT_SE_DACL_PROTECTED; |
| sd->sd.offset_owner = __offsetof(nt_sd_common_buffer,owner); |
| sd->sd.offset_group = 0; |
| sd->sd.offset_dacl = __offsetof(nt_sd_common_buffer,dacl); |
| sd->sd.offset_sacl = 0; |
| |
| |
| owner = owner ? owner : __ntapi_internals()->user; |
| group = group ? group : owner; |
| other = other ? other : &sid_auth_users; |
| |
| |
| __ntapi->tt_sid_copy( |
| (nt_sid *)&sd->owner, |
| owner); |
| |
| |
| if (!__ntapi->tt_sid_compare(owner,&sid_system)) |
| if (!__ntapi->tt_sid_compare(group,&sid_system)) |
| if (system_access == owner_access) |
| system_access = 0; |
| |
| |
| ace = (nt_access_allowed_ace *)&sd->buffer; |
| ace = __acl_ace_init(ace,system_access,&sid_system,&ace_count); |
| ace = __acl_ace_init(ace,owner_access,&sid_owner_rights,&ace_count); |
| ace = __acl_ace_init(ace,group_access,group,&ace_count); |
| ace = __acl_ace_init(ace,other_access,other,&ace_count); |
| |
| if (admin_access) { |
| admin = admin ? admin : (nt_sid *)&sid_admins; |
| ace = __acl_ace_init(ace,admin_access,admin,&ace_count); |
| } |
| |
| |
| sd->dacl.acl_revision = 0x02; |
| sd->dacl.sbz_1st = 0; |
| sd->dacl.acl_size = (uint16_t)((char *)ace - (char *)&sd->dacl); |
| 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; |
| nt_access_allowed_ace * sysace; |
| nt_sid * syssid; |
| 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; |
| |
| sysace = ace; |
| syssid = sid; |
| |
| } 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; |
| } |
| |
| if (!meta->group_ace && meta->owner_ace) { |
| if (meta->owner_ace->mask != meta->system_acc) { |
| if (!__ntapi->tt_sid_compare(meta->owner,&sid_system)) { |
| meta->group_ace = sysace; |
| meta->group_sid = syssid; |
| meta->group = syssid; |
| meta->system_acc = meta->owner_ace->mask; |
| } |
| } |
| } |
| |
| 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 = m.system_acc; |
| |
| 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; |
| } |
| } |