2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 * Copyright (C) Paul Ashton 1997-2000,
8 * Copyright (C) Jean Francois Micouleau 1998-2000,
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "rpc_parse.h"
27 #include "rpc_client.h"
30 extern int DEBUGLEVEL
;
32 /****************************************************************************
33 do a SPOOLSS Enum Printer Drivers
34 ****************************************************************************/
35 uint32
spoolss_enum_printerdrivers(const char * srv_name
,
36 const char *environment
,
38 NEW_BUFFER
*buffer
, uint32 offered
,
39 uint32
*needed
, uint32
*returned
)
43 SPOOL_Q_ENUMPRINTERDRIVERS q_o
;
44 SPOOL_R_ENUMPRINTERDRIVERS r_o
;
46 struct cli_connection
*con
= NULL
;
48 if (!cli_connection_init(srv_name
, PIPE_SPOOLSS
, &con
))
51 prs_init(&buf
, 0, 4, False
);
52 prs_init(&rbuf
, 0, 4, True
);
54 /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
56 DEBUG(5,("SPOOLSS Enum Printer Drivers (Server: %s Environment: %s level: %d)\n",
57 srv_name
, environment
, level
));
59 make_spoolss_q_enumprinterdrivers(&q_o
, srv_name
, environment
,
60 level
, buffer
, offered
);
62 /* turn parameters into data stream */
63 if (!spoolss_io_q_enumprinterdrivers("", &q_o
, &buf
, 0) ) {
67 cli_connection_unlink(con
);
70 if(!rpc_con_pipe_req(con
, SPOOLSS_ENUMPRINTERDRIVERS
, &buf
, &rbuf
)) {
74 cli_connection_unlink(con
);
80 buffer
->prs
.io
=UNMARSHALL
;
84 if(!new_spoolss_io_r_enumprinterdrivers("", &r_o
, &rbuf
, 0)) {
86 cli_connection_unlink(con
);
90 *returned
=r_o
.returned
;
95 cli_connection_unlink(con
);
100 /****************************************************************************
101 do a SPOOLSS Enum Printers
102 ****************************************************************************/
103 uint32
spoolss_enum_printers(uint32 flags
, fstring srv_name
, uint32 level
,
104 NEW_BUFFER
*buffer
, uint32 offered
,
105 uint32
*needed
, uint32
*returned
)
109 SPOOL_Q_ENUMPRINTERS q_o
;
110 SPOOL_R_ENUMPRINTERS r_o
;
112 struct cli_connection
*con
= NULL
;
114 if (!cli_connection_init(srv_name
, PIPE_SPOOLSS
, &con
))
117 prs_init(&buf
, 0, 4, False
);
118 prs_init(&rbuf
, 0, 4, True
);
120 /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
122 DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n", srv_name
, level
));
124 make_spoolss_q_enumprinters(&q_o
, flags
, "", level
, buffer
, offered
);
126 /* turn parameters into data stream */
127 if (!spoolss_io_q_enumprinters("", &q_o
, &buf
, 0) ) {
128 prs_free_data(&rbuf
);
129 prs_free_data(&buf
);
131 cli_connection_unlink(con
);
134 if(!rpc_con_pipe_req(con
, SPOOLSS_ENUMPRINTERS
, &buf
, &rbuf
)) {
135 prs_free_data(&rbuf
);
136 prs_free_data(&buf
);
138 cli_connection_unlink(con
);
141 prs_free_data(&buf
);
144 buffer
->prs
.io
=UNMARSHALL
;
145 buffer
->prs
.offset
=0;
148 if(!new_spoolss_io_r_enumprinters("", &r_o
, &rbuf
, 0)) {
149 prs_free_data(&rbuf
);
150 cli_connection_unlink(con
);
154 *returned
=r_o
.returned
;
156 prs_free_data(&rbuf
);
157 prs_free_data(&buf
);
159 cli_connection_unlink(con
);
164 /****************************************************************************
165 do a SPOOLSS Enum Jobs
166 ****************************************************************************/
167 uint32
spoolss_enum_jobs(const POLICY_HND
*hnd
, uint32 firstjob
, uint32 numofjobs
,
168 uint32 level
, NEW_BUFFER
*buffer
, uint32 offered
,
169 uint32
*needed
, uint32
*returned
)
173 SPOOL_Q_ENUMJOBS q_o
;
174 SPOOL_R_ENUMJOBS r_o
;
177 return NT_STATUS_INVALID_PARAMETER
;
179 prs_init(&buf
, 0, 4, False
);
180 prs_init(&rbuf
, 0, 4, True
);
182 /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
184 DEBUG(5,("SPOOLSS Enum Jobs level: %d)\n", level
));
186 make_spoolss_q_enumjobs(&q_o
, hnd
, firstjob
, numofjobs
, level
, buffer
, offered
);
188 /* turn parameters into data stream */
189 if (!spoolss_io_q_enumjobs("", &q_o
, &buf
, 0)) {
190 prs_free_data(&rbuf
);
191 prs_free_data(&buf
);
194 if(!rpc_hnd_pipe_req(hnd
, SPOOLSS_ENUMJOBS
, &buf
, &rbuf
))
196 prs_free_data(&rbuf
);
197 prs_free_data(&buf
);
201 prs_free_data(&buf
);
205 if(!spoolss_io_r_enumjobs("", &r_o
, &rbuf
, 0)) {
206 prs_free_data(&rbuf
);
210 *returned
=r_o
.returned
;
212 prs_free_data(&rbuf
);
213 prs_free_data(&buf
);
218 /****************************************************************************
219 do a SPOOLSS Enum printer datas
220 ****************************************************************************/
221 uint32
spoolss_enum_printerdata(const POLICY_HND
*hnd
, uint32 idx
,
222 uint32
*valuelen
, uint16
*value
, uint32
*rvaluelen
,
224 uint32
*datalen
, uint8
*data
, uint32
*rdatalen
)
228 SPOOL_Q_ENUMPRINTERDATA q_o
;
229 SPOOL_R_ENUMPRINTERDATA r_o
;
232 return NT_STATUS_INVALID_PARAMETER
;
234 prs_init(&buf
, 0, 4, False
);
235 prs_init(&rbuf
, 0, 4, True
);
237 /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
239 DEBUG(5,("SPOOLSS Enum Printer data)\n"));
241 make_spoolss_q_enumprinterdata(&q_o
, hnd
, idx
, *valuelen
, *datalen
);
243 /* turn parameters into data stream */
244 if (!spoolss_io_q_enumprinterdata("", &q_o
, &buf
, 0)) {
245 prs_free_data(&rbuf
);
246 prs_free_data(&buf
);
249 if(!rpc_hnd_pipe_req(hnd
, SPOOLSS_ENUMPRINTERDATA
, &buf
, &rbuf
)) {
250 prs_free_data(&rbuf
);
251 prs_free_data(&buf
);
255 prs_free_data(&buf
);
260 if(!spoolss_io_r_enumprinterdata("", &r_o
, &rbuf
, 0)) {
261 prs_free_data(&rbuf
);
264 *valuelen
=r_o
.valuesize
;
265 *rvaluelen
=r_o
.realvaluesize
;
267 *datalen
=r_o
.datasize
;
268 *rdatalen
=r_o
.realdatasize
;
270 prs_free_data(&rbuf
);
271 prs_free_data(&buf
);
276 /****************************************************************************
277 do a SPOOLSS Enum printer datas
278 ****************************************************************************/
279 uint32
spoolss_getprinter(const POLICY_HND
*hnd
, uint32 level
,
280 NEW_BUFFER
*buffer
, uint32 offered
,
285 SPOOL_Q_GETPRINTER q_o
;
286 SPOOL_R_GETPRINTER r_o
;
289 return NT_STATUS_INVALID_PARAMETER
;
291 prs_init(&buf
, 0, 4, False
);
292 prs_init(&rbuf
, 0, 4, True
);
294 /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
296 DEBUG(5,("SPOOLSS Enum Printer data)\n"));
298 make_spoolss_q_getprinter(&q_o
, hnd
, level
, buffer
, offered
);
300 /* turn parameters into data stream */
301 if (!spoolss_io_q_getprinter("", &q_o
, &buf
, 0)) {
302 prs_free_data(&rbuf
);
303 prs_free_data(&buf
);
306 if(!rpc_hnd_pipe_req(hnd
, SPOOLSS_GETPRINTER
, &buf
, &rbuf
)) {
307 prs_free_data(&rbuf
);
308 prs_free_data(&buf
);
312 prs_free_data(&buf
);
314 buffer
->prs
.io
=UNMARSHALL
;
315 buffer
->prs
.offset
=0;
318 if(!spoolss_io_r_getprinter("", &r_o
, &rbuf
, 0)) {
319 prs_free_data(&rbuf
);
324 prs_free_data(&rbuf
);
325 prs_free_data(&buf
);
330 /****************************************************************************
331 do a SPOOLSS Enum printer driver
332 ****************************************************************************/
333 uint32
spoolss_getprinterdriver(const POLICY_HND
*hnd
,
334 const char *environment
, uint32 level
,
335 NEW_BUFFER
*buffer
, uint32 offered
,
340 SPOOL_Q_GETPRINTERDRIVER2 q_o
;
341 SPOOL_R_GETPRINTERDRIVER2 r_o
;
344 return NT_STATUS_INVALID_PARAMETER
;
346 prs_init(&buf
, 0, 4, False
);
347 prs_init(&rbuf
, 0, 4, True
);
349 /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
351 DEBUG(5,("SPOOLSS Enum Printer driver)\n"));
353 make_spoolss_q_getprinterdriver2(&q_o
, hnd
, environment
, level
, 2, 0, buffer
, offered
);
355 /* turn parameters into data stream */
356 if (!spoolss_io_q_getprinterdriver2("", &q_o
, &buf
, 0)) {
357 prs_free_data(&rbuf
);
358 prs_free_data(&buf
);
361 if(!rpc_hnd_pipe_req(hnd
, SPOOLSS_GETPRINTERDRIVER2
, &buf
, &rbuf
)) {
362 prs_free_data(&rbuf
);
363 prs_free_data(&buf
);
367 prs_free_data(&buf
);
369 buffer
->prs
.io
=UNMARSHALL
;
370 buffer
->prs
.offset
=0;
373 if(!spoolss_io_r_getprinterdriver2("", &r_o
, &rbuf
, 0)) {
374 prs_free_data(&rbuf
);
379 prs_free_data(&rbuf
);
380 prs_free_data(&buf
);
385 /****************************************************************************
386 do a SPOOLSS Open Printer Ex
387 ****************************************************************************/
388 BOOL
spoolss_open_printer_ex( const char *printername
,
389 const char *datatype
, uint32 access_required
,
390 const char *station
, const char *username
,
395 SPOOL_Q_OPEN_PRINTER_EX q_o
;
396 BOOL valid_pol
= False
;
400 struct cli_connection
*con
= NULL
;
402 memset(srv_name
, 0, sizeof(srv_name
));
403 fstrcpy(srv_name
, printername
);
405 s
= strchr(&srv_name
[2], '\\');
410 if (!cli_connection_init(srv_name
, PIPE_SPOOLSS
, &con
))
413 if (hnd
== NULL
) return False
;
415 prs_init(&buf
, 0, 4, False
);
416 prs_init(&rbuf
, 0, 4, True
);
418 /* create and send a MSRPC command with api SPOOLSS_OPENPRINTEREX */
420 DEBUG(5,("SPOOLSS Open Printer Ex\n"));
422 make_spoolss_q_open_printer_ex(&q_o
, printername
, datatype
,
423 access_required
, station
, username
);
425 /* turn parameters into data stream */
426 if (spoolss_io_q_open_printer_ex("", &q_o
, &buf
, 0) &&
427 rpc_con_pipe_req(con
, SPOOLSS_OPENPRINTEREX
, &buf
, &rbuf
))
429 SPOOL_R_OPEN_PRINTER_EX r_o
;
432 spoolss_io_r_open_printer_ex("", &r_o
, &rbuf
, 0);
433 p
= rbuf
.offset
!= 0;
435 if (p
&& r_o
.status
!= 0)
437 /* report error code */
438 DEBUG(5,("SPOOLSS_OPENPRINTEREX: %s\n", get_nt_error_msg(r_o
.status
)));
444 /* ok, at last: we're happy. return the policy handle */
447 valid_pol
= register_policy_hnd(get_global_hnd_cache(),
448 cli_con_sec_ctx(con
),
449 hnd
, access_required
) &&
450 set_policy_con(get_global_hnd_cache(),
452 cli_connection_unlink
);
456 prs_free_data(&rbuf
);
457 prs_free_data(&buf
);
462 /****************************************************************************
464 ****************************************************************************/
465 BOOL
spoolss_closeprinter(POLICY_HND
*hnd
)
469 SPOOL_Q_CLOSEPRINTER q_c
;
470 BOOL valid_close
= False
;
472 if (hnd
== NULL
) return False
;
474 /* create and send a MSRPC command with api SPOOLSS_CLOSEPRINTER */
476 prs_init(&buf
, 0, 4, False
);
477 prs_init(&rbuf
, 0, 4, True
);
479 DEBUG(4,("SPOOL Close Printer\n"));
481 /* store the parameters */
482 make_spoolss_q_closeprinter(&q_c
, hnd
);
484 /* turn parameters into data stream */
485 if (spoolss_io_q_closeprinter("", &q_c
, &buf
, 0) &&
486 rpc_hnd_pipe_req(hnd
, SPOOLSS_CLOSEPRINTER
, &buf
, &rbuf
))
488 SPOOL_R_CLOSEPRINTER r_c
;
491 spoolss_io_r_closeprinter("", &r_c
, &rbuf
, 0);
492 p
= rbuf
.offset
!= 0;
494 if (p
&& r_c
.status
!= 0)
496 /* report error code */
497 DEBUG(0,("SPOOL_CLOSEPRINTER: %s\n", get_nt_error_msg(r_c
.status
)));
502 prs_free_data(&rbuf
);
503 prs_free_data(&buf
);
505 close_policy_hnd(get_global_hnd_cache(), hnd
);
510 /****************************************************************************
511 do a SPOOLSS Get printer datas
512 ****************************************************************************/
513 uint32
spoolss_getprinterdata(const POLICY_HND
*hnd
, const UNISTR2
*valuename
,
522 SPOOL_Q_GETPRINTERDATA q_o
;
523 SPOOL_R_GETPRINTERDATA r_o
;
526 return NT_STATUS_INVALID_PARAMETER
;
528 prs_init(&buf
, 0, 4, False
);
529 prs_init(&rbuf
, 0, 4, True
);
531 /* create and send a MSRPC command with api SPOOLSS_GETPRINTERDATA */
533 DEBUG(5,("SPOOLSS Get Printer data)\n"));
535 make_spoolss_q_getprinterdata(&q_o
, hnd
, valuename
, in_size
);
537 /* turn parameters into data stream */
538 if (!spoolss_io_q_getprinterdata("", &q_o
, &buf
, 0)) {
539 prs_free_data(&rbuf
);
540 prs_free_data(&buf
);
543 if(!rpc_hnd_pipe_req(hnd
, SPOOLSS_GETPRINTERDATA
, &buf
, &rbuf
)) {
544 prs_free_data(&rbuf
);
545 prs_free_data(&buf
);
549 prs_free_data(&buf
);
553 if(!spoolss_io_r_getprinterdata("", &r_o
, &rbuf
, 0)) {
554 prs_free_data(&rbuf
);
561 prs_free_data(&rbuf
);
562 prs_free_data(&buf
);
567 /****************************************************************************
568 do a SPOOLSS Get Printer Driver Direcotry
569 ****************************************************************************/
570 uint32
spoolss_getprinterdriverdir(fstring srv_name
, fstring env_name
, uint32 level
,
571 NEW_BUFFER
*buffer
, uint32 offered
,
576 SPOOL_Q_GETPRINTERDRIVERDIR q_o
;
577 SPOOL_R_GETPRINTERDRIVERDIR r_o
;
579 struct cli_connection
*con
= NULL
;
581 if (!cli_connection_init(srv_name
, PIPE_SPOOLSS
, &con
))
584 prs_init(&buf
, 0, 4, False
);
585 prs_init(&rbuf
, 0, 4, True
);
587 /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
589 DEBUG(5,("SPOOLSS GetPrinterDriverDir (Server: %s Env: %s level: %d)\n", srv_name
, env_name
, level
));
591 make_spoolss_q_getprinterdriverdir(&q_o
, srv_name
, env_name
, level
, buffer
, offered
);
593 /* turn parameters into data stream */
594 if (!spoolss_io_q_getprinterdriverdir("", &q_o
, &buf
, 0) ) {
595 prs_free_data(&rbuf
);
596 prs_free_data(&buf
);
598 cli_connection_unlink(con
);
601 if(!rpc_con_pipe_req(con
, SPOOLSS_GETPRINTERDRIVERDIRECTORY
, &buf
, &rbuf
)) {
602 prs_free_data(&rbuf
);
603 prs_free_data(&buf
);
605 cli_connection_unlink(con
);
608 prs_free_data(&buf
);
611 buffer
->prs
.io
=UNMARSHALL
;
612 buffer
->prs
.offset
=0;
615 if(!spoolss_io_r_getprinterdriverdir("", &r_o
, &rbuf
, 0)) {
616 prs_free_data(&rbuf
);
617 cli_connection_unlink(con
);
622 prs_free_data(&rbuf
);
623 prs_free_data(&buf
);
625 cli_connection_unlink(con
);