mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
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
This commit is contained in:
parent
309ad2b08f
commit
690ed0c5e2
@ -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)";
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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)) {
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user