From 28c155e20d3ebf53581821572c6c3fe1724582c9 Mon Sep 17 00:00:00 2001 From: Yassir Elley Date: Tue, 6 May 2014 12:28:04 -0400 Subject: AD-GPO: Remove dependency on libsamba-security Reviewed-by: Sumit Bose --- Makefile.am | 1 + src/providers/ad/ad_gpo.c | 102 ++++++--- src/providers/ad/ad_gpo.h | 2 - src/providers/ad/ad_gpo_ndr.c | 508 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 586 insertions(+), 27 deletions(-) create mode 100644 src/providers/ad/ad_gpo_ndr.c diff --git a/Makefile.am b/Makefile.am index 138caf841..7140646b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2119,6 +2119,7 @@ libsss_ad_la_SOURCES = \ src/providers/ad/ad_access.h \ src/providers/ad/ad_gpo.c \ src/providers/ad/ad_gpo.h \ + src/providers/ad/ad_gpo_ndr.c \ src/providers/ad/ad_opts.h \ src/providers/ad/ad_srv.c \ src/providers/ad/ad_subdomains.c \ diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index ca8a5f66c..168ed2d7e 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -42,6 +42,8 @@ #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap.h" +#include "providers/ldap/sdap_idmap.h" +#include "util/util_sss_idmap.h" #include #include @@ -63,7 +65,6 @@ #define UAC_WORKSTATION_TRUST_ACCOUNT 0x00001000 #define AD_AGP_GUID "edacfd8f-ffb3-11d1-b41d-00a0c968f939" #define AD_AUTHENTICATED_USERS_SID "S-1-5-11" -#define SID_MAX_LEN 1024 /* == common data structures and declarations ============================= */ @@ -123,6 +124,43 @@ int ad_gpo_process_gpo_recv(struct tevent_req *req, /* == ad_gpo_access_send/recv helpers =======================================*/ +static bool +ad_gpo_dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) +{ + int i; + + if (sid1 == sid2) { + return true; + } + + if (!sid1 || !sid2) { + return false; + } + + if (sid1->sid_rev_num != sid2->sid_rev_num) { + return false; + } + + for (i = 0; i < 6; i++) { + if (sid1->id_auth[i] != sid2->id_auth[i]) { + return false; + } + } + + if (sid1->num_auths != sid2->num_auths) { + return false; + } + + for (i = 0; i < sid1->num_auths; i++) { + if (sid1->sub_auths[i] != sid2->sub_auths[i]) { + return false; + } + } + + return true; +} + + /* * This function retrieves the SIDs corresponding to the input user and returns * the user_sid, group_sids, and group_size in their respective output params. @@ -207,10 +245,6 @@ ad_gpo_get_sids(TALLOC_CTX *mem_ctx, return ret; } -bool string_to_sid(struct dom_sid *sidout, const char *sidstr); -int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen); -bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2); - /* * This function determines whether the input ACE includes any of the * client's SIDs. The boolean result is assigned to the _included output param. @@ -220,34 +254,40 @@ ad_gpo_ace_includes_client_sid(const char *user_sid, const char **group_sids, int group_size, struct security_ace *ace, + struct sss_idmap_ctx *idmap_ctx, bool *_included) { int i = 0; struct dom_sid ace_dom_sid; - struct dom_sid user_dom_sid; - struct dom_sid group_dom_sid; - char buf[SID_MAX_LEN + 1]; + struct dom_sid *user_dom_sid; + struct dom_sid *group_dom_sid; + enum idmap_error_code err; + bool included = false; ace_dom_sid = ace->trustee; - dom_sid_string_buf(&ace_dom_sid, buf, SID_MAX_LEN); - - if (!string_to_sid(&user_dom_sid, user_sid)) { - DEBUG(SSSDBG_OP_FAILURE, "string_to_sid failed\n"); - return EINVAL; + err = sss_idmap_sid_to_smb_sid(idmap_ctx, user_sid, &user_dom_sid); + if (err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n"); + return EFAULT; } - if (dom_sid_equal(&ace_dom_sid, &user_dom_sid)) { + included = ad_gpo_dom_sid_equal(&ace_dom_sid, user_dom_sid); + sss_idmap_free_smb_sid(idmap_ctx, user_dom_sid); + if (included) { *_included = true; return EOK; } for (i = 0; i < group_size; i++) { - if (!string_to_sid(&group_dom_sid, group_sids[i])) { - DEBUG(SSSDBG_OP_FAILURE, "string_to_sid failed\n"); - return EINVAL; + err = sss_idmap_sid_to_smb_sid(idmap_ctx, group_sids[i], &group_dom_sid); + if (err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n"); + return EFAULT; } - if (dom_sid_equal(&ace_dom_sid, &group_dom_sid)) { + included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid); + sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid); + if (included) { *_included = true; return EOK; } @@ -286,6 +326,7 @@ ad_gpo_ace_includes_client_sid(const char *user_sid, * AGP, then deny the requested control access right. Stop access checking. */ static enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace, + struct sss_idmap_ctx *idmap_ctx, const char *user_sid, const char **group_sids, int group_size) @@ -301,7 +342,7 @@ static enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace, } ret = ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size, ace, - &included); + idmap_ctx, &included); if (ret != EOK) { return AD_GPO_ACE_DENIED; } @@ -342,6 +383,7 @@ static enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace, * The boolean result is assigned to the _access_allowed output parameter. */ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, + struct sss_idmap_ctx *idmap_ctx, const char *user_sid, const char **group_sids, int group_size, @@ -367,7 +409,8 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, for (i = 0; i < dacl->num_aces; i ++) { ace = &dacl->aces[i]; - ace_status = ad_gpo_evaluate_ace(ace, user_sid, group_sids, group_size); + ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid, + group_sids, group_size); switch (ace_status) { case AD_GPO_ACE_NEUTRAL: @@ -396,6 +439,7 @@ static errno_t ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, const char *user, struct sss_domain_info *domain, + struct sss_idmap_ctx *idmap_ctx, struct gp_gpo **candidate_gpos, int num_candidate_gpos, struct gp_gpo ***_dacl_filtered_gpos, @@ -474,7 +518,7 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, break; } - ad_gpo_evaluate_dacl(dacl, user_sid, group_sids, + ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, group_sids, group_size, &access_allowed); if (access_allowed) { DEBUG(SSSDBG_TRACE_ALL, @@ -707,7 +751,6 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) ret, sss_strerror(ret)); goto done; } - state->target_dn = talloc_steal(state, target_dn); if (state->target_dn == NULL) { ret = ENOMEM; @@ -831,6 +874,7 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) } ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->domain, + state->opts->idmap_ctx->map, candidate_gpos, num_candidate_gpos, &state->dacl_filtered_gpos, &state->num_dacl_filtered_gpos); @@ -1878,8 +1922,8 @@ ad_gpo_parse_machine_ext_names(TALLOC_CTX *mem_ctx, } enum ndr_err_code -ndr_pull_security_descriptor(struct ndr_pull *ndr, int ndr_flags, - struct security_descriptor *r); +ad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr, int ndr_flags, + struct security_descriptor *r); /* * This function parses the input data blob and assigns the resulting @@ -1894,6 +1938,7 @@ static errno_t ad_gpo_parse_sd(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr_pull = NULL; struct security_descriptor sd; DATA_BLOB blob; + enum ndr_err_code ndr_err; blob.data = data; blob.length = length; @@ -1904,7 +1949,14 @@ static errno_t ad_gpo_parse_sd(TALLOC_CTX *mem_ctx, return EINVAL; } - ndr_pull_security_descriptor(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &sd); + ndr_err = ad_gpo_ndr_pull_security_descriptor(ndr_pull, + NDR_SCALARS|NDR_BUFFERS, + &sd); + + if (ndr_err != NDR_ERR_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to pull security descriptor\n"); + return EINVAL; + } *_gpo_sd = talloc_memdup(mem_ctx, &sd, sizeof(struct security_descriptor)); diff --git a/src/providers/ad/ad_gpo.h b/src/providers/ad/ad_gpo.h index 856013e43..851195d11 100644 --- a/src/providers/ad/ad_gpo.h +++ b/src/providers/ad/ad_gpo.h @@ -50,6 +50,4 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, errno_t ad_gpo_access_recv(struct tevent_req *req); -struct security_descriptor; - #endif /* AD_GPO_H_ */ diff --git a/src/providers/ad/ad_gpo_ndr.c b/src/providers/ad/ad_gpo_ndr.c new file mode 100644 index 000000000..0ee28f097 --- /dev/null +++ b/src/providers/ad/ad_gpo_ndr.c @@ -0,0 +1,508 @@ +/* + SSSD + + ad_gpo_ndr.c + + Authors: + Yassir Elley + + Copyright (C) 2014 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * This file contains a copy of samba's ndr_pull_* functions needed + * to parse a security_descriptor. We are copying them here so that we don't + * have to link against libsamba-security, which is a private samba library + * These functions are taken from: + * librpc/ndr/gen_ndr/ndr_security.c + * librpc/ndr/ndr_misc.c + * librpc/ndr/ndr_sec_helper.c + */ + +#include "util/util.h" +#include +#include + +static enum ndr_err_code +ndr_pull_GUID(struct ndr_pull *ndr, + int ndr_flags, + struct GUID *r) +{ + uint32_t size_clock_seq_0 = 0; + uint32_t size_node_0 = 0; + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time_low)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_mid)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_hi_and_version)); + size_clock_seq_0 = 2; + NDR_CHECK(ndr_pull_array_uint8(ndr, + NDR_SCALARS, + r->clock_seq, + size_clock_seq_0)); + size_node_0 = 6; + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->node, size_node_0)); + NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code +ndr_pull_security_ace_flags(struct ndr_pull *ndr, + int ndr_flags, + uint8_t *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_ace_type(struct ndr_pull *ndr, + int ndr_flags, + enum security_ace_type *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_enum_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_ace_object_flags(struct ndr_pull *ndr, + int ndr_flags, + uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_ace_object_type(struct ndr_pull *ndr, + int ndr_flags, + union security_ace_object_type *r) +{ + uint32_t level; + level = ndr_pull_get_switch_value(ndr, r); + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_union_align(ndr, 4)); + switch (level) { + case SEC_ACE_OBJECT_TYPE_PRESENT: { + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->type)); + break; } + default: { + break; } + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case SEC_ACE_OBJECT_TYPE_PRESENT: + break; + default: + break; + } + } + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_ace_object_inherited_type(struct ndr_pull *ndr, + int ndr_flags, + union security_ace_object_inherited_type *r) +{ + uint32_t level; + level = ndr_pull_get_switch_value(ndr, r); + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_union_align(ndr, 4)); + switch (level) { + case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: { + NDR_CHECK(ndr_pull_GUID(ndr, + NDR_SCALARS, + &r->inherited_type)); + break; } + default: { + break; } + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: + break; + default: + break; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code +ndr_pull_security_ace_object(struct ndr_pull *ndr, + int ndr_flags, + struct security_ace_object *r) +{ + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_security_ace_object_flags + (ndr, NDR_SCALARS, &r->flags)); + NDR_CHECK(ndr_pull_set_switch_value + (ndr, &r->type, r->flags & SEC_ACE_OBJECT_TYPE_PRESENT)); + NDR_CHECK(ndr_pull_security_ace_object_type + (ndr, NDR_SCALARS, &r->type)); + NDR_CHECK(ndr_pull_set_switch_value + (ndr, + &r->inherited_type, + r->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)); + NDR_CHECK(ndr_pull_security_ace_object_inherited_type + (ndr, NDR_SCALARS, &r->inherited_type)); + NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_security_ace_object_type + (ndr, NDR_BUFFERS, &r->type)); + NDR_CHECK(ndr_pull_security_ace_object_inherited_type + (ndr, NDR_BUFFERS, &r->inherited_type)); + } + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, + int ndr_flags, + union security_ace_object_ctr *r) +{ + uint32_t level; + level = ndr_pull_get_switch_value(ndr, r); + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_union_align(ndr, 4)); + switch (level) { + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: { + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_SCALARS, &r->object)); + break; } + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: { + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_SCALARS, &r->object)); + break; } + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: { + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_SCALARS, &r->object)); + break; } + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: { + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_SCALARS, &r->object)); + break; } + default: { + break; } + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_BUFFERS, &r->object)); + break; + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_BUFFERS, &r->object)); + break; + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_BUFFERS, &r->object)); + break; + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + NDR_CHECK(ndr_pull_security_ace_object + (ndr, NDR_BUFFERS, &r->object)); + break; + default: + break; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code +ndr_pull_dom_sid(struct ndr_pull *ndr, + int ndr_flags, + struct dom_sid *r) +{ + uint32_t cntr_sub_auths_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num)); + NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths)); + if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6)); + ZERO_STRUCT(r->sub_auths); + for (cntr_sub_auths_0 = 0; + cntr_sub_auths_0 < r->num_auths; + cntr_sub_auths_0++) { + NDR_CHECK(ndr_pull_uint32 + (ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0])); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code +ndr_pull_security_ace(struct ndr_pull *ndr, + int ndr_flags, + struct security_ace *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t start_ofs = ndr->offset; + uint32_t size = 0; + uint32_t pad = 0; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type)); + NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type)); + NDR_CHECK(ndr_pull_security_ace_object_ctr + (ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee)); + size = ndr->offset - start_ofs; + if (r->size < size) { + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, + "ndr_pull_security_ace: r->size %u < size %u", + (unsigned)r->size, size); + } + pad = r->size - size; + NDR_PULL_NEED_BYTES(ndr, pad); + ndr->offset += pad; + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_security_ace_object_ctr + (ndr, NDR_BUFFERS, &r->object)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code +ndr_pull_security_acl_revision(struct ndr_pull *ndr, + int ndr_flags, + enum security_acl_revision *r) +{ + uint16_t v; + NDR_CHECK(ndr_pull_enum_uint1632(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_acl(struct ndr_pull *ndr, + int ndr_flags, + struct security_acl *r) +{ + uint32_t size_aces_0 = 0; + uint32_t cntr_aces_0; + TALLOC_CTX *_mem_save_aces_0; + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_security_acl_revision + (ndr, NDR_SCALARS, &r->revision)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_aces)); + if (r->num_aces > 1000) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + size_aces_0 = r->num_aces; + NDR_PULL_ALLOC_N(ndr, r->aces, size_aces_0); + _mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0); + for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) { + NDR_CHECK(ndr_pull_security_ace + (ndr, NDR_SCALARS, &r->aces[cntr_aces_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0); + NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); + } + if (ndr_flags & NDR_BUFFERS) { + size_aces_0 = r->num_aces; + _mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0); + for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) { + NDR_CHECK(ndr_pull_security_ace + (ndr, NDR_BUFFERS, &r->aces[cntr_aces_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0); + } + return NDR_ERR_SUCCESS; +} + + +static enum ndr_err_code +ndr_pull_security_descriptor_revision(struct ndr_pull *ndr, + int ndr_flags, + enum security_descriptor_revision *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_enum_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + + + +static enum ndr_err_code +ndr_pull_security_descriptor_type(struct ndr_pull *ndr, + int ndr_flags, + uint16_t *r) +{ + uint16_t v; + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + + +enum ndr_err_code +ad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr, + int ndr_flags, + struct security_descriptor *r) +{ + uint32_t _ptr_owner_sid; + TALLOC_CTX *_mem_save_owner_sid_0; + uint32_t _ptr_group_sid; + TALLOC_CTX *_mem_save_group_sid_0; + uint32_t _ptr_sacl; + TALLOC_CTX *_mem_save_sacl_0; + uint32_t _ptr_dacl; + TALLOC_CTX *_mem_save_dacl_0; + uint32_t _flags_save_STRUCT = ndr->flags; + uint32_t _relative_save_offset; + + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN); + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 5)); + NDR_CHECK(ndr_pull_security_descriptor_revision(ndr, + NDR_SCALARS, + &r->revision)); + NDR_CHECK(ndr_pull_security_descriptor_type(ndr, + NDR_SCALARS, + &r->type)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_owner_sid)); + if (_ptr_owner_sid) { + NDR_PULL_ALLOC(ndr, r->owner_sid); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, + r->owner_sid, + _ptr_owner_sid)); + } else { + r->owner_sid = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_sid)); + if (_ptr_group_sid) { + NDR_PULL_ALLOC(ndr, r->group_sid); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, + r->group_sid, + _ptr_group_sid)); + } else { + r->group_sid = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sacl)); + if (_ptr_sacl) { + NDR_PULL_ALLOC(ndr, r->sacl); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->sacl, _ptr_sacl)); + } else { + r->sacl = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_dacl)); + if (_ptr_dacl) { + NDR_PULL_ALLOC(ndr, r->dacl); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->dacl, _ptr_dacl)); + } else { + r->dacl = NULL; + } + NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->owner_sid) { + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->owner_sid)); + _mem_save_owner_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->owner_sid, 0); + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->owner_sid)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_owner_sid_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } + if (r->group_sid) { + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->group_sid)); + _mem_save_group_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->group_sid, 0); + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->group_sid)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_sid_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } + if (r->sacl) { + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->sacl)); + _mem_save_sacl_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->sacl, 0); + NDR_CHECK(ndr_pull_security_acl(ndr, + NDR_SCALARS|NDR_BUFFERS, + r->sacl)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sacl_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } + if (r->dacl) { + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->dacl)); + _mem_save_dacl_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->dacl, 0); + NDR_CHECK(ndr_pull_security_acl(ndr, + NDR_SCALARS|NDR_BUFFERS, + r->dacl)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_dacl_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } + + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} -- cgit