Otherwise a lot of information that is usually generated in the ndr_push remains
in an uninitialized state.
Guenther
pidl "";
}
-sub ParseDispatchFunction($)
-{
- my ($if) = @_;
-
- pidl_hdr "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r);";
- pidl "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *_r)";
- pidl "{";
- indent;
- pidl "if (cli->pipes_struct == NULL) {";
- pidl "\treturn NT_STATUS_INVALID_PARAMETER;";
- pidl "}";
- pidl "";
- pidl "/* set opnum in fake rpc header */";
- pidl "cli->pipes_struct->hdr_req.opnum = opnum;";
- pidl "";
- pidl "switch (opnum)";
- pidl "{";
- indent;
- foreach my $fn (@{$if->{FUNCTIONS}}) {
- next if ($fn->{PROPERTIES}{noopnum});
- my $op = "NDR_".uc($fn->{NAME});
- pidl "case $op: {";
- indent;
- pidl "struct $fn->{NAME} *r = (struct $fn->{NAME} *)_r;";
-
- pidl "if (DEBUGLEVEL >= 10) {";
- pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, r);";
- pidl "}";
-
- CallWithStruct("cli->pipes_struct", "mem_ctx", $fn,
- sub { pidl "\treturn NT_STATUS_NO_MEMORY;"; });
-
- pidl "if (DEBUGLEVEL >= 10) {";
- pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, r);";
- pidl "}";
-
- pidl "return NT_STATUS_OK;";
- deindent;
- pidl "}";
- pidl "";
- }
-
- pidl "default:";
- pidl "\treturn NT_STATUS_NOT_IMPLEMENTED;";
- deindent;
- pidl "}";
- deindent;
- pidl "}";
-
- pidl "";
-}
-
sub ParseInterface($)
{
my $if = shift;
pidl "}";
pidl "";
- ParseDispatchFunction($if);
-
if (not has_property($if, "no_srv_register")) {
pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
const char *client_address,
struct auth_serversupplied_info *server_info);
NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *abstract_syntax,
- NTSTATUS (*dispatch) (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r),
struct auth_serversupplied_info *serversupplied_info,
struct rpc_pipe_client **presult);
NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn,
*/
#include "includes.h"
+#include "rpc_server/srv_pipe_internal.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
return p;
}
+/****************************************************************************
+****************************************************************************/
+
+static NTSTATUS internal_ndr_push(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *cli,
+ const struct ndr_interface_table *table,
+ uint32_t opnum,
+ void *r)
+{
+ const struct ndr_interface_call *call;
+ struct ndr_push *push;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ bool ret;
+
+ if (!ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax) ||
+ (opnum >= table->num_calls)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ call = &table->calls[opnum];
+
+ if (DEBUGLEVEL >= 10) {
+ ndr_print_function_debug(call->ndr_print,
+ call->name, NDR_IN, r);
+ }
+
+ push = ndr_push_init_ctx(mem_ctx);
+ if (push == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ndr_err = call->ndr_push(push, NDR_IN, r);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ TALLOC_FREE(push);
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ blob = ndr_push_blob(push);
+ ret = prs_init_data_blob(&cli->pipes_struct->in_data.data, &blob, mem_ctx);
+ TALLOC_FREE(push);
+ if (!ret) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static NTSTATUS internal_ndr_pull(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *cli,
+ const struct ndr_interface_table *table,
+ uint32_t opnum,
+ void *r)
+{
+ const struct ndr_interface_call *call;
+ struct ndr_pull *pull;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ bool ret;
+
+ if (!ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax) ||
+ (opnum >= table->num_calls)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ call = &table->calls[opnum];
+
+ ret = prs_data_blob(&cli->pipes_struct->out_data.rdata, &blob, mem_ctx);
+ if (!ret) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ pull = ndr_pull_init_blob(&blob, mem_ctx);
+ if (pull == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* have the ndr parser alloc memory for us */
+ pull->flags |= LIBNDR_FLAG_REF_ALLOC;
+ ndr_err = call->ndr_pull(pull, NDR_OUT, r);
+ TALLOC_FREE(pull);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ ndr_print_function_debug(call->ndr_print,
+ call->name, NDR_OUT, r);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static NTSTATUS rpc_pipe_internal_dispatch(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const struct ndr_interface_table *table,
+ uint32_t opnum, void *r)
+{
+ NTSTATUS status;
+ int num_cmds = rpc_srv_get_pipe_num_cmds(&table->syntax_id);
+ const struct api_struct *cmds = rpc_srv_get_pipe_cmds(&table->syntax_id);
+ int i;
+
+ if (cli->pipes_struct == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* set opnum in fake rpc header */
+ cli->pipes_struct->hdr_req.opnum = opnum;
+
+ for (i = 0; i < num_cmds; i++) {
+ if (cmds[i].opnum == opnum && cmds[i].fn != NULL) {
+ break;
+ }
+ }
+
+ if (i == num_cmds) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ prs_init_empty(&cli->pipes_struct->out_data.rdata, cli->pipes_struct->mem_ctx, MARSHALL);
+
+ status = internal_ndr_push(mem_ctx, cli, table, opnum, r);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (!cmds[i].fn(cli->pipes_struct)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ status = internal_ndr_pull(mem_ctx, cli, table, opnum, r);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ prs_mem_free(&cli->pipes_struct->in_data.data);
+ prs_mem_free(&cli->pipes_struct->out_data.rdata);
+
+ return NT_STATUS_OK;
+}
+
/**
* @brief Create a new RPC client context which uses a local dispatch function.
*
*/
NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
const struct ndr_syntax_id *abstract_syntax,
- NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx,
- const struct ndr_interface_table *table,
- uint32_t opnum, void *r),
struct auth_serversupplied_info *serversupplied_info,
struct rpc_pipe_client **presult)
{
result->abstract_syntax = *abstract_syntax;
result->transfer_syntax = ndr_transfer_syntax;
- result->dispatch = dispatch;
+ result->dispatch = rpc_pipe_internal_dispatch;
result->pipes_struct = make_internal_rpc_pipe_p(
result, abstract_syntax, "", serversupplied_info);
DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
status = rpc_pipe_open_internal(p->mem_ctx, &ndr_table_lsarpc.syntax_id,
- rpc_lsarpc_dispatch, p->server_info,
+ p->server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
return status;
ZERO_STRUCT(user_handle);
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
- rpc_samr_dispatch, server_info,
+ server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
goto out;
ZERO_STRUCT(user_handle);
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
- rpc_samr_dispatch, server_info,
+ server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
goto out;
if (!conn->spoolss_pipe) {
status = rpc_pipe_open_internal(conn,
&ndr_table_spoolss.syntax_id,
- rpc_spoolss_dispatch,
conn->server_info,
&conn->spoolss_pipe);
if (!NT_STATUS_IS_OK(status)) {
/* create winreg connection */
status = rpc_pipe_open_internal(mem_ctx,
&ndr_table_winreg.syntax_id,
- rpc_winreg_dispatch,
server_info,
&pipe_handle);
if (!NT_STATUS_IS_OK(status)) {
}
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
- rpc_srvsvc_dispatch, conn->server_info,
+ conn->server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("api_RNetShareAdd: could not connect to srvsvc: %s\n",
}
status = rpc_pipe_open_internal(
- talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+ talloc_tos(), &ndr_table_samr.syntax_id,
conn->server_info, &samr_pipe);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
endp = *rdata + *rdata_len;
status = rpc_pipe_open_internal(
- talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+ talloc_tos(), &ndr_table_samr.syntax_id,
conn->server_info, &samr_pipe);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
endp = *rdata + *rdata_len;
status = rpc_pipe_open_internal(
- talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+ talloc_tos(), &ndr_table_samr.syntax_id,
conn->server_info, &samr_pipe);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
ZERO_STRUCT(user_handle);
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
- rpc_samr_dispatch, conn->server_info,
+ conn->server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",
memcpy(hash.hash, data+516, 16);
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
- rpc_samr_dispatch, conn->server_info,
+ conn->server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("api_SamOEMChangePassword: could not connect to samr: %s\n",
p2 = p + struct_len;
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
- rpc_srvsvc_dispatch, conn->server_info,
+ conn->server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("api_RNetServerGetInfo: could not connect to srvsvc: %s\n",
ZERO_STRUCT(user_handle);
status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
- rpc_samr_dispatch, conn->server_info,
+ conn->server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("api_RNetUserGetInfo: could not connect to samr: %s\n",
#include "winbindd.h"
#include "../../nsswitch/libwbclient/wbc_async.h"
#include "librpc/gen_ndr/messaging.h"
+#include "../librpc/gen_ndr/srv_lsa.h"
+#include "../librpc/gen_ndr/srv_samr.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
winbindd_register_handlers();
+ rpc_lsarpc_init();
+ rpc_samr_init();
+
if (!init_system_info()) {
DEBUG(0,("ERROR: failed to setup system user info.\n"));
exit(1);
/* create a samr connection */
status = rpc_pipe_open_internal(mem_ctx,
&ndr_table_samr.syntax_id,
- rpc_samr_dispatch,
server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {
/* create a samr connection */
status = rpc_pipe_open_internal(mem_ctx,
&ndr_table_lsarpc.syntax_id,
- rpc_lsarpc_dispatch,
server_info,
&cli);
if (!NT_STATUS_IS_OK(status)) {