From c91e756f8d406abee41f9644bd82353fdee347cb Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 7 Sep 2010 14:58:19 +0200 Subject: s3-rpc_client: Added dcerpc_lsa_lookup_sids and dcerpc_lsa_lookup_sids3. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Günther Deschner --- source3/rpc_client/cli_lsarpc.c | 205 +++++++++++++++++++++++++++++----------- source3/rpc_client/cli_lsarpc.h | 66 +++++++++++++ 2 files changed, 214 insertions(+), 57 deletions(-) diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 55aeddc403..ac6bfb8106 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -162,7 +162,7 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, * internal version withOUT memory allocation of the target arrays. * this assumes suffciently sized arrays to store domains, names and types. */ -static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, +static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, struct policy_handle *pol, int num_sids, @@ -170,29 +170,23 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, char **domains, char **names, enum lsa_SidType *types, - bool use_lookupsids3) + bool use_lookupsids3, + NTSTATUS *presult) { - NTSTATUS result = NT_STATUS_OK; - TALLOC_CTX *tmp_ctx = NULL; - int i; + NTSTATUS status = NT_STATUS_OK; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_SidArray sid_array; struct lsa_RefDomainList *ref_domains = NULL; struct lsa_TransNameArray lsa_names; + enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; uint32_t count = 0; - uint16_t level = 1; + int i; ZERO_STRUCT(lsa_names); - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - DEBUG(0, ("rpccli_lsa_lookup_sids_noalloc: out of memory!\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - sid_array.num_sids = num_sids; sid_array.sids = TALLOC_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids); - if (!sid_array.sids) { + if (sid_array.sids == NULL) { return NT_STATUS_NO_MEMORY; } @@ -209,19 +203,26 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, ZERO_STRUCT(lsa_names2); - result = rpccli_lsa_LookupSids3(cli, mem_ctx, + status = dcerpc_lsa_LookupSids3(h, + mem_ctx, &sid_array, &ref_domains, &lsa_names2, level, &count, 0, - 0); + 0, + &result); + if (NT_STATUS_IS_OK(status)) { + return status; + } - if (!NT_STATUS_IS_ERR(result)) { - lsa_names.count = lsa_names2.count; - lsa_names.names = talloc_array(mem_ctx, struct lsa_TranslatedName, lsa_names.count); - if (!lsa_names.names) { + if(!NT_STATUS_IS_ERR(result)) { + lsa_names.count = lsa_names2.count; + lsa_names.names = talloc_array(mem_ctx, + struct lsa_TranslatedName, + lsa_names.count); + if (lsa_names.names == NULL) { return NT_STATUS_NO_MEMORY; } for (n=0; n < lsa_names.count; n++) { @@ -232,28 +233,34 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, } } else { - result = rpccli_lsa_LookupSids(cli, mem_ctx, + status = dcerpc_lsa_LookupSids(h, + mem_ctx, pol, &sid_array, &ref_domains, &lsa_names, level, - &count); + &count, + &result); } - DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n", - nt_errstr(result), count)); + DEBUG(10, ("LSA_LOOKUPSIDS returned status: '%s', result: '%s', " + "mapped count = %d'\n", + nt_errstr(status), nt_errstr(result), count)); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) && !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { - /* An actual error occured */ - goto done; + *presult = result; + return status; } /* Return output parameters */ - if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) || (count == 0)) { @@ -262,8 +269,8 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, (domains)[i] = NULL; (types)[i] = SID_NAME_UNKNOWN; } - result = NT_STATUS_NONE_MAPPED; - goto done; + *presult = NT_STATUS_NONE_MAPPED; + return status; } for (i = 0; i < num_sids; i++) { @@ -281,8 +288,8 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, (names)[i] = talloc_strdup(names, name); if ((names)[i] == NULL) { DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; + *presult = NT_STATUS_UNSUCCESSFUL; + return status; } } else { (names)[i] = NULL; @@ -292,8 +299,8 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, (types)[i] = lsa_names.names[i].sid_type; if (((domains)[i] == NULL)) { DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; + *presult = NT_STATUS_UNSUCCESSFUL; + return status; } } else { @@ -303,9 +310,8 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, } } -done: - TALLOC_FREE(tmp_ctx); - return result; + *presult = NT_STATUS_OK; + return status; } /* Lookup a list of sids @@ -320,7 +326,7 @@ done: * at 20480 for win2k3, but we keep it at a save 1000 for now. */ #define LOOKUP_SIDS_HUNK_SIZE 1000 -static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli, +static NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, struct policy_handle *pol, int num_sids, @@ -328,8 +334,10 @@ static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli, char ***pdomains, char ***pnames, enum lsa_SidType **ptypes, - bool use_lookupsids3) + bool use_lookupsids3, + NTSTATUS *presult) { + NTSTATUS status; NTSTATUS result = NT_STATUS_OK; int sids_left = 0; int sids_processed = 0; @@ -370,7 +378,7 @@ static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli, while (sids_left > 0) { int hunk_num_sids; - NTSTATUS hunk_result = NT_STATUS_OK; + NTSTATUS hunk_result; hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE) ? LOOKUP_SIDS_HUNK_SIZE @@ -382,22 +390,26 @@ static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli, sids_processed + hunk_num_sids - 1, num_sids)); - hunk_result = rpccli_lsa_lookup_sids_noalloc(cli, - mem_ctx, - pol, - hunk_num_sids, - hunk_sids, - hunk_domains, - hunk_names, - hunk_types, - use_lookupsids3); + status = dcerpc_lsa_lookup_sids_noalloc(h, + mem_ctx, + pol, + hunk_num_sids, + hunk_sids, + hunk_domains, + hunk_names, + hunk_types, + use_lookupsids3, + &hunk_result); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } if (!NT_STATUS_IS_OK(hunk_result) && !NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED) && !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ - result = hunk_result; + *presult = hunk_result; goto fail; } @@ -431,18 +443,43 @@ static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli, *ptypes = types; if (!have_mapped) { - return NT_STATUS_NONE_MAPPED; + result = NT_STATUS_NONE_MAPPED; } if (have_unmapped) { - return STATUS_SOME_UNMAPPED; + result = STATUS_SOME_UNMAPPED; } - return NT_STATUS_OK; + *presult = result; + + return status; fail: TALLOC_FREE(domains); TALLOC_FREE(names); TALLOC_FREE(types); - return result; + + return status; +} + +NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const struct dom_sid *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + NTSTATUS *result) +{ + return dcerpc_lsa_lookup_sids_generic(h, + mem_ctx, + pol, + num_sids, + sids, + pdomains, + pnames, + ptypes, + false, + result); } NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, @@ -454,8 +491,46 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, char ***pnames, enum lsa_SidType **ptypes) { - return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids, - pdomains, pnames, ptypes, false); + NTSTATUS status; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle, + mem_ctx, + pol, + num_sids, + sids, + pdomains, + pnames, + ptypes, + false, + &result); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return result; +} + +NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const struct dom_sid *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + NTSTATUS *result) +{ + return dcerpc_lsa_lookup_sids_generic(h, + mem_ctx, + pol, + num_sids, + sids, + pdomains, + pnames, + ptypes, + true, + result); } NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, @@ -467,8 +542,24 @@ NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, char ***pnames, enum lsa_SidType **ptypes) { - return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids, - pdomains, pnames, ptypes, true); + NTSTATUS status; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle, + mem_ctx, + pol, + num_sids, + sids, + pdomains, + pnames, + ptypes, + true, + &result); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return result; } /** Lookup a list of names */ diff --git a/source3/rpc_client/cli_lsarpc.h b/source3/rpc_client/cli_lsarpc.h index bdcbb69a78..fb7760a2bf 100644 --- a/source3/rpc_client/cli_lsarpc.h +++ b/source3/rpc_client/cli_lsarpc.h @@ -56,6 +56,38 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, bool sec_qos, uint32 des_access, struct policy_handle *pol); +/** + * @brief Look up the names that correspond to an array of sids. + * + * @param[in] h The initialized binding handle for a dcerpc connection. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] pol The opened domain policy handle. + * + * @param[in] num_sids The number of sids in the sids array to look up. + * + * @param[in] sids The array of sids to look up. + * + * @param[out] pdomains A pointer to store the refercenced domains. + * + * @param[out] pnames A pointer to an array for the translated names. + * + * @param[out] ptypes A pointer to an array for the types of the names. + * + * @param[out] result A pointer for the conversion result. + * + * @return A corresponding NTSTATUS error code. + */ +NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const struct dom_sid *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + NTSTATUS *result); NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *pol, @@ -64,6 +96,39 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, char ***pdomains, char ***pnames, enum lsa_SidType **ptypes); + +/** + * @brief Look up the names that correspond to an array of sids. + * + * @param[in] h The initialized binding handle for a dcerpc connection. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] pol The opened domain policy handle. + * + * @param[in] num_sids The number of sids in the sids array to look up. + * + * @param[in] sids The array of sids to look up. + * + * @param[out] pdomains A pointer to store the refercenced domains. + * + * @param[out] pnames A pointer to an array for the translated names. + * + * @param[out] ptypes A pointer to an array for the types of the names. + * + * @param[out] result A pointer for the conversion result. + * + * @return A corresponding NTSTATUS error code. + */ +NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const struct dom_sid *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + NTSTATUS *result); NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *pol, @@ -72,6 +137,7 @@ NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, char ***pdomains, char ***pnames, enum lsa_SidType **ptypes); + NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *pol, int num_names, -- cgit