From 5685914344d21e5fdac98c367b3dd1eba555f227 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 6 Jul 2010 11:33:15 -0400 Subject: s3-rpc_server: Convert rpc_connect_spoolss_pipe into a generic interface. This way we have one common way to open internal pipes whether they are shortcircuited or piped to an external process. --- source3/include/proto.h | 8 +++- source3/printing/printspoolss.c | 25 +++++++++++-- source3/rpc_server/srv_pipe_hnd.c | 78 +++++++++++++++++++++++++-------------- source3/smbd/lanman.c | 63 ++++++++++++++++++++++++++----- source3/smbd/reply.c | 7 +++- 5 files changed, 138 insertions(+), 43 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 6a1ab0fe10..6fe8f641ba 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4163,8 +4163,12 @@ NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, struct client_address *client_id, struct messaging_context *msg_ctx, struct rpc_pipe_client **presult); -NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn, - struct rpc_pipe_client **spoolss_pipe); +NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx, + const struct ndr_syntax_id *syntax, + struct auth_serversupplied_info *server_info, + struct client_address *client_id, + struct messaging_context *msg_ctx, + struct rpc_pipe_client **cli_pipe); NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, const struct ndr_syntax_id *interface, struct rpc_pipe_client **presult); diff --git a/source3/printing/printspoolss.c b/source3/printing/printspoolss.c index e97b397cb0..62182865bf 100644 --- a/source3/printing/printspoolss.c +++ b/source3/printing/printspoolss.c @@ -20,6 +20,7 @@ #include "includes.h" #include "printing.h" #include "../librpc/gen_ndr/cli_spoolss.h" +#include "smbd/globals.h" void print_spool_terminate(struct connection_struct *conn, struct print_file_data *print_file); @@ -120,10 +121,16 @@ NTSTATUS print_spool_open(files_struct *fsp, * all printer verification, and eventually assigns * a job id */ - status = rpc_connect_spoolss_pipe(fsp->conn, &cli); + status = rpc_pipe_open_interface(fsp->conn, + &ndr_table_spoolss.syntax_id, + fsp->conn->server_info, + &fsp->conn->sconn->client_id, + fsp->conn->sconn->msg_ctx, + &fsp->conn->spoolss_pipe); if (!NT_STATUS_IS_OK(status)) { goto done; } + cli = fsp->conn->spoolss_pipe; ZERO_STRUCT(devmode_ctr); @@ -265,13 +272,19 @@ void print_spool_end(files_struct *fsp, enum file_close_type close_type) NTSTATUS status; WERROR werr; - status = rpc_connect_spoolss_pipe(fsp->conn, &cli); + status = rpc_pipe_open_interface(fsp->conn, + &ndr_table_spoolss.syntax_id, + fsp->conn->server_info, + &fsp->conn->sconn->client_id, + fsp->conn->sconn->msg_ctx, + &fsp->conn->spoolss_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("print_spool_end: " "Failed to get spoolss pipe [%s]\n", nt_errstr(status))); return; } + cli = fsp->conn->spoolss_pipe; switch (close_type) { case NORMAL_CLOSE: @@ -302,13 +315,19 @@ void print_spool_terminate(struct connection_struct *conn, rap_jobid_delete(print_file->svcname, print_file->jobid); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &conn->spoolss_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("print_spool_terminate: " "Failed to get spoolss pipe [%s]\n", nt_errstr(status))); return; } + cli = &conn->spoolss_pipe; status = rpccli_spoolss_SetJob(cli, print_file, &print_file->handle, diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index df53489383..9b471d959d 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -996,56 +996,78 @@ done: /** * @brief Create a new RPC client context which uses a local dispatch function. * - * @param[in] conn The connection struct that will hold the pipe + * @param mem_ctx The memory context on which thje pipe will ultimately + * be allocated + * @param name The pipe name to connect to. + * @param server_info Credentials to use for the connection. + * @param pipe [in|out] Checks if a pipe is connected, and connects it + * if not * - * @param[out] spoolss_pipe A pointer to the connected rpc client pipe. - * - * @return NT_STATUS_OK on success, a corresponding NT status if an - * error occured. + * @return NT_STATUS_OK on success, a corresponding NT status if + * an error occured. */ -NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn, - struct rpc_pipe_client **spoolss_pipe) + +NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx, + const struct ndr_syntax_id *syntax, + struct auth_serversupplied_info *server_info, + struct client_address *client_id, + struct messaging_context *msg_ctx, + struct rpc_pipe_client **cli_pipe) { + TALLOC_CTX *tmpctx; const char *server_type; + const char *pipe_name; NTSTATUS status; - DEBUG(10, ("Connecting to spoolss pipe.\n")); - *spoolss_pipe = NULL; - - if (rpccli_is_connected(conn->spoolss_pipe)) { - *spoolss_pipe = conn->spoolss_pipe; + if (rpccli_is_connected(*cli_pipe)) { return NT_STATUS_OK; } else { - TALLOC_FREE(conn->spoolss_pipe); + TALLOC_FREE(*cli_pipe); + } + + tmpctx = talloc_new(mem_ctx); + if (!tmpctx) { + return NT_STATUS_NO_MEMORY; + } + + pipe_name = get_pipe_name_from_syntax(tmpctx, syntax); + if (!pipe_name) { + TALLOC_FREE(tmpctx); + return NT_STATUS_INVALID_PARAMETER; } + DEBUG(10, ("Connecting to %s pipe.\n", pipe_name)); + server_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, - "rpc_server", "spoolss", + "rpc_server", pipe_name, "embedded"); if (StrCaseCmp(server_type, "embedded") == 0) { - status = rpc_pipe_open_internal(conn, - &ndr_table_spoolss.syntax_id, - conn->server_info, - &conn->sconn->client_id, - conn->sconn->msg_ctx, - &conn->spoolss_pipe); + status = rpc_pipe_open_internal(tmpctx, + syntax, server_info, + client_id, msg_ctx, + cli_pipe); if (!NT_STATUS_IS_OK(status)) { - return status; + goto done; } } else { /* It would be nice to just use rpc_pipe_open_ncalrpc() but * for now we need to use the special proxy setup to connect * to spoolssd. */ - status = rpc_pipe_open_external(conn, "spoolss", - &ndr_table_spoolss.syntax_id, - conn->server_info, - &conn->spoolss_pipe); + status = rpc_pipe_open_external(tmpctx, + pipe_name, syntax, + server_info, + cli_pipe); if (!NT_STATUS_IS_OK(status)) { - return status; + goto done; } } - *spoolss_pipe = conn->spoolss_pipe; - return NT_STATUS_OK; + status = NT_STATUS_OK; +done: + if (NT_STATUS_IS_OK(status)) { + talloc_steal(mem_ctx, *cli_pipe); + } + TALLOC_FREE(tmpctx); + return status; } diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 1c7d08db37..fd69d247d2 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -825,7 +825,12 @@ static bool api_DosPrintQGetInfo(struct smbd_server_connection *sconn, goto out; } - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_DosPrintQGetInfo: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -1015,7 +1020,12 @@ static bool api_DosPrintQEnum(struct smbd_server_connection *sconn, return(True); } - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_DosPrintQEnum: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -3233,7 +3243,12 @@ static bool api_RDosPrintJobDel(struct smbd_server_connection *sconn, ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_RDosPrintJobDel: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -3354,7 +3369,12 @@ static bool api_WPrintQueueCtrl(struct smbd_server_connection *sconn, ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_WPrintQueueCtrl: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -3529,7 +3549,12 @@ static bool api_PrintJobInfo(struct smbd_server_connection *sconn, ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_PrintJobInfo: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -4617,7 +4642,12 @@ static bool api_WPrintJobGetInfo(struct smbd_server_connection *sconn, ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_WPrintJobGetInfo: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -4752,7 +4782,12 @@ static bool api_WPrintJobEnumerate(struct smbd_server_connection *sconn, ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_WPrintJobEnumerate: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -4945,7 +4980,12 @@ static bool api_WPrintDestGetInfo(struct smbd_server_connection *sconn, ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_WPrintDestGetInfo: could not connect to spoolss: %s\n", nt_errstr(status))); @@ -5071,7 +5111,12 @@ static bool api_WPrintDestEnum(struct smbd_server_connection *sconn, queuecnt = 0; - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("api_WPrintDestEnum: could not connect to spoolss: %s\n", nt_errstr(status))); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index df7dac7b09..4ace452ed9 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -5294,7 +5294,12 @@ void reply_printqueue(struct smb_request *req) ZERO_STRUCT(handle); - status = rpc_connect_spoolss_pipe(conn, &cli); + status = rpc_pipe_open_interface(conn, + &ndr_table_spoolss.syntax_id, + conn->server_info, + &conn->sconn->client_id, + conn->sconn->msg_ctx, + &cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("reply_printqueue: " "could not connect to spoolss: %s\n", -- cgit