From b74f2bfeb8b6c0f77c4dd5e586e7ed98460a41f5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 15 Mar 2005 19:43:44 +0000 Subject: [PATCH] r5805: merging spoolss parsing changes from trunk and cleaning up resulting segvs --- source/Makefile.in | 2 +- source/include/ntdomain.h | 1 + source/include/rpc_buffer.h | 38 ++ source/include/rpc_spoolss.h | 74 ++- source/rpc_client/cli_spoolss.c | 84 ++-- source/rpc_parse/parse_buffer.c | 512 +++++++++++++++++++++ source/rpc_parse/parse_misc.c | 19 + source/rpc_parse/parse_prs.c | 28 ++ source/rpc_parse/parse_sec.c | 2 +- source/rpc_parse/parse_spoolss.c | 554 +++------------------- source/rpc_server/srv_spoolss_nt.c | 908 +++++++++++++++++++++---------------- 11 files changed, 1244 insertions(+), 978 deletions(-) create mode 100644 source/include/rpc_buffer.h create mode 100644 source/rpc_parse/parse_buffer.c diff --git a/source/Makefile.in b/source/Makefile.in index fda2bd3d93a..8c06832eea9 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -298,7 +298,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \ rpc_parse/parse_wks.o rpc_parse/parse_ds.o \ rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \ rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \ - $(REGOBJS_OBJ) + rpc_parse/parse_buffer.o $(REGOBJS_OBJ) RPC_CLIENT_OBJ = rpc_client/cli_pipe.o diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h index 45d64cf6331..9f0cbe6160d 100644 --- a/source/include/ntdomain.h +++ b/source/include/ntdomain.h @@ -391,6 +391,7 @@ typedef struct { #include "authdata.h" /* different dce/rpc pipes */ +#include "rpc_buffer.h" #include "rpc_lsa.h" #include "rpc_netlogon.h" #include "rpc_reg.h" diff --git a/source/include/rpc_buffer.h b/source/include/rpc_buffer.h new file mode 100644 index 00000000000..819c4d5b18a --- /dev/null +++ b/source/include/rpc_buffer.h @@ -0,0 +1,38 @@ +/* + Unix SMB/Netbios implementation. + + Copyright (C) Andrew Tridgell 1992-2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + Copyright (C) Jean Francois Micouleau 1998-2000. + Copyright (C) Gerald Carter 2001-2005. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _RPC_BUFFER_H /* _RPC_SPOOLSS_H */ +#define _RPC_BUFFER_H + +typedef struct { +#if 0 + uint32 ptr; +#endif + uint32 size; + prs_struct prs; + uint32 struct_start; + uint32 string_at_end; +} RPC_BUFFER; + + +#endif /* _RPC_BUFFER_H */ diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index 7c5942759f4..5d74a30fbdc 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -1,11 +1,10 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-2000, Copyright (C) Luke Kenneth Casson Leighton 1996-2000, Copyright (C) Jean Francois Micouleau 1998-2000. - Copyright (C) Gerald Carter 2001-2002. + Copyright (C) Gerald Carter 2001-2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -614,15 +613,6 @@ typedef struct s_header_type } HEADER_TYPE; -typedef struct new_buffer -{ - uint32 ptr; - uint32 size; - prs_struct prs; - uint32 struct_start; - uint32 string_at_end; -} -NEW_BUFFER; typedef struct spool_q_getprinterdata { @@ -1014,7 +1004,7 @@ typedef struct spool_q_enumprinters uint32 servername_ptr; UNISTR2 servername; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMPRINTERS; @@ -1033,7 +1023,7 @@ PRINTER_INFO_CTR; typedef struct spool_r_enumprinters { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; /* bytes needed */ uint32 returned; /* number of printers */ WERROR status; @@ -1045,7 +1035,7 @@ typedef struct spool_q_getprinter { POLICY_HND handle; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_GETPRINTER; @@ -1063,7 +1053,7 @@ typedef struct printer_info_info typedef struct spool_r_getprinter { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; WERROR status; } SPOOL_R_GETPRINTER; @@ -1137,7 +1127,7 @@ typedef struct spool_q_getprinterdriver2 uint32 architecture_ptr; UNISTR2 architecture; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; uint32 clientmajorversion; uint32 clientminorversion; @@ -1146,7 +1136,7 @@ SPOOL_Q_GETPRINTERDRIVER2; typedef struct spool_r_getprinterdriver2 { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 servermajorversion; uint32 serverminorversion; @@ -1167,14 +1157,14 @@ typedef struct spool_q_addjob { POLICY_HND handle; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ADDJOB; typedef struct spool_r_addjob { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; WERROR status; } @@ -1251,7 +1241,7 @@ typedef struct spool_q_enumjobs uint32 firstjob; uint32 numofjobs; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMJOBS; @@ -1269,7 +1259,7 @@ typedef struct job_info_ctr_info typedef struct spool_r_enumjobs { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 returned; WERROR status; @@ -1316,7 +1306,7 @@ typedef struct spool_q_enumports uint32 name_ptr; UNISTR2 name; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMPORTS; @@ -1335,7 +1325,7 @@ PORT_INFO_CTR; typedef struct spool_r_enumports { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; /* bytes needed */ uint32 returned; /* number of printers */ WERROR status; @@ -1385,14 +1375,14 @@ typedef struct spool_q_enumprinterdrivers uint32 environment_ptr; UNISTR2 environment; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMPRINTERDRIVERS; typedef struct spool_r_enumprinterdrivers { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 returned; WERROR status; @@ -1420,14 +1410,14 @@ typedef struct spool_q_enumforms { POLICY_HND handle; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMFORMS; typedef struct spool_r_enumforms { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 numofforms; WERROR status; @@ -1439,14 +1429,14 @@ typedef struct spool_q_getform POLICY_HND handle; UNISTR2 formname; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_GETFORM; typedef struct spool_r_getform { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; WERROR status; } @@ -1758,14 +1748,14 @@ typedef struct spool_q_getprinterdriverdirectory uint32 environment_ptr; UNISTR2 environment; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_GETPRINTERDRIVERDIR; typedef struct spool_r_getprinterdriverdirectory { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; WERROR status; } @@ -1795,7 +1785,7 @@ typedef struct spool_q_enumprintprocessors uint32 environment_ptr; UNISTR2 environment; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMPRINTPROCESSORS; @@ -1808,7 +1798,7 @@ PRINTPROCESSOR_1; typedef struct spool_r_enumprintprocessors { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 returned; WERROR status; @@ -1822,7 +1812,7 @@ typedef struct spool_q_enumprintprocdatatypes uint32 processor_ptr; UNISTR2 processor; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMPRINTPROCDATATYPES; @@ -1835,7 +1825,7 @@ PRINTPROCDATATYPE_1; typedef struct spool_r_enumprintprocdatatypes { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 returned; WERROR status; @@ -1861,14 +1851,14 @@ typedef struct spool_q_enumprintmonitors uint32 name_ptr; UNISTR2 name; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_ENUMPRINTMONITORS; typedef struct spool_r_enumprintmonitors { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; uint32 returned; WERROR status; @@ -1996,7 +1986,7 @@ typedef struct spool_q_getjob POLICY_HND handle; uint32 jobid; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_GETJOB; @@ -2016,7 +2006,7 @@ PJOB_INFO; typedef struct spool_r_getjob { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; WERROR status; } @@ -2217,14 +2207,14 @@ typedef struct spool_q_getprintprocessordirectory UNISTR2 name; UNISTR2 environment; uint32 level; - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 offered; } SPOOL_Q_GETPRINTPROCESSORDIRECTORY; typedef struct spool_r_getprintprocessordirectory { - NEW_BUFFER *buffer; + RPC_BUFFER *buffer; uint32 needed; WERROR status; } diff --git a/source/rpc_client/cli_spoolss.c b/source/rpc_client/cli_spoolss.c index 8094b2bf087..ac2d5bd31e6 100644 --- a/source/rpc_client/cli_spoolss.c +++ b/source/rpc_client/cli_spoolss.c @@ -31,25 +31,13 @@ * @{ **/ -/********************************************************************** - Initialize a new spoolss buff for use by a client rpc -**********************************************************************/ -static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) -{ - buffer->ptr = (size != 0); - buffer->size = size; - buffer->string_at_end = size; - prs_init(&buffer->prs, size, ctx, MARSHALL); - buffer->struct_start = prs_offset(&buffer->prs); -} - /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ /********************************************************************** **********************************************************************/ -static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PRINTER_INFO_0 **info) { uint32 i; @@ -69,7 +57,7 @@ static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PRINTER_INFO_1 **info) { uint32 i; @@ -89,7 +77,7 @@ static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PRINTER_INFO_2 **info) { uint32 i; @@ -111,7 +99,7 @@ static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PRINTER_INFO_3 **info) { uint32 i; @@ -132,7 +120,7 @@ static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_info_7(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PRINTER_INFO_7 **info) { uint32 i; @@ -153,7 +141,7 @@ static void decode_printer_info_7(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PORT_INFO_1 **info) { uint32 i; @@ -173,7 +161,7 @@ static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PORT_INFO_2 **info) { uint32 i; @@ -193,7 +181,7 @@ static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, DRIVER_INFO_1 **info) { uint32 i; @@ -213,7 +201,7 @@ static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, DRIVER_INFO_2 **info) { uint32 i; @@ -233,7 +221,7 @@ static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, DRIVER_INFO_3 **info) { uint32 i; @@ -253,7 +241,7 @@ static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, DRIVER_DIRECTORY_1 **info ) { @@ -430,7 +418,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERS q; SPOOL_R_ENUMPRINTERS r; - NEW_BUFFER buffer; + RPC_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); @@ -438,7 +426,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -525,7 +513,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SPOOL_Q_ENUMPORTS q; SPOOL_R_ENUMPORTS r; - NEW_BUFFER buffer; + RPC_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); fstring server; @@ -537,7 +525,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -600,7 +588,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTER q; SPOOL_R_GETPRINTER r; - NEW_BUFFER buffer; + RPC_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); @@ -608,7 +596,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -749,7 +737,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDRIVER2 q; SPOOL_R_GETPRINTERDRIVER2 r; - NEW_BUFFER buffer; + RPC_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); fstring server; @@ -761,7 +749,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -830,7 +818,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERDRIVERS q; SPOOL_R_ENUMPRINTERDRIVERS r; - NEW_BUFFER buffer; + RPC_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); fstring server; @@ -842,7 +830,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -916,7 +904,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDRIVERDIR q; SPOOL_R_GETPRINTERDRIVERDIR r; - NEW_BUFFER buffer; + RPC_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); fstring server; @@ -928,7 +916,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -1204,7 +1192,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, SPOOL_R_GETPRINTPROCESSORDIRECTORY r; int level = 1; WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; + RPC_BUFFER buffer; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -1216,7 +1204,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, /* Initialise input parameters */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); make_spoolss_q_getprintprocessordirectory( &q, name, environment, level, &buffer, offered); @@ -1388,14 +1376,14 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, SPOOL_Q_GETFORM q; SPOOL_R_GETFORM r; WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; + RPC_BUFFER buffer; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -1494,7 +1482,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 num_forms, FORM_1 **forms) { int i; @@ -1530,14 +1518,14 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, SPOOL_Q_ENUMFORMS q; SPOOL_R_ENUMFORMS r; WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; + RPC_BUFFER buffer; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -1576,7 +1564,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 num_jobs, JOB_INFO_1 **jobs) { uint32 i; @@ -1588,7 +1576,7 @@ static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); } -static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, +static void decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 num_jobs, JOB_INFO_2 **jobs) { uint32 i; @@ -1611,14 +1599,14 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, SPOOL_Q_ENUMJOBS q; SPOOL_R_ENUMJOBS r; WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; + RPC_BUFFER buffer; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -1728,14 +1716,14 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, SPOOL_Q_GETJOB q; SPOOL_R_GETJOB r; WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; + RPC_BUFFER buffer; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ - init_buffer(&buffer, offered, mem_ctx); + rpcbuf_init(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); diff --git a/source/rpc_parse/parse_buffer.c b/source/rpc_parse/parse_buffer.c new file mode 100644 index 00000000000..d3584c3954a --- /dev/null +++ b/source/rpc_parse/parse_buffer.c @@ -0,0 +1,512 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + * Copyright (C) Jean François Micouleau 1998-2000, + * Copyright (C) Gerald Carter 2000-2005, + * Copyright (C) Tim Potter 2001-2002. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + +/********************************************************************** + Initialize a new spoolss buff for use by a client rpc +**********************************************************************/ +void rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) +{ +#if 0 + buffer->ptr = (size != 0); +#endif + buffer->size = size; + buffer->string_at_end = size; + prs_init(&buffer->prs, size, ctx, MARSHALL); + buffer->struct_start = prs_offset(&buffer->prs); +} + +/******************************************************************* + Read/write a RPC_BUFFER struct. +********************************************************************/ + +BOOL prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer) +{ + prs_debug(ps, depth, desc, "prs_rpcbuffer"); + depth++; + + /* reading */ + if (UNMARSHALLING(ps)) { + buffer->size=0; + buffer->string_at_end=0; + +#if 0 + if (buffer->ptr==0) { + /* + * JRA. I'm not sure if the data in here is in big-endian format if + * the client is big-endian. Leave as default (little endian) for now. + */ + + if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL)) + return False; + return True; + } +#endif + + if (!prs_uint32("size", ps, depth, &buffer->size)) + return False; + + /* + * JRA. I'm not sure if the data in here is in big-endian format if + * the client is big-endian. Leave as default (little endian) for now. + */ + + if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL)) + return False; + + if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size)) + return False; + + if (!prs_set_offset(&buffer->prs, 0)) + return False; + + if (!prs_set_offset(ps, buffer->size+prs_offset(ps))) + return False; + + buffer->string_at_end=buffer->size; + + return True; + } + else { + BOOL ret = False; + +#if 0 + /* writing */ + if (buffer->ptr==0) { + /* We have finished with the data in buffer->prs - free it. */ + prs_mem_free(&buffer->prs); + return True; + } +#endif + + if (!prs_uint32("size", ps, depth, &buffer->size)) + goto out; + + if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size)) + goto out; + + ret = True; + out: + + /* We have finished with the data in buffer->prs - free it. */ + prs_mem_free(&buffer->prs); + + return ret; + } +} + +/******************************************************************* + Read/write an RPC_BUFFER* struct.(allocate memory if unmarshalling) +********************************************************************/ + +BOOL prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer) +{ + uint32 data_p; + + /* caputure the pointer value to stream */ + + data_p = (uint32) *buffer; + + if ( !prs_uint32("ptr", ps, depth, &data_p )) + return False; + + /* we're done if there is no data */ + + if ( !data_p ) + return True; + + if ( UNMARSHALLING(ps) ) { + if ( !(*buffer = PRS_ALLOC_MEM(ps, RPC_BUFFER, 1)) ) + return False; + } + + return prs_rpcbuffer( desc, ps, depth, *buffer); +} + +/**************************************************************************** + Allocate more memory for a RPC_BUFFER. +****************************************************************************/ + +BOOL rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size) +{ + prs_struct *ps; + uint32 extra_space; + uint32 old_offset; + + ps= &buffer->prs; + + /* damn, I'm doing the reverse operation of prs_grow() :) */ + if (buffer_size < prs_data_size(ps)) + extra_space=0; + else + extra_space = buffer_size - prs_data_size(ps); + + /* + * save the offset and move to the end of the buffer + * prs_grow() checks the extra_space against the offset + */ + old_offset=prs_offset(ps); + prs_set_offset(ps, prs_data_size(ps)); + + if (!prs_grow(ps, extra_space)) + return False; + + prs_set_offset(ps, old_offset); + + buffer->string_at_end=prs_data_size(ps); + + return True; +} + +/******************************************************************* + move a BUFFER from the query to the reply. + As the data pointers in RPC_BUFFER are malloc'ed, not talloc'ed, + this is ok. This is an OPTIMIZATION and is not strictly neccessary. + Clears the memory to zero also. +********************************************************************/ + +void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest) +{ + if ( !src ) + return; + + prs_switch_type(&src->prs, MARSHALL); + if(!prs_set_offset(&src->prs, 0)) + return; + prs_force_dynamic(&src->prs); + prs_mem_clear(&src->prs); + *dest=src; +} + +/******************************************************************* + Get the size of a BUFFER struct. +********************************************************************/ + +uint32 rpcbuf_get_size(RPC_BUFFER *buffer) +{ + return (buffer->size); +} + + +/******************************************************************* + * write a UNICODE string and its relative pointer. + * used by all the RPC structs passing a buffer + * + * As I'm a nice guy, I'm forcing myself to explain this code. + * MS did a good job in the overall spoolss code except in some + * functions where they are passing the API buffer directly in the + * RPC request/reply. That's to maintain compatiility at the API level. + * They could have done it the good way the first time. + * + * So what happen is: the strings are written at the buffer's end, + * in the reverse order of the original structure. Some pointers to + * the strings are also in the buffer. Those are relative to the + * buffer's start. + * + * If you don't understand or want to change that function, + * first get in touch with me: jfm@samba.org + * + ********************************************************************/ + +BOOL smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string) +{ + prs_struct *ps=&buffer->prs; + + if (MARSHALLING(ps)) { + uint32 struct_offset = prs_offset(ps); + uint32 relative_offset; + + buffer->string_at_end -= (size_of_relative_string(string) - 4); + if(!prs_set_offset(ps, buffer->string_at_end)) + return False; +#if 0 /* JERRY */ + /* + * Win2k does not align strings in a buffer + * Tested against WinNT 4.0 SP 6a & 2k SP2 --jerry + */ + if (!prs_align(ps)) + return False; +#endif + buffer->string_at_end = prs_offset(ps); + + /* write the string */ + if (!smb_io_unistr(desc, string, ps, depth)) + return False; + + if(!prs_set_offset(ps, struct_offset)) + return False; + + relative_offset=buffer->string_at_end - buffer->struct_start; + /* write its offset */ + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + } + else { + uint32 old_offset; + + /* read the offset */ + if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end))) + return False; + + if (buffer->string_at_end == 0) + return True; + + old_offset = prs_offset(ps); + if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start)) + return False; + + /* read the string */ + if (!smb_io_unistr(desc, string, ps, depth)) + return False; + + if(!prs_set_offset(ps, old_offset)) + return False; + } + return True; +} + +/******************************************************************* + * write a array of UNICODE strings and its relative pointer. + * used by 2 RPC structs + ********************************************************************/ + +BOOL smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string) +{ + UNISTR chaine; + + prs_struct *ps=&buffer->prs; + + if (MARSHALLING(ps)) { + uint32 struct_offset = prs_offset(ps); + uint32 relative_offset; + uint16 *p; + uint16 *q; + uint16 zero=0; + p=*string; + q=*string; + + /* first write the last 0 */ + buffer->string_at_end -= 2; + if(!prs_set_offset(ps, buffer->string_at_end)) + return False; + + if(!prs_uint16("leading zero", ps, depth, &zero)) + return False; + + while (p && (*p!=0)) { + while (*q!=0) + q++; + + /* Yes this should be malloc not talloc. Don't change. */ + + chaine.buffer = SMB_MALLOC((q-p+1)*sizeof(uint16)); + if (chaine.buffer == NULL) + return False; + + memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); + + buffer->string_at_end -= (q-p+1)*sizeof(uint16); + + if(!prs_set_offset(ps, buffer->string_at_end)) { + SAFE_FREE(chaine.buffer); + return False; + } + + /* write the string */ + if (!smb_io_unistr(desc, &chaine, ps, depth)) { + SAFE_FREE(chaine.buffer); + return False; + } + q++; + p=q; + + SAFE_FREE(chaine.buffer); + } + + if(!prs_set_offset(ps, struct_offset)) + return False; + + relative_offset=buffer->string_at_end - buffer->struct_start; + /* write its offset */ + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + + } else { + + /* UNMARSHALLING */ + + uint32 old_offset; + uint16 *chaine2=NULL; + int l_chaine=0; + int l_chaine2=0; + size_t realloc_size = 0; + + *string=NULL; + + /* read the offset */ + if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) + return False; + + old_offset = prs_offset(ps); + if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) + return False; + + do { + if (!smb_io_unistr(desc, &chaine, ps, depth)) + return False; + + l_chaine=str_len_uni(&chaine); + + /* we're going to add two more bytes here in case this + is the last string in the array and we need to add + an extra NULL for termination */ + if (l_chaine > 0) + { + uint16 *tc2; + + realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16); + + /* Yes this should be realloc - it's freed below. JRA */ + + if((tc2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) { + SAFE_FREE(chaine2); + return False; + } + else chaine2 = tc2; + memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); + l_chaine2+=l_chaine+1; + } + + } while(l_chaine!=0); + + /* the end should be bould NULL terminated so add + the second one here */ + if (chaine2) + { + chaine2[l_chaine2] = '\0'; + *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size); + SAFE_FREE(chaine2); + } + + if(!prs_set_offset(ps, old_offset)) + return False; + } + return True; +} + +/******************************************************************* + Parse a DEVMODE structure and its relative pointer. +********************************************************************/ + +BOOL smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc) +{ + prs_struct *ps= &buffer->prs; + + prs_debug(ps, depth, desc, "smb_io_relsecdesc"); + depth++; + + if (MARSHALLING(ps)) { + uint32 struct_offset = prs_offset(ps); + uint32 relative_offset; + + if (! *secdesc) { + relative_offset = 0; + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + return True; + } + + if (*secdesc != NULL) { + buffer->string_at_end -= sec_desc_size(*secdesc); + + if(!prs_set_offset(ps, buffer->string_at_end)) + return False; + /* write the secdesc */ + if (!sec_io_desc(desc, secdesc, ps, depth)) + return False; + + if(!prs_set_offset(ps, struct_offset)) + return False; + } + + relative_offset=buffer->string_at_end - buffer->struct_start; + /* write its offset */ + + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + } else { + uint32 old_offset; + + /* read the offset */ + if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) + return False; + + old_offset = prs_offset(ps); + if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) + return False; + + /* read the sd */ + if (!sec_io_desc(desc, secdesc, ps, depth)) + return False; + + if(!prs_set_offset(ps, old_offset)) + return False; + } + return True; +} + + + +/******************************************************************* + * return the length of a UNICODE string in number of char, includes: + * - the leading zero + * - the relative pointer size + ********************************************************************/ + +uint32 size_of_relative_string(UNISTR *string) +{ + uint32 size=0; + + size=str_len_uni(string); /* the string length */ + size=size+1; /* add the trailing zero */ + size=size*2; /* convert in char */ + size=size+4; /* add the size of the ptr */ + +#if 0 /* JERRY */ + /* + * Do not include alignment as Win2k does not align relative + * strings within a buffer --jerry + */ + /* Ensure size is 4 byte multiple (prs_align is being called...). */ + /* size += ((4 - (size & 3)) & 3); */ +#endif + + return size; +} + diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c index bca40a64c82..dec20769b6d 100644 --- a/source/rpc_parse/parse_misc.c +++ b/source/rpc_parse/parse_misc.c @@ -1797,3 +1797,22 @@ BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer) return True; } + +/******************************************************************* +return the length of a UNISTR string. +********************************************************************/ + +uint32 str_len_uni(UNISTR *source) +{ + uint32 i=0; + + if (!source->buffer) + return 0; + + while (source->buffer[i]) + i++; + + return i; +} + + diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index 4b78d373bab..566efae7a9e 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -647,6 +647,34 @@ BOOL prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32) } /******************************************************************* + Stream a uint32* (allocate memory if unmarshalling) + ********************************************************************/ + +BOOL prs_uint32_p(const char *name, prs_struct *ps, int depth, uint32 **data32) +{ + uint32 data_p; + + /* caputure the pointer value to stream */ + + data_p = (uint32) *data32; + + if ( !prs_uint32("ptr", ps, depth, &data_p )) + return False; + + /* we're done if there is no data */ + + if ( !data_p ) + return True; + + if (UNMARSHALLING(ps)) { + if ( !(*data32 = PRS_ALLOC_MEM(ps, uint32, 1)) ) + return False; + } + + return prs_uint32(name, ps, depth, *data32); +} + +/******************************************************************* Stream a NTSTATUS ********************************************************************/ diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c index f6fdf102928..6a752688a0b 100644 --- a/source/rpc_parse/parse_sec.c +++ b/source/rpc_parse/parse_sec.c @@ -133,7 +133,7 @@ BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) * Note that the size is always a multiple of 4 bytes due to the * nature of the data structure. Therefore the prs_align() calls * have been removed as they through us off when doing two-layer - * marshalling such as in the printing code (NEW_BUFFER). --jerry + * marshalling such as in the printing code (RPC_BUFFER). --jerry */ if (ppsa == NULL) diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index 2e5244d6532..02790749464 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -27,22 +27,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_PARSE -/******************************************************************* -return the length of a UNISTR string. -********************************************************************/ - -static uint32 str_len_uni(UNISTR *source) -{ - uint32 i=0; - - if (!source->buffer) - return 0; - - while (source->buffer[i]) - i++; - - return i; -} /******************************************************************* This should be moved in a more generic lib. @@ -2068,33 +2052,6 @@ static uint32 size_of_nttime(NTTIME *value) } /******************************************************************* - * return the length of a UNICODE string in number of char, includes: - * - the leading zero - * - the relative pointer size - ********************************************************************/ - -static uint32 size_of_relative_string(UNISTR *string) -{ - uint32 size=0; - - size=str_len_uni(string); /* the string length */ - size=size+1; /* add the trailing zero */ - size=size*2; /* convert in char */ - size=size+4; /* add the size of the ptr */ - -#if 0 /* JERRY */ - /* - * Do not include alignment as Win2k does not align relative - * strings within a buffer --jerry - */ - /* Ensure size is 4 byte multiple (prs_align is being called...). */ - /* size += ((4 - (size & 3)) & 3); */ -#endif - - return size; -} - -/******************************************************************* * return the length of a uint32 (obvious, but the code is clean) ********************************************************************/ @@ -2119,277 +2076,10 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime) } /******************************************************************* - * write a UNICODE string and its relative pointer. - * used by all the RPC structs passing a buffer - * - * As I'm a nice guy, I'm forcing myself to explain this code. - * MS did a good job in the overall spoolss code except in some - * functions where they are passing the API buffer directly in the - * RPC request/reply. That's to maintain compatiility at the API level. - * They could have done it the good way the first time. - * - * So what happen is: the strings are written at the buffer's end, - * in the reverse order of the original structure. Some pointers to - * the strings are also in the buffer. Those are relative to the - * buffer's start. - * - * If you don't understand or want to change that function, - * first get in touch with me: jfm@samba.org - * - ********************************************************************/ - -static BOOL smb_io_relstr(const char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string) -{ - prs_struct *ps=&buffer->prs; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - - buffer->string_at_end -= (size_of_relative_string(string) - 4); - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; -#if 0 /* JERRY */ - /* - * Win2k does not align strings in a buffer - * Tested against WinNT 4.0 SP 6a & 2k SP2 --jerry - */ - if (!prs_align(ps)) - return False; -#endif - buffer->string_at_end = prs_offset(ps); - - /* write the string */ - if (!smb_io_unistr(desc, string, ps, depth)) - return False; - - if(!prs_set_offset(ps, struct_offset)) - return False; - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - } - else { - uint32 old_offset; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end))) - return False; - - if (buffer->string_at_end == 0) - return True; - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start)) - return False; - - /* read the string */ - if (!smb_io_unistr(desc, string, ps, depth)) - return False; - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - -/******************************************************************* - * write a array of UNICODE strings and its relative pointer. - * used by 2 RPC structs - ********************************************************************/ - -static BOOL smb_io_relarraystr(const char *desc, NEW_BUFFER *buffer, int depth, uint16 **string) -{ - UNISTR chaine; - - prs_struct *ps=&buffer->prs; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - uint16 *p; - uint16 *q; - uint16 zero=0; - p=*string; - q=*string; - - /* first write the last 0 */ - buffer->string_at_end -= 2; - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; - - if(!prs_uint16("leading zero", ps, depth, &zero)) - return False; - - while (p && (*p!=0)) { - while (*q!=0) - q++; - - /* Yes this should be malloc not talloc. Don't change. */ - - chaine.buffer = SMB_MALLOC((q-p+1)*sizeof(uint16)); - if (chaine.buffer == NULL) - return False; - - memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); - - buffer->string_at_end -= (q-p+1)*sizeof(uint16); - - if(!prs_set_offset(ps, buffer->string_at_end)) { - SAFE_FREE(chaine.buffer); - return False; - } - - /* write the string */ - if (!smb_io_unistr(desc, &chaine, ps, depth)) { - SAFE_FREE(chaine.buffer); - return False; - } - q++; - p=q; - - SAFE_FREE(chaine.buffer); - } - - if(!prs_set_offset(ps, struct_offset)) - return False; - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - - } else { - - /* UNMARSHALLING */ - - uint32 old_offset; - uint16 *chaine2=NULL; - int l_chaine=0; - int l_chaine2=0; - size_t realloc_size = 0; - - *string=NULL; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) - return False; - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) - return False; - - do { - if (!smb_io_unistr(desc, &chaine, ps, depth)) - return False; - - l_chaine=str_len_uni(&chaine); - - /* we're going to add two more bytes here in case this - is the last string in the array and we need to add - an extra NULL for termination */ - if (l_chaine > 0) - { - uint16 *tc2; - - realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16); - - /* Yes this should be realloc - it's freed below. JRA */ - - if((tc2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) { - SAFE_FREE(chaine2); - return False; - } - else chaine2 = tc2; - memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); - l_chaine2+=l_chaine+1; - } - - } while(l_chaine!=0); - - /* the end should be bould NULL terminated so add - the second one here */ - if (chaine2) - { - chaine2[l_chaine2] = '\0'; - *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size); - SAFE_FREE(chaine2); - } - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - -/******************************************************************* - Parse a DEVMODE structure and its relative pointer. -********************************************************************/ - -static BOOL smb_io_relsecdesc(const char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc) -{ - prs_struct *ps= &buffer->prs; - - prs_debug(ps, depth, desc, "smb_io_relsecdesc"); - depth++; - - if (MARSHALLING(ps)) { - uint32 struct_offset = prs_offset(ps); - uint32 relative_offset; - - if (! *secdesc) { - relative_offset = 0; - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - return True; - } - - if (*secdesc != NULL) { - buffer->string_at_end -= sec_desc_size(*secdesc); - - if(!prs_set_offset(ps, buffer->string_at_end)) - return False; - /* write the secdesc */ - if (!sec_io_desc(desc, secdesc, ps, depth)) - return False; - - if(!prs_set_offset(ps, struct_offset)) - return False; - } - - relative_offset=buffer->string_at_end - buffer->struct_start; - /* write its offset */ - - if (!prs_uint32("offset", ps, depth, &relative_offset)) - return False; - } else { - uint32 old_offset; - - /* read the offset */ - if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) - return False; - - old_offset = prs_offset(ps); - if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) - return False; - - /* read the sd */ - if (!sec_io_desc(desc, secdesc, ps, depth)) - return False; - - if(!prs_set_offset(ps, old_offset)) - return False; - } - return True; -} - -/******************************************************************* Parse a DEVMODE structure and its relative pointer. ********************************************************************/ -static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode) +static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode) { prs_struct *ps=&buffer->prs; @@ -2457,7 +2147,7 @@ static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, D Parse a PRINTER_INFO_0 structure. ********************************************************************/ -BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth) +BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2558,7 +2248,7 @@ BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 Parse a PRINTER_INFO_1 structure. ********************************************************************/ -BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth) +BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2583,7 +2273,7 @@ BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 Parse a PRINTER_INFO_2 structure. ********************************************************************/ -BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth) +BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth) { prs_struct *ps=&buffer->prs; uint32 dm_offset, sd_offset, current_offset; @@ -2674,7 +2364,7 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 Parse a PRINTER_INFO_3 structure. ********************************************************************/ -BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth) +BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2695,7 +2385,7 @@ BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 Parse a PRINTER_INFO_4 structure. ********************************************************************/ -BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth) +BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2717,7 +2407,7 @@ BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 Parse a PRINTER_INFO_5 structure. ********************************************************************/ -BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth) +BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2743,7 +2433,7 @@ BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 Parse a PRINTER_INFO_7 structure. ********************************************************************/ -BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7 *info, int depth) +BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2763,7 +2453,7 @@ BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7 Parse a PORT_INFO_1 structure. ********************************************************************/ -BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth) +BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2782,7 +2472,7 @@ BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, Parse a PORT_INFO_2 structure. ********************************************************************/ -BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth) +BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2809,7 +2499,7 @@ BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, Parse a DRIVER_INFO_1 structure. ********************************************************************/ -BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) +BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2828,7 +2518,7 @@ BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_I Parse a DRIVER_INFO_2 structure. ********************************************************************/ -BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) +BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2857,7 +2547,7 @@ BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_I Parse a DRIVER_INFO_3 structure. ********************************************************************/ -BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth) +BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2896,7 +2586,7 @@ BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_I Parse a DRIVER_INFO_6 structure. ********************************************************************/ -BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth) +BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -2961,7 +2651,7 @@ BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_I Parse a JOB_INFO_1 structure. ********************************************************************/ -BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth) +BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3004,7 +2694,7 @@ BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, i Parse a JOB_INFO_2 structure. ********************************************************************/ -BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth) +BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth) { uint32 pipo=0; prs_struct *ps=&buffer->prs; @@ -3071,7 +2761,7 @@ BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, i /******************************************************************* ********************************************************************/ -BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth) +BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3102,123 +2792,13 @@ BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth return True; } -/******************************************************************* - Read/write a BUFFER struct. -********************************************************************/ - -static BOOL spoolss_io_buffer(const char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer) -{ - NEW_BUFFER *buffer = *pp_buffer; - - prs_debug(ps, depth, desc, "spoolss_io_buffer"); - depth++; - - if (UNMARSHALLING(ps)) - buffer = *pp_buffer = PRS_ALLOC_MEM(ps, NEW_BUFFER, 1); - - if (buffer == NULL) - return False; - - if (!prs_uint32("ptr", ps, depth, &buffer->ptr)) - return False; - - /* reading */ - if (UNMARSHALLING(ps)) { - buffer->size=0; - buffer->string_at_end=0; - - if (buffer->ptr==0) { - /* - * JRA. I'm not sure if the data in here is in big-endian format if - * the client is big-endian. Leave as default (little endian) for now. - */ - - if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL)) - return False; - return True; - } - - if (!prs_uint32("size", ps, depth, &buffer->size)) - return False; - - /* - * JRA. I'm not sure if the data in here is in big-endian format if - * the client is big-endian. Leave as default (little endian) for now. - */ - - if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL)) - return False; - - if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size)) - return False; - - if (!prs_set_offset(&buffer->prs, 0)) - return False; - - if (!prs_set_offset(ps, buffer->size+prs_offset(ps))) - return False; - - buffer->string_at_end=buffer->size; - - return True; - } - else { - BOOL ret = False; - - /* writing */ - if (buffer->ptr==0) { - /* We have finished with the data in buffer->prs - free it. */ - prs_mem_free(&buffer->prs); - return True; - } - - if (!prs_uint32("size", ps, depth, &buffer->size)) - goto out; - - if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size)) - goto out; - - ret = True; - out: - - /* We have finished with the data in buffer->prs - free it. */ - prs_mem_free(&buffer->prs); - - return ret; - } -} - -/******************************************************************* - move a BUFFER from the query to the reply. - As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed, - this is ok. This is an OPTIMIZATION and is not strictly neccessary. - Clears the memory to zero also. -********************************************************************/ - -void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest) -{ - prs_switch_type(&src->prs, MARSHALL); - if(!prs_set_offset(&src->prs, 0)) - return; - prs_force_dynamic(&src->prs); - prs_mem_clear(&src->prs); - *dest=src; -} - -/******************************************************************* - Get the size of a BUFFER struct. -********************************************************************/ -uint32 new_get_buffer_size(NEW_BUFFER *buffer) -{ - return (buffer->size); -} /******************************************************************* Parse a DRIVER_DIRECTORY_1 structure. ********************************************************************/ -BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth) +BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3237,7 +2817,7 @@ BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 Parse a PORT_INFO_1 structure. ********************************************************************/ -BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth) +BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3256,7 +2836,7 @@ BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int Parse a PORT_INFO_2 structure. ********************************************************************/ -BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth) +BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3282,7 +2862,7 @@ BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int /******************************************************************* ********************************************************************/ -BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth) +BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3300,7 +2880,7 @@ BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPRO /******************************************************************* ********************************************************************/ -BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth) +BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3318,7 +2898,7 @@ BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINT /******************************************************************* ********************************************************************/ -BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth) +BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3336,7 +2916,7 @@ BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONIT /******************************************************************* ********************************************************************/ -BOOL smb_io_printmonitor_info_2(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth) +BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -3859,7 +3439,7 @@ BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, const POLICY_HND *hnd, const fstring architecture, uint32 level, uint32 clientmajor, uint32 clientminor, - NEW_BUFFER *buffer, uint32 offered) + RPC_BUFFER *buffer, uint32 offered) { if (q_u == NULL) return False; @@ -3903,7 +3483,7 @@ BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 if(!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if(!prs_align(ps)) @@ -3933,7 +3513,7 @@ BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -3959,7 +3539,7 @@ BOOL make_spoolss_q_enumprinters( uint32 flags, char *servername, uint32 level, - NEW_BUFFER *buffer, + RPC_BUFFER *buffer, uint32 offered ) { @@ -3981,7 +3561,7 @@ BOOL make_spoolss_q_enumprinters( BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, fstring servername, uint32 level, - NEW_BUFFER *buffer, uint32 offered) + RPC_BUFFER *buffer, uint32 offered) { q_u->name_ptr = (servername != NULL) ? 1 : 0; init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername); @@ -4019,7 +3599,7 @@ BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_ if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -4042,7 +3622,7 @@ BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_ if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4074,7 +3654,7 @@ BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_stru if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4107,7 +3687,7 @@ BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -4127,7 +3707,7 @@ BOOL make_spoolss_q_getprinter( SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, - NEW_BUFFER *buffer, + RPC_BUFFER *buffer, uint32 offered ) { @@ -4349,7 +3929,7 @@ BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, if(!prs_align(ps)) return False; - if(!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if(!prs_align(ps)) @@ -4380,7 +3960,7 @@ BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, if(!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if(!prs_align(ps)) @@ -4403,7 +3983,7 @@ BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct * if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4428,7 +4008,7 @@ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs, uint32 level, - NEW_BUFFER *buffer, + RPC_BUFFER *buffer, uint32 offered) { if (q_u == NULL) @@ -4465,7 +4045,7 @@ BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct * if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if(!prs_align(ps)) @@ -4569,7 +4149,7 @@ BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVER if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4595,7 +4175,7 @@ BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u, const char *name, const char *environment, uint32 level, - NEW_BUFFER *buffer, uint32 offered) + RPC_BUFFER *buffer, uint32 offered) { init_buf_unistr2(&q_u->name, &q_u->name_ptr, name); init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment); @@ -4637,7 +4217,7 @@ BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVER if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -4665,7 +4245,7 @@ BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -4687,7 +4267,7 @@ BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4727,7 +4307,7 @@ BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -4749,7 +4329,7 @@ BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4776,7 +4356,7 @@ BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -4815,7 +4395,7 @@ BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if (!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -5815,7 +5395,7 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u, fstring servername, fstring env_name, uint32 level, - NEW_BUFFER *buffer, uint32 offered) + RPC_BUFFER *buffer, uint32 offered) { init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername); init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name); @@ -5857,7 +5437,7 @@ BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVER if(!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if(!prs_align(ps)) @@ -5881,7 +5461,7 @@ BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVER if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -5907,7 +5487,7 @@ BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESS if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -5955,7 +5535,7 @@ BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESS if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -6029,7 +5609,7 @@ BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROC if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -6077,7 +5657,7 @@ BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROC if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -6112,7 +5692,7 @@ BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS if (!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if (!prs_align(ps)) @@ -6135,7 +5715,7 @@ BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -6578,7 +6158,7 @@ BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, if (!prs_align(ps)) return False; - if (!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if (!prs_align(ps)) @@ -6612,7 +6192,7 @@ BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, if(!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if(!prs_align(ps)) @@ -7463,7 +7043,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX [in] unistr2 *name, [in] unistr2 *environment, [in] uint32 level, - [in,out] NEW_BUFFER buffer, + [in,out] RPC_BUFFER buffer, [in] uint32 offered, [out] uint32 needed, [out] uint32 returned @@ -7471,7 +7051,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX */ -BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered) +BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered) { DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n")); @@ -7522,7 +7102,7 @@ BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTP if(!prs_uint32("level", ps, depth, &q_u->level)) return False; - if(!spoolss_io_buffer("", ps, depth, &q_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer)) return False; if(!prs_align(ps)) @@ -7546,7 +7126,7 @@ BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTP if(!prs_align(ps)) return False; - if(!spoolss_io_buffer("", ps, depth, &r_u->buffer)) + if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer)) return False; if(!prs_align(ps)) @@ -7561,7 +7141,7 @@ BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTP return True; } -BOOL smb_io_printprocessordirectory_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth) +BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth) { prs_struct *ps=&buffer->prs; @@ -7625,7 +7205,7 @@ BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, const char *formname, uint32 level, - NEW_BUFFER *buffer, uint32 offered) + RPC_BUFFER *buffer, uint32 offered) { memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); q_u->level = level; @@ -7641,7 +7221,7 @@ BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, ********************************************************************/ BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, - uint32 level, NEW_BUFFER *buffer, + uint32 level, RPC_BUFFER *buffer, uint32 offered) { memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); @@ -7676,7 +7256,7 @@ BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, ********************************************************************/ BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, - uint32 jobid, uint32 level, NEW_BUFFER *buffer, + uint32 jobid, uint32 level, RPC_BUFFER *buffer, uint32 offered) { memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index ffeeb0af9a9..053290f80fe 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -644,41 +644,6 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3 return True; } -/**************************************************************************** - Allocate more memory for a BUFFER. -****************************************************************************/ - -static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) -{ - prs_struct *ps; - uint32 extra_space; - uint32 old_offset; - - ps= &buffer->prs; - - /* damn, I'm doing the reverse operation of prs_grow() :) */ - if (buffer_size < prs_data_size(ps)) - extra_space=0; - else - extra_space = buffer_size - prs_data_size(ps); - - /* - * save the offset and move to the end of the buffer - * prs_grow() checks the extra_space against the offset - */ - old_offset=prs_offset(ps); - prs_set_offset(ps, prs_data_size(ps)); - - if (!prs_grow(ps, extra_space)) - return False; - - prs_set_offset(ps, old_offset); - - buffer->string_at_end=prs_data_size(ps); - - return True; -} - /*************************************************************************** check to see if the client motify handle is monitoring the notification given by (notify_type, notify_field). @@ -4121,7 +4086,7 @@ static void free_dev_mode(DEVICEMODE *dev) if (dev == NULL) return; - SAFE_FREE(dev->private); + SAFE_FREE(dev->private); SAFE_FREE(dev); } @@ -4404,13 +4369,14 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p Spoolss_enumprinters. ********************************************************************/ -static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; int i; int n_services=lp_numservices(); PRINTER_INFO_1 *tp, *printers=NULL; PRINTER_INFO_1 current_prt; + WERROR result = WERR_OK; DEBUG(4,("enum_all_printers_info_1\n")); @@ -4438,29 +4404,36 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 for (i=0; i<*returned; i++) (*needed) += spoolss_size_printer_info_1(&printers[i]); - if (!alloc_buffer_size(buffer, *needed)) - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } /* fill the buffer with the structures */ for (i=0; i<*returned; i++) smb_io_printer_info_1("", buffer, &printers[i], 0); +out: /* clear memory */ + SAFE_FREE(printers); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } - else - return WERR_OK; + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; + + return result; } /******************************************************************** enum_all_printers_info_1_local. *********************************************************************/ -static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { DEBUG(4,("enum_all_printers_info_1_local\n")); @@ -4471,7 +4444,7 @@ static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, enum_all_printers_info_1_name. *********************************************************************/ -static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { char *s = name; @@ -4492,13 +4465,14 @@ static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, ui enum_all_printers_info_1_remote. *********************************************************************/ -static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PRINTER_INFO_1 *printer; fstring printername; fstring desc; fstring comment; DEBUG(4,("enum_all_printers_info_1_remote\n")); + WERROR result = WERR_OK; /* JFM: currently it's more a place holder than anything else. * In the spooler world there is a notion of server registration. @@ -4525,23 +4499,27 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, /* check the required size. */ *needed += spoolss_size_printer_info_1(printer); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_info_1("", buffer, printer, 0); +out: /* clear memory */ SAFE_FREE(printer); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } - else - return WERR_OK; + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; + + return result; } #endif @@ -4550,7 +4528,7 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, enum_all_printers_info_1_network. *********************************************************************/ -static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { char *s = name; @@ -4579,13 +4557,14 @@ static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; int i; int n_services=lp_numservices(); PRINTER_INFO_2 *tp, *printers=NULL; PRINTER_INFO_2 current_prt; + WERROR result = WERR_OK; for (snum=0; snum offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ for (i=0; i<*returned; i++) smb_io_printer_info_2("", buffer, &(printers[i]), 0); +out: /* clear memory */ for (i=0; i<*returned; i++) { free_devmode(printers[i].devmode); } SAFE_FREE(printers); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } - else - return WERR_OK; + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; + + return result; } /******************************************************************** @@ -4641,7 +4621,7 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3 ********************************************************************/ static WERROR enumprinters_level1( uint32 flags, fstring name, - NEW_BUFFER *buffer, uint32 offered, + RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { /* Not all the flags are equals */ @@ -4668,7 +4648,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name, ********************************************************************/ static WERROR enumprinters_level2( uint32 flags, fstring servername, - NEW_BUFFER *buffer, uint32 offered, + RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { char *s = servername; @@ -4697,7 +4677,7 @@ static WERROR enumprinters_level2( uint32 flags, fstring servername, ********************************************************************/ static WERROR enumprinters_level5( uint32 flags, fstring servername, - NEW_BUFFER *buffer, uint32 offered, + RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/ @@ -4715,7 +4695,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_ uint32 flags = q_u->flags; UNISTR2 *servername = &q_u->servername; uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; @@ -4723,8 +4703,11 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_ fstring name; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_enumprinters\n")); @@ -4764,9 +4747,10 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_ /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_0 *printer=NULL; + WERROR result = WERR_OK; if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL) return WERR_NOMEM; @@ -4776,30 +4760,34 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_0(printer); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_info_0("", buffer, printer, 0); +out: /* clear memory */ - SAFE_FREE(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } + SAFE_FREE(printer); - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_1 *printer=NULL; + WERROR result = WERR_OK; if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL) return WERR_NOMEM; @@ -4809,30 +4797,33 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_1(printer); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_info_1("", buffer, printer, 0); +out: /* clear memory */ SAFE_FREE(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_2 *printer=NULL; + WERROR result = WERR_OK; if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL) return WERR_NOMEM; @@ -4842,33 +4833,34 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_2(printer); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_info_2(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; } - /* fill the buffer with the structures */ - if (!smb_io_printer_info_2("", buffer, printer, 0)) { - free_printer_info_2(printer); - return WERR_NOMEM; + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } + + /* fill the buffer with the structures */ + if (!smb_io_printer_info_2("", buffer, printer, 0)) + result = WERR_NOMEM; +out: /* clear memory */ free_printer_info_2(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_3 *printer=NULL; + WERROR result = WERR_OK; if (!construct_printer_info_3(print_hnd, &printer, snum)) return WERR_NOMEM; @@ -4876,30 +4868,33 @@ static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_3(printer); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_info_3(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_info_3("", buffer, printer, 0); +out: /* clear memory */ free_printer_info_3(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_4 *printer=NULL; + WERROR result = WERR_OK; if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL) return WERR_NOMEM; @@ -4910,30 +4905,33 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_4(printer); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_info_4(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_info_4("", buffer, printer, 0); +out: /* clear memory */ free_printer_info_4(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_5 *printer=NULL; + WERROR result = WERR_OK; if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL) return WERR_NOMEM; @@ -4944,27 +4942,30 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_5(printer); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_info_5(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_info_5("", buffer, printer, 0); +out: /* clear memory */ free_printer_info_5(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + return result; } -static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_7 *printer=NULL; + WERROR result = WERR_OK; if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL) return WERR_NOMEM; @@ -4975,22 +4976,25 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER /* check the required size. */ *needed += spoolss_size_printer_info_7(printer); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_info_7(printer); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } /* fill the buffer with the structures */ smb_io_printer_info_7("", buffer, printer, 0); +out: /* clear memory */ free_printer_info_7(printer); - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + return result; } /**************************************************************************** @@ -5000,7 +5004,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET { POLICY_HND *handle = &q_u->handle; uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); @@ -5008,8 +5012,11 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET int snum; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } *needed=0; @@ -5433,149 +5440,154 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info) static void free_printer_driver_info_6(DRIVER_INFO_6 *info) { SAFE_FREE(info->dependentfiles); - } /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_1 *info=NULL; - WERROR status; + WERROR result; if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL) return WERR_NOMEM; - status=construct_printer_driver_info_1(info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(status)) { - SAFE_FREE(info); - return status; - } + result = construct_printer_driver_info_1(info, snum, servername, architecture, version); + if (!W_ERROR_IS_OK(result)) + goto out; /* check the required size. */ *needed += spoolss_size_printer_driver_info_1(info); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_driver_info_1("", buffer, info, 0); +out: /* clear memory */ SAFE_FREE(info); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_2 *info=NULL; - WERROR status; + WERROR result; if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL) return WERR_NOMEM; - status=construct_printer_driver_info_2(info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(status)) { - SAFE_FREE(info); - return status; - } + result = construct_printer_driver_info_2(info, snum, servername, architecture, version); + if (!W_ERROR_IS_OK(result)) + goto out; /* check the required size. */ *needed += spoolss_size_printer_driver_info_2(info); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_driver_info_2("", buffer, info, 0); +out: /* clear memory */ SAFE_FREE(info); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_3 info; - WERROR status; + WERROR result; ZERO_STRUCT(info); - status=construct_printer_driver_info_3(&info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(status)) { - return status; - } + result = construct_printer_driver_info_3(&info, snum, servername, architecture, version); + if (!W_ERROR_IS_OK(result)) + goto out; /* check the required size. */ *needed += spoolss_size_printer_driver_info_3(&info); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_driver_info_3(&info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_driver_info_3("", buffer, &info, 0); +out: free_printer_driver_info_3(&info); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - - return WERR_OK; + return result; } /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_6 info; - WERROR status; + WERROR result; ZERO_STRUCT(info); - status=construct_printer_driver_info_6(&info, snum, servername, architecture, version); - if (!W_ERROR_IS_OK(status)) { - return status; - } + result = construct_printer_driver_info_6(&info, snum, servername, architecture, version); + if (!W_ERROR_IS_OK(result)) + goto out; /* check the required size. */ *needed += spoolss_size_printer_driver_info_6(&info); - if (!alloc_buffer_size(buffer, *needed)) { - free_printer_driver_info_6(&info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ smb_io_printer_driver_info_6("", buffer, &info, 0); +out: free_printer_driver_info_6(&info); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - - return WERR_OK; + return result; } /**************************************************************************** @@ -5587,7 +5599,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_ UNISTR2 *uni_arch = &q_u->architecture; uint32 level = q_u->level; uint32 clientmajorversion = q_u->clientmajorversion; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *servermajorversion = &r_u->servermajorversion; @@ -5599,8 +5611,11 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_ int snum; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_getprinterdriver2\n")); @@ -6389,8 +6404,10 @@ WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u) WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u) { - /* that's an [in out] buffer (despite appearences to the contrary) */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); + /* that's an [in out] buffer */ + + if ( q_u->buffer ) + rpcbuf_move(q_u->buffer, &r_u->buffer); r_u->needed = 0; return WERR_INVALID_PARAM; /* this is what a NT server @@ -6476,11 +6493,12 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, static WERROR enumjobs_level1(print_queue_struct *queue, int snum, NT_PRINTER_INFO_LEVEL *ntprinter, - NEW_BUFFER *buffer, uint32 offered, + RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { JOB_INFO_1 *info; int i; + WERROR result = WERR_OK; info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned); if (info==NULL) { @@ -6498,24 +6516,28 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum, for (i=0; i<*returned; i++) (*needed) += spoolss_size_job_info_1(&info[i]); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ for (i=0; i<*returned; i++) smb_io_job_info_1("", buffer, &info[i], 0); +out: /* clear memory */ SAFE_FREE(info); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** @@ -6524,19 +6546,17 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum, static WERROR enumjobs_level2(print_queue_struct *queue, int snum, NT_PRINTER_INFO_LEVEL *ntprinter, - NEW_BUFFER *buffer, uint32 offered, + RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { JOB_INFO_2 *info = NULL; int i; - WERROR result; + WERROR result = WERR_OK; DEVICEMODE *devmode = NULL; - info=SMB_MALLOC_ARRAY(JOB_INFO_2,*returned); - if (info==NULL) { + if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) { *returned=0; - result = WERR_NOMEM; - goto done; + return WERR_NOMEM; } /* this should not be a failure condition if the devmode is NULL */ @@ -6544,8 +6564,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, devmode = construct_dev_mode(snum); for (i=0; i<*returned; i++) - fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, - devmode); + fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode); free_a_printer(&ntprinter, 2); SAFE_FREE(queue); @@ -6555,29 +6574,26 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, (*needed) += spoolss_size_job_info_2(&info[i]); if (*needed > offered) { - *returned=0; result = WERR_INSUFFICIENT_BUFFER; - goto done; + goto out; } - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(info); - result = WERR_INSUFFICIENT_BUFFER; - goto done; + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the structures */ for (i=0; i<*returned; i++) smb_io_job_info_2("", buffer, &info[i], 0); - result = WERR_OK; - - done: - free_a_printer(&ntprinter, 2); +out: free_devmode(devmode); - SAFE_FREE(queue); SAFE_FREE(info); + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; + return result; } @@ -6590,7 +6606,7 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO { POLICY_HND *handle = &q_u->handle; uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; @@ -6601,8 +6617,11 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO print_queue_struct *queue=NULL; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_enumjobs\n")); @@ -6703,15 +6722,15 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u Enumerates all printer drivers at level 1. ****************************************************************************/ -static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; int ndrivers; uint32 version; fstring *list = NULL; - NT_PRINTER_DRIVER_INFO_LEVEL driver; DRIVER_INFO_1 *tdi1, *driver_info_1=NULL; + WERROR result = WERR_OK; *returned=0; @@ -6757,9 +6776,14 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]); } - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(driver_info_1); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the driver structures */ @@ -6768,29 +6792,28 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0); } +out: SAFE_FREE(driver_info_1); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** Enumerates all printer drivers at level 2. ****************************************************************************/ -static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; int ndrivers; uint32 version; fstring *list = NULL; - NT_PRINTER_DRIVER_INFO_LEVEL driver; DRIVER_INFO_2 *tdi2, *driver_info_2=NULL; + WERROR result = WERR_OK; *returned=0; @@ -6837,9 +6860,14 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); } - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(driver_info_2); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the form structures */ @@ -6848,29 +6876,28 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); } +out: SAFE_FREE(driver_info_2); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** Enumerates all printer drivers at level 3. ****************************************************************************/ -static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; int ndrivers; uint32 version; fstring *list = NULL; - NT_PRINTER_DRIVER_INFO_LEVEL driver; DRIVER_INFO_3 *tdi3, *driver_info_3=NULL; + WERROR result = WERR_OK; *returned=0; @@ -6917,28 +6944,32 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]); } - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(driver_info_3); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; } - + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } + /* fill the buffer with the driver structures */ for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d] to buffer\n",i)); smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0); } +out: for (i=0; i<*returned; i++) SAFE_FREE(driver_info_3[i].dependentfiles); - + SAFE_FREE(driver_info_3); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** @@ -6948,22 +6979,25 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; - fstring *list = NULL; fstring servername; fstring architecture; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_enumprinterdrivers\n")); - *needed=0; - *returned=0; + + *needed = 0; + *returned = 0; unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1); unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1); @@ -6979,8 +7013,6 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS case 3: return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned); default: - *returned=0; - SAFE_FREE(list); return WERR_UNKNOWN_LEVEL; } } @@ -7006,7 +7038,7 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list) WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *numofforms = &r_u->numofforms; @@ -7019,8 +7051,11 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF int i; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_enumforms\n")); DEBUGADD(5,("Offered buffer size [%d]\n", offered)); @@ -7032,7 +7067,8 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF DEBUGADD(5,("Number of user forms [%d]\n", *numofforms)); *numofforms += numbuiltinforms; - if (*numofforms == 0) return WERR_NO_MORE_ITEMS; + if (*numofforms == 0) + return WERR_NO_MORE_ITEMS; switch (level) { case 1: @@ -7068,10 +7104,17 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF *needed=buffer_size; - if (!alloc_buffer_size(buffer, buffer_size)){ + if (*needed > offered) { SAFE_FREE(forms_1); + *numofforms=0; return WERR_INSUFFICIENT_BUFFER; } + + if (!rpcbuf_alloc_size(buffer, buffer_size)){ + SAFE_FREE(forms_1); + *numofforms=0; + return WERR_NOMEM; + } /* fill the buffer with the form structures */ for (i=0; i offered) { - *numofforms=0; - return WERR_INSUFFICIENT_BUFFER; - } - else - return WERR_OK; + return WERR_OK; default: SAFE_FREE(list); @@ -7107,7 +7145,7 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM * { uint32 level = q_u->level; UNISTR2 *uni_formname = &q_u->formname; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; @@ -7120,8 +7158,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM * int numofforms=0, i=0; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1); @@ -7165,13 +7206,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM * *needed=spoolss_size_form_1(&form_1); - if (!alloc_buffer_size(buffer, buffer_size)){ + if (*needed > offered) return WERR_INSUFFICIENT_BUFFER; - } - if (*needed > offered) { - return WERR_INSUFFICIENT_BUFFER; - } + if (!rpcbuf_alloc_size(buffer, buffer_size)) + return WERR_NOMEM; /* fill the buffer with the form structures */ DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i)); @@ -7209,10 +7248,11 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name) enumports level 1. ****************************************************************************/ -static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PORT_INFO_1 *ports=NULL; int i=0; + WERROR result = WERR_OK; if (*lp_enumports_cmd()) { char *cmd = lp_enumports_cmd(); @@ -7274,9 +7314,14 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need *needed += spoolss_size_port_info_1(&ports[i]); } - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(ports); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the ports structures */ @@ -7285,24 +7330,24 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need smb_io_port_1("", buffer, &ports[i], 0); } +out: SAFE_FREE(ports); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** enumports level 2. ****************************************************************************/ -static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PORT_INFO_2 *ports=NULL; int i=0; + WERROR result = WERR_OK; if (*lp_enumports_cmd()) { char *cmd = lp_enumports_cmd(); @@ -7372,9 +7417,14 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need *needed += spoolss_size_port_info_2(&ports[i]); } - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(ports); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } /* fill the buffer with the ports structures */ @@ -7383,14 +7433,13 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need smb_io_port_2("", buffer, &ports[i], 0); } +out: SAFE_FREE(ports); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** @@ -7400,14 +7449,17 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_enumports\n")); @@ -7741,7 +7793,7 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name) /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { pstring path; pstring long_archi; @@ -7749,6 +7801,7 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen char *pservername; const char *short_archi; DRIVER_DIRECTORY_1 *info=NULL; + WERROR result = WERR_OK; unistr2_to_ascii(servername, name, sizeof(servername)-1); unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); @@ -7778,19 +7831,22 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen *needed += spoolss_size_driverdir_info_1(info); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } smb_io_driverdir_1("", buffer, info, 0); +out: SAFE_FREE(info); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - - return WERR_OK; + return result; } /**************************************************************************** @@ -7801,13 +7857,16 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI UNISTR2 *name = &q_u->name; UNISTR2 *uni_environment = &q_u->environment; uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(4,("_spoolss_getprinterdriverdirectory\n")); @@ -8367,9 +8426,10 @@ done: enumprintprocessors level 1. ****************************************************************************/ -static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PRINTPROCESSOR_1 *info_1=NULL; + WERROR result = WERR_OK; if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL) return WERR_NOMEM; @@ -8380,19 +8440,25 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui *needed += spoolss_size_printprocessor_info_1(info_1); - if (!alloc_buffer_size(buffer, *needed)) - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } smb_io_printprocessor_info_1("", buffer, info_1, 0); +out: SAFE_FREE(info_1); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** @@ -8401,14 +8467,17 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(5,("spoolss_enumprintprocessors\n")); @@ -8434,9 +8503,10 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS enumprintprocdatatypes level 1. ****************************************************************************/ -static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PRINTPROCDATATYPE_1 *info_1=NULL; + WERROR result = WERR_NOMEM; if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL) return WERR_NOMEM; @@ -8447,19 +8517,25 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, *needed += spoolss_size_printprocdatatype_info_1(info_1); - if (!alloc_buffer_size(buffer, *needed)) - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } smb_io_printprocdatatype_info_1("", buffer, info_1, 0); +out: SAFE_FREE(info_1); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** @@ -8468,14 +8544,17 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(5,("_spoolss_enumprintprocdatatypes\n")); @@ -8494,9 +8573,10 @@ WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT enumprintmonitors level 1. ****************************************************************************/ -static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PRINTMONITOR_1 *info_1=NULL; + WERROR result = WERR_OK; if((info_1 = SMB_MALLOC_P(PRINTMONITOR_1)) == NULL) return WERR_NOMEM; @@ -8507,28 +8587,35 @@ static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint *needed += spoolss_size_printmonitor_info_1(info_1); - if (!alloc_buffer_size(buffer, *needed)) - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } smb_io_printmonitor_info_1("", buffer, info_1, 0); +out: SAFE_FREE(info_1); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; - return WERR_OK; + return result; } /**************************************************************************** enumprintmonitors level 2. ****************************************************************************/ -static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { PRINTMONITOR_2 *info_2=NULL; + WERROR result = WERR_OK; if((info_2 = SMB_MALLOC_P(PRINTMONITOR_2)) == NULL) return WERR_NOMEM; @@ -8541,19 +8628,25 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint *needed += spoolss_size_printmonitor_info_2(info_2); - if (!alloc_buffer_size(buffer, *needed)) - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; + } smb_io_printmonitor_info_2("", buffer, info_2, 0); +out: SAFE_FREE(info_2); - if (*needed > offered) { - *returned=0; - return WERR_INSUFFICIENT_BUFFER; - } - - return WERR_OK; + if ( !W_ERROR_IS_OK(result) ) + *returned = 0; + + return result; } /**************************************************************************** @@ -8562,14 +8655,17 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(5,("spoolss_enumprintmonitors\n")); @@ -8598,12 +8694,13 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, NT_PRINTER_INFO_LEVEL *ntprinter, - uint32 jobid, NEW_BUFFER *buffer, uint32 offered, + uint32 jobid, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { int i=0; BOOL found=False; JOB_INFO_1 *info_1=NULL; + WERROR result = WERR_OK; info_1=SMB_MALLOC_P(JOB_INFO_1); @@ -8626,19 +8723,22 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, *needed += spoolss_size_job_info_1(info_1); - if (!alloc_buffer_size(buffer, *needed)) { - SAFE_FREE(info_1); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_NOMEM; + goto out; } smb_io_job_info_1("", buffer, info_1, 0); +out: SAFE_FREE(info_1); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - - return WERR_OK; + return result; } /**************************************************************************** @@ -8646,7 +8746,7 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, NT_PRINTER_INFO_LEVEL *ntprinter, - uint32 jobid, NEW_BUFFER *buffer, uint32 offered, + uint32 jobid, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { int i = 0; @@ -8698,18 +8798,18 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, *needed += spoolss_size_job_info_2(info_2); - if (!alloc_buffer_size(buffer, *needed)) { + if (*needed > offered) { ret = WERR_INSUFFICIENT_BUFFER; goto done; } - smb_io_job_info_2("", buffer, info_2, 0); - - if (*needed > offered) { + if (!rpcbuf_alloc_size(buffer, *needed)) { ret = WERR_INSUFFICIENT_BUFFER; goto done; } + smb_io_job_info_2("", buffer, info_2, 0); + ret = WERR_OK; done: @@ -8729,7 +8829,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ POLICY_HND *handle = &q_u->handle; uint32 jobid = q_u->jobid; uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; WERROR wstatus = WERR_OK; @@ -8740,8 +8840,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ print_status_struct prt_status; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(5,("spoolss_getjob\n")); @@ -9307,13 +9410,14 @@ static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, cha static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, UNISTR2 *environment, - NEW_BUFFER *buffer, + RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { pstring path; pstring long_archi; PRINTPROCESSOR_DIRECTORY_1 *info=NULL; + WERROR result = WERR_OK; unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1); @@ -9329,32 +9433,38 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, *needed += spoolss_size_printprocessordirectory_info_1(info); - if (!alloc_buffer_size(buffer, *needed)) { - safe_free(info); - return WERR_INSUFFICIENT_BUFFER; + if (*needed > offered) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; + } + + if (!rpcbuf_alloc_size(buffer, *needed)) { + result = WERR_INSUFFICIENT_BUFFER; + goto out; } smb_io_printprocessordirectory_1("", buffer, info, 0); - safe_free(info); +out: + SAFE_FREE(info); - if (*needed > offered) - return WERR_INSUFFICIENT_BUFFER; - else - return WERR_OK; + return result; } WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u) { uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + RPC_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; WERROR result; /* that's an [in out] buffer */ - spoolss_move_buffer(q_u->buffer, &r_u->buffer); - buffer = r_u->buffer; + + if ( q_u->buffer ) { + rpcbuf_move(q_u->buffer, &r_u->buffer); + buffer = r_u->buffer; + } DEBUG(5,("_spoolss_getprintprocessordirectory\n")); -- 2.11.4.GIT