From: Günther Deschner Date: Fri, 2 Jul 2010 08:17:44 +0000 (+0200) Subject: s3-rpc: when using rpc_pipe_open_internal, make sure to go through NDR. X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba.git;a=commitdiff_plain;h=690ed0c5e2c61584daa2acb5dbfb680ecee83e0f s3-rpc: when using rpc_pipe_open_internal, make sure to go through NDR. Otherwise a lot of information that is usually generated in the ndr_push remains in an uninitialized state. Guenther --- diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm index 311eb5b6198..a25d12bfea4 100644 --- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm +++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm @@ -225,58 +225,6 @@ sub ParseFunction($$) 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; @@ -317,8 +265,6 @@ sub ParseInterface($) 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)"; diff --git a/source3/include/proto.h b/source3/include/proto.h index d08dc59ecba..8ce2bf169cf 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4875,7 +4875,6 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, 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, diff --git a/source3/rpc_server/rpc_ncacn_np_internal.c b/source3/rpc_server/rpc_ncacn_np_internal.c index f9317b9756d..d702e4b4d7b 100644 --- a/source3/rpc_server/rpc_ncacn_np_internal.c +++ b/source3/rpc_server/rpc_ncacn_np_internal.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "rpc_server/srv_pipe_internal.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -186,6 +187,155 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, 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. * @@ -217,10 +367,6 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, */ 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) { @@ -233,7 +379,7 @@ NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, 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); diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index cccd0d570ae..c7ff3ddeeb5 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -406,7 +406,7 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p, 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; @@ -629,7 +629,7 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct, 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; @@ -1032,7 +1032,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, 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; diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index e9339929dff..9ed54a4e104 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1411,7 +1411,6 @@ NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn, 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)) { diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c index 4c70ce4edb8..49f6a71433d 100644 --- a/source3/rpc_server/srv_spoolss_util.c +++ b/source3/rpc_server/srv_spoolss_util.c @@ -250,7 +250,6 @@ static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx, /* 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)) { diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index ba51c617df4..ce7ad0e56d2 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -2235,7 +2235,7 @@ static bool api_RNetShareAdd(struct smbd_server_connection *sconn, } 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", @@ -2341,7 +2341,7 @@ static bool api_RNetGroupEnum(struct smbd_server_connection *sconn, } 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", @@ -2523,7 +2523,7 @@ static bool api_NetUserGetGroups(struct smbd_server_connection *sconn, 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", @@ -2679,7 +2679,7 @@ static bool api_RNetUserEnum(struct smbd_server_connection *sconn, 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", @@ -2922,7 +2922,7 @@ static bool api_SetUserPassword(struct smbd_server_connection *sconn, 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", @@ -3138,7 +3138,7 @@ static bool api_SamOEMChangePassword(struct smbd_server_connection *sconn, 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", @@ -3691,7 +3691,7 @@ static bool api_RNetServerGetInfo(struct smbd_server_connection *sconn, 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", @@ -4113,7 +4113,7 @@ static bool api_RNetUserGetInfo(struct smbd_server_connection *sconn, 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", diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 25d4e1d3d4a..7e1eb3e7140 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -26,6 +26,8 @@ #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 @@ -1289,6 +1291,9 @@ int main(int argc, char **argv, char **envp) 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); diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index a2865a0bca8..e9e3e6f30d5 100644 --- a/source3/winbindd/winbindd_samr.c +++ b/source3/winbindd/winbindd_samr.c @@ -60,7 +60,6 @@ static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx, /* 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)) { @@ -132,7 +131,6 @@ static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx, /* 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)) {