diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss.c | 22 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 174 |
3 files changed, 113 insertions, 84 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 8542fbb779..04182fba24 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6262,7 +6262,6 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u); WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u); WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u); -WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u); /* The following definitions come from rpc_server/srv_srvsvc_nt.c */ diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index c5d20e0d3d..10e983e72a 100644 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -974,27 +974,7 @@ static bool api_spoolss_deleteprinterdriverex(pipes_struct *p) static bool api_spoolss_xcvdataport(pipes_struct *p) { - SPOOL_Q_XCVDATAPORT q_u; - SPOOL_R_XCVDATAPORT r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!spoolss_io_q_xcvdataport("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_replyopenprinter: unable to unmarshall SPOOL_Q_XCVDATAPORT.\n")); - return False; - } - - r_u.status = _spoolss_xcvdataport(p, &q_u, &r_u); - - if(!spoolss_io_r_xcvdataport("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_replyopenprinter: unable to marshall SPOOL_R_XCVDATAPORT.\n")); - return False; - } - - return True; + return proxy_spoolss_call(p, NDR_SPOOLSS_XCVDATA); } /******************************************************************* diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 8faa1f5355..6019d1875f 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -69,7 +69,7 @@ extern struct standard_mapping printer_std_mapping, printserver_std_mapping; struct xcv_api_table { const char *name; - WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed); + WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed); }; /******************************************************************** @@ -9826,21 +9826,41 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC } /******************************************************************* + ********************************************************************/ + +static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf, + const char *dllname) +{ + enum ndr_err_code ndr_err; + struct spoolss_MonitorUi ui; + + ui.dll_name = dllname; + + ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui, + (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) { + NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui); + } + return NDR_ERR_CODE_IS_SUCCESS(ndr_err); +} + +/******************************************************************* Streams the monitor UI DLL name in UNICODE *******************************************************************/ -static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, - RPC_BUFFER *out, uint32 *needed ) +static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx, + NT_USER_TOKEN *token, DATA_BLOB *in, + DATA_BLOB *out, uint32_t *needed) { const char *dllname = "tcpmonui.dll"; *needed = (strlen(dllname)+1) * 2; - if ( rpcbuf_get_size(out) < *needed ) { + if (out->length < *needed) { return WERR_INSUFFICIENT_BUFFER; } - if ( !make_monitorui_buf( out, dllname ) ) { + if (!push_monitorui_buf(mem_ctx, out, dllname)) { return WERR_NOMEM; } @@ -9848,35 +9868,52 @@ static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, } /******************************************************************* + ********************************************************************/ + +static bool pull_port_data_1(TALLOC_CTX *mem_ctx, + struct spoolss_PortData1 *port1, + const DATA_BLOB *buf) +{ + enum ndr_err_code ndr_err; + ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1, + (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) { + NDR_PRINT_DEBUG(spoolss_PortData1, port1); + } + return NDR_ERR_CODE_IS_SUCCESS(ndr_err); +} + +/******************************************************************* Create a new TCP/IP port *******************************************************************/ -static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in, - RPC_BUFFER *out, uint32 *needed ) +static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx, + NT_USER_TOKEN *token, DATA_BLOB *in, + DATA_BLOB *out, uint32_t *needed) { - NT_PORT_DATA_1 port1; - TALLOC_CTX *ctx = talloc_tos(); + struct spoolss_PortData1 port1; char *device_uri = NULL; - ZERO_STRUCT( port1 ); + ZERO_STRUCT(port1); /* convert to our internal port data structure */ - if ( !convert_port_data_1( &port1, in ) ) { + if (!pull_port_data_1(mem_ctx, &port1, in)) { return WERR_NOMEM; } /* create the device URI and call the add_port_hook() */ switch ( port1.protocol ) { - case PORT_PROTOCOL_DIRECT: - device_uri = talloc_asprintf(ctx, - "socket://%s:%d/", port1.hostaddr, port1.port ); + case PROTOCOL_RAWTCP_TYPE: + device_uri = talloc_asprintf(mem_ctx, + "socket://%s:%d/", port1.hostaddress, + port1.port_number); break; - case PORT_PROTOCOL_LPR: - device_uri = talloc_asprintf(ctx, - "lpr://%s/%s", port1.hostaddr, port1.queue ); + case PROTOCOL_LPR_TYPE: + device_uri = talloc_asprintf(mem_ctx, + "lpr://%s/%s", port1.hostaddress, port1.queue ); break; default: @@ -9887,7 +9924,7 @@ static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in, return WERR_NOMEM; } - return add_port_hook(ctx, token, port1.name, device_uri ); + return add_port_hook(mem_ctx, token, port1.portname, device_uri); } /******************************************************************* @@ -9899,9 +9936,11 @@ struct xcv_api_table xcvtcp_cmds[] = { { NULL, NULL } }; -static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command, - RPC_BUFFER *inbuf, RPC_BUFFER *outbuf, - uint32 *needed ) +static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx, + NT_USER_TOKEN *token, const char *command, + DATA_BLOB *inbuf, + DATA_BLOB *outbuf, + uint32_t *needed ) { int i; @@ -9909,7 +9948,7 @@ static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command, for ( i=0; xcvtcp_cmds[i].name; i++ ) { if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 ) - return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed ); + return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed); } return WERR_BADFUNC; @@ -9919,18 +9958,19 @@ static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command, *******************************************************************/ #if 0 /* don't support management using the "Local Port" monitor */ -static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, - RPC_BUFFER *out, uint32 *needed ) +static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx, + NT_USER_TOKEN *token, DATA_BLOB *in, + DATA_BLOB *out, uint32_t *needed) { const char *dllname = "localui.dll"; *needed = (strlen(dllname)+1) * 2; - if ( rpcbuf_get_size(out) < *needed ) { + if (out->length < *needed) { return WERR_INSUFFICIENT_BUFFER; } - if ( !make_monitorui_buf( out, dllname )) { + if (!push_monitorui_buf(mem_ctx, out, dllname)) { return WERR_NOMEM; } @@ -9955,9 +9995,10 @@ struct xcv_api_table xcvlocal_cmds[] = { /******************************************************************* *******************************************************************/ -static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command, - RPC_BUFFER *inbuf, RPC_BUFFER *outbuf, - uint32 *needed ) +static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx, + NT_USER_TOKEN *token, const char *command, + DATA_BLOB *inbuf, DATA_BLOB *outbuf, + uint32_t *needed) { int i; @@ -9965,59 +10006,79 @@ static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *comman for ( i=0; xcvlocal_cmds[i].name; i++ ) { if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 ) - return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed ); + return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed); } return WERR_BADFUNC; } -/******************************************************************* -*******************************************************************/ +/**************************************************************** + _spoolss_XcvData +****************************************************************/ -WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u) +WERROR _spoolss_XcvData(pipes_struct *p, + struct spoolss_XcvData *r) { - Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle); - fstring command; + Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); + DATA_BLOB out_data; + WERROR werror; if (!Printer) { - DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle))); + DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n", + OUR_HANDLE(r->in.handle))); return WERR_BADFID; } /* Has to be a handle to the TCP/IP port monitor */ if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) { - DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n")); + DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n")); return WERR_BADFID; } /* requires administrative access to the server */ if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) { - DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n")); + DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n")); return WERR_ACCESS_DENIED; } - /* Get the command name. There's numerous commands supported by the - TCPMON interface. */ - - rpcstr_pull(command, q_u->dataname.buffer, sizeof(command), - q_u->dataname.uni_str_len*2, 0); - /* Allocate the outgoing buffer */ - if (!rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx )) - return WERR_NOMEM; + if (r->in.out_data_size) { + out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size); + if (out_data.data == NULL) { + return WERR_NOMEM; + } + } switch ( Printer->printer_type ) { case SPLHND_PORTMON_TCP: - return process_xcvtcp_command( p->server_info->ptok, command, - &q_u->indata, &r_u->outdata, &r_u->needed ); + werror = process_xcvtcp_command(p->mem_ctx, + p->server_info->ptok, + r->in.function_name, + &r->in.in_data, &out_data, + r->out.needed); + break; case SPLHND_PORTMON_LOCAL: - return process_xcvlocal_command( p->server_info->ptok, command, - &q_u->indata, &r_u->outdata, &r_u->needed ); + werror = process_xcvlocal_command(p->mem_ctx, + p->server_info->ptok, + r->in.function_name, + &r->in.in_data, &out_data, + r->out.needed); + break; + default: + werror = WERR_INVALID_PRINT_MONITOR; + } + + if (!W_ERROR_IS_OK(werror)) { + return werror; } - return WERR_INVALID_PRINT_MONITOR; + *r->out.status_code = 0; + + memcpy(r->out.out_data, out_data.data, out_data.length); + + return WERR_OK; } /**************************************************************** @@ -10685,17 +10746,6 @@ WERROR _spoolss_57(pipes_struct *p, } /**************************************************************** - _spoolss_XcvData -****************************************************************/ - -WERROR _spoolss_XcvData(pipes_struct *p, - struct spoolss_XcvData *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** _spoolss_AddPrinterDriverEx ****************************************************************/ |