diff options
-rw-r--r-- | source4/rpc_server/common/sid_helper.c | 134 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/getncchanges.c | 109 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 109 | ||||
-rw-r--r-- | source4/rpc_server/wscript_build | 9 |
4 files changed, 144 insertions, 217 deletions
diff --git a/source4/rpc_server/common/sid_helper.c b/source4/rpc_server/common/sid_helper.c new file mode 100644 index 00000000000..698249391ef --- /dev/null +++ b/source4/rpc_server/common/sid_helper.c @@ -0,0 +1,134 @@ +/* + Unix SMB/CIFS implementation. + + common sid helper functions + + Copyright (C) Catalyst.NET Ltd 2017 + + 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 <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "rpc_server/dcerpc_server.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "source4/dsdb/samdb/samdb.h" +#include "rpc_server/common/sid_helper.h" +#include "libcli/security/security.h" + +/* + see if any SIDs in list1 are in list2 + */ +bool sid_list_match(const struct dom_sid **list1, const struct dom_sid **list2) +{ + unsigned int i, j; + /* do we ever have enough SIDs here to worry about O(n^2) ? */ + for (i=0; list1[i]; i++) { + for (j=0; list2[j]; j++) { + if (dom_sid_equal(list1[i], list2[j])) { + return true; + } + } + } + return false; +} + +/* + * Return an array of SIDs from a ldb_message given an attribute name assumes + * the SIDs are in NDR form (with additional sids applied on the end). + */ +WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, + struct ldb_message *msg, + TALLOC_CTX *mem_ctx, + const char *attr, + const struct dom_sid ***sids, + const struct dom_sid **additional_sids, + unsigned int num_additional) +{ + struct ldb_message_element *el; + unsigned int i, j; + + el = ldb_msg_find_element(msg, attr); + if (!el) { + *sids = NULL; + return WERR_OK; + } + + /* Make array long enough for NULL and additional SID */ + (*sids) = talloc_array(mem_ctx, const struct dom_sid *, + el->num_values + num_additional + 1); + W_ERROR_HAVE_NO_MEMORY(*sids); + + for (i=0; i<el->num_values; i++) { + enum ndr_err_code ndr_err; + struct dom_sid *sid; + + sid = talloc(*sids, struct dom_sid); + W_ERROR_HAVE_NO_MEMORY(sid); + + ndr_err = ndr_pull_struct_blob(&el->values[i], sid, sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_INTERNAL_DB_CORRUPTION; + } + (*sids)[i] = sid; + } + + for (j = 0; j < num_additional; j++) { + (*sids)[i++] = additional_sids[j]; + } + + (*sids)[i] = NULL; + + return WERR_OK; +} + +/* + return an array of SIDs from a ldb_message given an attribute name + assumes the SIDs are in extended DN format + */ +WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, + struct ldb_message *msg, + TALLOC_CTX *mem_ctx, + const char *attr, + const struct dom_sid ***sids) +{ + struct ldb_message_element *el; + unsigned int i; + + el = ldb_msg_find_element(msg, attr); + if (!el) { + *sids = NULL; + return WERR_OK; + } + + (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); + W_ERROR_HAVE_NO_MEMORY(*sids); + + for (i=0; i<el->num_values; i++) { + struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]); + NTSTATUS status; + struct dom_sid *sid; + + sid = talloc(*sids, struct dom_sid); + W_ERROR_HAVE_NO_MEMORY(sid); + status = dsdb_get_extended_dn_sid(dn, sid, "SID"); + if (!NT_STATUS_IS_OK(status)) { + return WERR_INTERNAL_DB_CORRUPTION; + } + (*sids)[i] = sid; + } + (*sids)[i] = NULL; + + return WERR_OK; +} diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 1f02f2c0936..ce8e7122ac5 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -32,6 +32,7 @@ #include "libcli/security/session.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" #include "rpc_server/dcerpc_server_proto.h" +#include "rpc_server/common/sid_helper.h" #include "../libcli/drsuapi/drsuapi.h" #include "lib/util/binsearch.h" #include "lib/util/tsort.h" @@ -1140,114 +1141,6 @@ static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state, } /* - return an array of SIDs from a ldb_message given an attribute name - assumes the SIDs are in extended DN format - */ -static WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, - struct ldb_message *msg, - TALLOC_CTX *mem_ctx, - const char *attr, - const struct dom_sid ***sids) -{ - struct ldb_message_element *el; - unsigned int i; - - el = ldb_msg_find_element(msg, attr); - if (!el) { - *sids = NULL; - return WERR_OK; - } - - (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); - W_ERROR_HAVE_NO_MEMORY(*sids); - - for (i=0; i<el->num_values; i++) { - struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]); - NTSTATUS status; - struct dom_sid *sid; - - sid = talloc(*sids, struct dom_sid); - W_ERROR_HAVE_NO_MEMORY(sid); - status = dsdb_get_extended_dn_sid(dn, sid, "SID"); - if (!NT_STATUS_IS_OK(status)) { - return WERR_INTERNAL_DB_CORRUPTION; - } - (*sids)[i] = sid; - } - (*sids)[i] = NULL; - - return WERR_OK; -} - - -/* - * Return an array of SIDs from a ldb_message given an attribute name assumes - * the SIDs are in NDR form (with additional sids applied on the end). - */ -static WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, - struct ldb_message *msg, - TALLOC_CTX *mem_ctx, - const char *attr, - const struct dom_sid ***sids, - const struct dom_sid **additional_sids, - unsigned int num_additional) -{ - struct ldb_message_element *el; - unsigned int i, j; - - el = ldb_msg_find_element(msg, attr); - if (!el) { - *sids = NULL; - return WERR_OK; - } - - /* Make array long enough for NULL and additional SID */ - (*sids) = talloc_array(mem_ctx, const struct dom_sid *, - el->num_values + num_additional + 1); - W_ERROR_HAVE_NO_MEMORY(*sids); - - for (i=0; i<el->num_values; i++) { - enum ndr_err_code ndr_err; - struct dom_sid *sid; - - sid = talloc(*sids, struct dom_sid); - W_ERROR_HAVE_NO_MEMORY(sid); - - ndr_err = ndr_pull_struct_blob(&el->values[i], sid, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return WERR_INTERNAL_DB_CORRUPTION; - } - (*sids)[i] = sid; - } - - for (j = 0; j < num_additional; j++) { - (*sids)[i++] = additional_sids[j]; - } - - (*sids)[i] = NULL; - - return WERR_OK; -} - -/* - see if any SIDs in list1 are in list2 - */ -static bool sid_list_match(const struct dom_sid **list1, const struct dom_sid **list2) -{ - unsigned int i, j; - /* do we ever have enough SIDs here to worry about O(n^2) ? */ - for (i=0; list1[i]; i++) { - for (j=0; list2[j]; j++) { - if (dom_sid_equal(list1[i], list2[j])) { - return true; - } - } - } - return false; -} - -/* handle a DRSUAPI_EXOP_REPL_SECRET call */ static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 8094932c797..9392a3975d0 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -42,6 +42,7 @@ #include "librpc/gen_ndr/ndr_winbind.h" #include "librpc/gen_ndr/ndr_winbind_c.h" #include "lib/socket/netif.h" +#include "rpc_server/common/sid_helper.h" #define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \ dcesrv_interface_netlogon_bind(call, iface) @@ -2252,114 +2253,6 @@ static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } -/* - see if any SIDs in list1 are in list2 - */ -static bool sid_list_match(const struct dom_sid **list1, const struct dom_sid **list2) -{ - unsigned int i, j; - /* do we ever have enough SIDs here to worry about O(n^2) ? */ - for (i=0; list1[i]; i++) { - for (j=0; list2[j]; j++) { - if (dom_sid_equal(list1[i], list2[j])) { - return true; - } - } - } - return false; -} - -/* - return an array of SIDs from a ldb_message given an attribute name - assumes the SIDs are in extended DN format - */ -static WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, - struct ldb_message *msg, - TALLOC_CTX *mem_ctx, - const char *attr, - const struct dom_sid ***sids) -{ - struct ldb_message_element *el; - unsigned int i; - - el = ldb_msg_find_element(msg, attr); - if (!el) { - *sids = NULL; - return WERR_OK; - } - - (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); - W_ERROR_HAVE_NO_MEMORY(*sids); - - for (i=0; i<el->num_values; i++) { - struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]); - NTSTATUS status; - struct dom_sid *sid; - - sid = talloc(*sids, struct dom_sid); - W_ERROR_HAVE_NO_MEMORY(sid); - status = dsdb_get_extended_dn_sid(dn, sid, "SID"); - if (!NT_STATUS_IS_OK(status)) { - return WERR_INTERNAL_DB_CORRUPTION; - } - (*sids)[i] = sid; - } - (*sids)[i] = NULL; - - return WERR_OK; -} - - -/* - * Return an array of SIDs from a ldb_message given an attribute name assumes - * the SIDs are in NDR form (with additional sids applied on the end). - */ -static WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, - struct ldb_message *msg, - TALLOC_CTX *mem_ctx, - const char *attr, - const struct dom_sid ***sids, - const struct dom_sid **additional_sids, - unsigned int num_additional) -{ - struct ldb_message_element *el; - unsigned int i, j; - - el = ldb_msg_find_element(msg, attr); - if (!el) { - *sids = NULL; - return WERR_OK; - } - - /* Make array long enough for NULL and additional SID */ - (*sids) = talloc_array(mem_ctx, const struct dom_sid *, - el->num_values + num_additional + 1); - W_ERROR_HAVE_NO_MEMORY(*sids); - - for (i=0; i<el->num_values; i++) { - enum ndr_err_code ndr_err; - struct dom_sid *sid; - - sid = talloc(*sids, struct dom_sid); - W_ERROR_HAVE_NO_MEMORY(sid); - - ndr_err = ndr_pull_struct_blob(&el->values[i], sid, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return WERR_INTERNAL_DB_CORRUPTION; - } - (*sids)[i] = sid; - } - - for (j = 0; j < num_additional; j++) { - (*sids)[i++] = additional_sids[j]; - } - - (*sids)[i] = NULL; - - return WERR_OK; -} - static bool sam_rodc_access_check(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct dom_sid *user_sid, diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build index f1b1f19455a..966e07ee641 100644 --- a/source4/rpc_server/wscript_build +++ b/source4/rpc_server/wscript_build @@ -7,10 +7,17 @@ bld.SAMBA_SUBSYSTEM('DCERPC_SHARE', enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER'), ) +bld.SAMBA_SUBSYSTEM('DCERPC_SID_HELPER', + source='common/sid_helper.c', + autoproto='common/sid_helper.h', + deps='ldb', + enabled=bld.AD_DC_BUILD_IS_ENABLED(), + ) + bld.SAMBA_SUBSYSTEM('DCERPC_COMMON', source='common/server_info.c common/forward.c common/reply.c dcesrv_auth.c common/loadparm.c', autoproto='common/proto.h', - deps='ldb DCERPC_SHARE samba_server_gensec', + deps='ldb DCERPC_SHARE DCERPC_SID_HELPER samba_server_gensec', enabled=bld.AD_DC_BUILD_IS_ENABLED() ) |