1/*
2   Unix SMB/CIFS implementation.
3   RPC pipe client
4
5   Copyright (C) Gerald Carter                2001-2002,
6   Copyright (C) Tim Potter                   2000-2002,
7   Copyright (C) Andrew Tridgell              1994-2000,
8   Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
9   Copyright (C) Jean-Francois Micouleau      1999-2000.
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#include "includes.h"
27
28/*
29 * SPOOLSS Client RPC's used by servers as the notification
30 * back channel.
31 */
32
33/* Send a ReplyOpenPrinter request.  This rpc is made by the printer
34   server to the printer client in response to a rffpcnex request.
35   The rrfpcnex request names a printer and a handle (the printerlocal
36   value) and this rpc establishes a back-channel over which printer
37   notifications are performed. */
38
39WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
40				      const char *printer, uint32 printerlocal, uint32 type,
41				      POLICY_HND *handle)
42{
43	prs_struct qbuf, rbuf;
44	SPOOL_Q_REPLYOPENPRINTER q;
45	SPOOL_R_REPLYOPENPRINTER r;
46	WERROR result = W_ERROR(ERRgeneral);
47
48	/* Initialise input parameters */
49
50	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
51	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
52
53	make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type);
54
55	/* Marshall data and send request */
56
57	if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) ||
58	    !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
59		goto done;
60
61	/* Unmarshall response */
62
63	if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0))
64		goto done;
65
66	/* Return result */
67
68	memcpy(handle, &r.handle, sizeof(r.handle));
69	result = r.status;
70
71done:
72	prs_mem_free(&qbuf);
73	prs_mem_free(&rbuf);
74
75	return result;
76}
77
78/* Close a back-channel notification connection */
79
80WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
81				       POLICY_HND *handle)
82{
83	prs_struct qbuf, rbuf;
84	SPOOL_Q_REPLYCLOSEPRINTER q;
85	SPOOL_R_REPLYCLOSEPRINTER r;
86	WERROR result = W_ERROR(ERRgeneral);
87
88	/* Initialise input parameters */
89
90	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
91	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
92
93	make_spoolss_q_reply_closeprinter(&q, handle);
94
95	/* Marshall data and send request */
96
97	if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
98	    !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
99		goto done;
100
101	/* Unmarshall response */
102
103	if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0))
104		goto done;
105
106	/* Return result */
107
108	result = r.status;
109
110done:
111	prs_mem_free(&qbuf);
112	prs_mem_free(&rbuf);
113
114	return result;
115}
116
117/*********************************************************************
118 This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change
119 notification event when the registration **did not** use
120 SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor.
121 Also see cli_spolss_reply_rrpcn()
122 *********************************************************************/
123
124WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
125				      POLICY_HND *pol, uint32 condition, uint32 change_id)
126{
127	prs_struct qbuf, rbuf;
128	SPOOL_Q_ROUTERREPLYPRINTER q;
129        SPOOL_R_ROUTERREPLYPRINTER r;
130	WERROR result = W_ERROR(ERRgeneral);
131
132	/* Initialise input parameters */
133
134	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
135	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
136
137	make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id);
138
139	/* Marshall data and send request */
140
141	if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) ||
142	    !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
143		goto done;
144
145	/* Unmarshall response */
146
147	if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0))
148		goto done;
149
150	/* Return output parameters */
151
152	result = r.status;
153
154done:
155	prs_mem_free(&qbuf);
156	prs_mem_free(&rbuf);
157
158	return result;
159}
160
161/*********************************************************************
162 This SPOOLSS_REPLY_RRPCN function is used to send a change
163 notification event when the registration **did** use
164 SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor
165 Also see cli_spoolss_routereplyprinter()
166 *********************************************************************/
167
168WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
169			 POLICY_HND *pol, uint32 notify_data_len,
170			 SPOOL_NOTIFY_INFO_DATA *notify_data,
171			 uint32 change_low, uint32 change_high)
172{
173	prs_struct qbuf, rbuf;
174	SPOOL_Q_REPLY_RRPCN q;
175	SPOOL_R_REPLY_RRPCN r;
176	WERROR result = W_ERROR(ERRgeneral);
177	SPOOL_NOTIFY_INFO 	notify_info;
178
179	ZERO_STRUCT(q);
180	ZERO_STRUCT(r);
181
182	/* Initialise parse structures */
183
184	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
185	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
186
187	ZERO_STRUCT(notify_info);
188
189	/* Initialise input parameters */
190
191	notify_info.version = 0x2;
192	notify_info.flags   = 0x00020000;	/* ?? */
193	notify_info.count   = notify_data_len;
194	notify_info.data    = notify_data;
195
196	/* create and send a MSRPC command with api  */
197	/* store the parameters */
198
199	make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high,
200				   &notify_info);
201
202	/* Marshall data and send request */
203
204	if(!spoolss_io_q_reply_rrpcn("", &q,  &qbuf, 0) ||
205	   !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_RRPCN, &qbuf, &rbuf))
206		goto done;
207
208	/* Unmarshall response */
209
210	if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0))
211		goto done;
212
213	if (r.unknown0 == 0x00080000)
214		DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
215	else if ( r.unknown0 != 0x0 )
216		DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0));
217
218	result = r.status;
219
220done:
221	prs_mem_free(&qbuf);
222	prs_mem_free(&rbuf);
223
224	return result;
225}
226
227/*********************************************************************
228 *********************************************************************/
229
230WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
231			    POLICY_HND *pol, uint32 flags, uint32 options,
232			    const char *localmachine, uint32 printerlocal,
233			    SPOOL_NOTIFY_OPTION *option)
234{
235	prs_struct qbuf, rbuf;
236	SPOOL_Q_RFFPCNEX q;
237	SPOOL_R_RFFPCNEX r;
238	WERROR result = W_ERROR(ERRgeneral);
239
240	ZERO_STRUCT(q);
241	ZERO_STRUCT(r);
242
243	/* Initialise parse structures */
244
245	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
246	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
247
248	/* Initialise input parameters */
249
250	make_spoolss_q_rffpcnex(
251		&q, pol, flags, options, localmachine, printerlocal,
252		option);
253
254	/* Marshall data and send request */
255
256	if(!spoolss_io_q_rffpcnex("", &q,  &qbuf, 0) ||
257	   !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_RFFPCNEX, &qbuf, &rbuf))
258		goto done;
259
260	/* Unmarshall response */
261
262	if(!spoolss_io_r_rffpcnex("", &r, &rbuf, 0))
263		goto done;
264
265	result = r.status;
266
267done:
268	prs_mem_free(&qbuf);
269	prs_mem_free(&rbuf);
270
271	return result;
272}
273