2 Unix SMB/Netbios implementation.
6 Copyright (C) Gerald Carter 2001,
7 Copyright (C) Tim Potter 2000,
8 Copyright (C) Andrew Tridgell 1994-2000
9 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
10 Copyright (C) Jean-Francois Micouleau 1999-2000
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 extern pstring global_myname
;
31 /* Opens a SMB connection to the SPOOLSS pipe */
32 struct cli_state
*cli_spoolss_initialise(struct cli_state
*cli
,
34 struct ntuser_creds
*creds
)
36 struct in_addr dest_ip
;
37 struct nmb_name calling
, called
;
39 extern pstring global_myname
;
40 struct ntuser_creds anon
;
42 /* Initialise cli_state information */
44 if (!cli_initialise(cli
)) {
50 anon
.pwd
.null_pwd
= 1;
54 cli_init_creds(cli
, creds
);
56 /* Establish a SMB connection */
58 if (!resolve_srv_name(system_name
, dest_host
, &dest_ip
)) {
62 make_nmb_name(&called
, dns_to_netbios_name(dest_host
), 0x20);
63 make_nmb_name(&calling
, dns_to_netbios_name(global_myname
), 0);
65 if (!cli_establish_connection(cli
, dest_host
, &dest_ip
, &calling
,
66 &called
, "IPC$", "IPC", False
, True
)) {
70 /* Open a NT session thingy */
72 if (!cli_nt_session_open(cli
, PIPE_SPOOLSS
)) {
80 /* Shut down a SMB connection to the SPOOLSS pipe */
82 void cli_spoolss_shutdown(struct cli_state
*cli
)
84 if (cli
->fd
!= -1) cli_ulogoff(cli
);
90 uint32
cli_spoolss_open_printer_ex(
91 struct cli_state
*cli
,
95 uint32 access_required
,
101 prs_struct qbuf
, rbuf
;
102 SPOOL_Q_OPEN_PRINTER_EX q
;
103 SPOOL_R_OPEN_PRINTER_EX r
;
109 /* Initialise parse structures */
111 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
112 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
114 /* Initialise input parameters */
116 make_spoolss_q_open_printer_ex(&q
, printername
, datatype
,
117 access_required
, station
, username
);
119 /* Marshall data and send request */
121 if (!spoolss_io_q_open_printer_ex("", &q
, &qbuf
, 0) ||
122 !rpc_api_pipe_req(cli
, SPOOLSS_OPENPRINTEREX
, &qbuf
, &rbuf
)) {
123 result
= NT_STATUS_UNSUCCESSFUL
;
127 /* Unmarshall response */
129 if (!spoolss_io_r_open_printer_ex("", &r
, &rbuf
, 0)) {
130 result
= NT_STATUS_UNSUCCESSFUL
;
134 /* Return output parameters */
136 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
147 /* Close a printer handle */
149 uint32
cli_spoolss_close_printer(
150 struct cli_state
*cli
,
155 prs_struct qbuf
, rbuf
;
156 SPOOL_Q_CLOSEPRINTER q
;
157 SPOOL_R_CLOSEPRINTER r
;
163 /* Initialise parse structures */
165 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
166 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
168 /* Initialise input parameters */
170 make_spoolss_q_closeprinter(&q
, pol
);
172 /* Marshall data and send request */
174 if (!spoolss_io_q_closeprinter("", &q
, &qbuf
, 0) ||
175 !rpc_api_pipe_req(cli
, SPOOLSS_CLOSEPRINTER
, &qbuf
, &rbuf
)) {
176 result
= NT_STATUS_UNSUCCESSFUL
;
180 /* Unmarshall response */
182 if (!spoolss_io_r_closeprinter("", &r
, &rbuf
, 0)) {
183 result
= NT_STATUS_UNSUCCESSFUL
;
187 /* Return output parameters */
189 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
200 /* Initialize a spoolss NEW_BUFFER */
202 static void init_buffer(NEW_BUFFER
*buffer
, uint32 size
, TALLOC_CTX
*ctx
)
204 buffer
->ptr
= (size
!= 0);
206 buffer
->string_at_end
= size
;
207 prs_init(&buffer
->prs
, size
, ctx
, MARSHALL
);
208 buffer
->struct_start
= prs_offset(&buffer
->prs
);
211 /* Decode various printer info levels - perhaps this should live in
214 static void decode_printer_info_0(
218 PRINTER_INFO_0
**info
224 inf
=(PRINTER_INFO_0
*)malloc(returned
*sizeof(PRINTER_INFO_0
));
226 buffer
->prs
.data_offset
=0;
228 for (i
=0; i
<returned
; i
++) {
229 smb_io_printer_info_0("", buffer
, &inf
[i
], 0);
235 static void decode_printer_info_1(
239 PRINTER_INFO_1
**info
245 inf
=(PRINTER_INFO_1
*)talloc(mem_ctx
, returned
*sizeof(PRINTER_INFO_1
));
247 buffer
->prs
.data_offset
=0;
249 for (i
=0; i
<returned
; i
++) {
250 smb_io_printer_info_1("", buffer
, &inf
[i
], 0);
256 static void decode_printer_info_2(
260 PRINTER_INFO_2
**info
266 inf
=(PRINTER_INFO_2
*)talloc(mem_ctx
, returned
*sizeof(PRINTER_INFO_2
));
268 buffer
->prs
.data_offset
=0;
270 for (i
=0; i
<returned
; i
++) {
271 /* a little initialization as we go */
272 inf
[i
].secdesc
= NULL
;
273 smb_io_printer_info_2("", buffer
, &inf
[i
], 0);
279 static void decode_printer_info_3(
283 PRINTER_INFO_3
**info
289 inf
=(PRINTER_INFO_3
*)talloc(mem_ctx
, returned
*sizeof(PRINTER_INFO_3
));
291 buffer
->prs
.data_offset
=0;
293 for (i
=0; i
<returned
; i
++) {
294 inf
[i
].secdesc
= NULL
;
295 smb_io_printer_info_3("", buffer
, &inf
[i
], 0);
301 /**********************************************************************
302 Decode a PORT_INFO_1 struct from a NEW_BUFFER
303 **********************************************************************/
304 static void decode_port_info_1(
314 inf
=(PORT_INFO_1
*)talloc(mem_ctx
, returned
*sizeof(PORT_INFO_1
));
316 prs_set_offset(&buffer
->prs
, 0);
318 for (i
=0; i
<returned
; i
++) {
319 smb_io_port_info_1("", buffer
, &(inf
[i
]), 0);
325 /**********************************************************************
326 Decode a PORT_INFO_2 struct from a NEW_BUFFER
327 **********************************************************************/
328 static void decode_port_info_2(
337 inf
=(PORT_INFO_2
*)talloc(mem_ctx
, returned
*sizeof(PORT_INFO_2
));
339 prs_set_offset(&buffer
->prs
, 0);
341 for (i
=0; i
<returned
; i
++) {
342 smb_io_port_info_2("", buffer
, &(inf
[i
]), 0);
348 static void decode_printer_driver_1(
358 inf
=(DRIVER_INFO_1
*)talloc(mem_ctx
, returned
*sizeof(DRIVER_INFO_1
));
360 buffer
->prs
.data_offset
=0;
362 for (i
=0; i
<returned
; i
++) {
363 smb_io_printer_driver_info_1("", buffer
, &(inf
[i
]), 0);
369 static void decode_printer_driver_2(
379 inf
=(DRIVER_INFO_2
*)talloc(mem_ctx
, returned
*sizeof(DRIVER_INFO_2
));
381 buffer
->prs
.data_offset
=0;
383 for (i
=0; i
<returned
; i
++) {
384 smb_io_printer_driver_info_2("", buffer
, &(inf
[i
]), 0);
390 static void decode_printer_driver_3(
400 inf
=(DRIVER_INFO_3
*)talloc(mem_ctx
, returned
*sizeof(DRIVER_INFO_3
));
402 buffer
->prs
.data_offset
=0;
404 for (i
=0; i
<returned
; i
++) {
405 smb_io_printer_driver_info_3("", buffer
, &(inf
[i
]), 0);
411 static void decode_printerdriverdir_1 (
415 DRIVER_DIRECTORY_1
**info
418 DRIVER_DIRECTORY_1
*inf
;
420 inf
=(DRIVER_DIRECTORY_1
*)talloc(mem_ctx
, sizeof(DRIVER_DIRECTORY_1
));
422 prs_set_offset(&buffer
->prs
, 0);
424 smb_io_driverdir_1("", buffer
, inf
, 0);
430 /* Enumerate printers */
432 uint32
cli_spoolss_enum_printers(
433 struct cli_state
*cli
,
438 PRINTER_INFO_CTR
*ctr
441 prs_struct qbuf
, rbuf
;
442 SPOOL_Q_ENUMPRINTERS q
;
443 SPOOL_R_ENUMPRINTERS r
;
452 fstrcpy (server
, cli
->desthost
);
456 /* Initialise input parameters */
458 init_buffer(&buffer
, needed
, mem_ctx
);
460 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
461 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
463 make_spoolss_q_enumprinters(&q
, flags
, server
, level
, &buffer
,
466 /* Marshall data and send request */
468 if (!spoolss_io_q_enumprinters("", &q
, &qbuf
, 0) ||
469 !rpc_api_pipe_req(cli
, SPOOLSS_ENUMPRINTERS
, &qbuf
, &rbuf
)) {
470 result
= NT_STATUS_UNSUCCESSFUL
;
474 /* Unmarshall response */
475 if (spoolss_io_r_enumprinters("", &r
, &rbuf
, 0)) {
479 /* Return output parameters */
481 if (((result
=r
.status
) == NT_STATUS_NOPROBLEMO
) && (*returned
= r
.returned
))
486 decode_printer_info_1(mem_ctx
, r
.buffer
, r
.returned
,
490 decode_printer_info_2(mem_ctx
, r
.buffer
, r
.returned
,
494 decode_printer_info_3(mem_ctx
, r
.buffer
, r
.returned
,
504 } while (result
== ERROR_INSUFFICIENT_BUFFER
);
509 /* Enumerate printer ports */
510 uint32
cli_spoolss_enum_ports(
511 struct cli_state
*cli
,
518 prs_struct qbuf
, rbuf
;
529 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
533 /* Initialise input parameters */
535 init_buffer(&buffer
, needed
, mem_ctx
);
537 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
538 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
540 make_spoolss_q_enumports(&q
, server
, level
, &buffer
, needed
);
542 /* Marshall data and send request */
544 if (!spoolss_io_q_enumports("", &q
, &qbuf
, 0) ||
545 !rpc_api_pipe_req(cli
, SPOOLSS_ENUMPORTS
, &qbuf
, &rbuf
)) {
546 result
= NT_STATUS_UNSUCCESSFUL
;
550 /* Unmarshall response */
551 if (spoolss_io_r_enumports("", &r
, &rbuf
, 0)) {
555 /* Return output parameters */
557 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
&&
560 *returned
= r
.returned
;
564 decode_port_info_1(mem_ctx
, r
.buffer
, r
.returned
,
568 decode_port_info_2(mem_ctx
, r
.buffer
, r
.returned
,
578 } while (result
== ERROR_INSUFFICIENT_BUFFER
);
583 /* Get printer info */
584 uint32
cli_spoolss_getprinter(
585 struct cli_state
*cli
,
589 PRINTER_INFO_CTR
*ctr
592 prs_struct qbuf
, rbuf
;
593 SPOOL_Q_GETPRINTER q
;
594 SPOOL_R_GETPRINTER r
;
603 /* Initialise input parameters */
605 init_buffer(&buffer
, needed
, mem_ctx
);
607 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
608 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
610 make_spoolss_q_getprinter(mem_ctx
, &q
, pol
, level
, &buffer
, needed
);
612 /* Marshall data and send request */
613 if (!spoolss_io_q_getprinter("", &q
, &qbuf
, 0) ||
614 !rpc_api_pipe_req(cli
, SPOOLSS_GETPRINTER
, &qbuf
, &rbuf
))
616 result
= NT_STATUS_UNSUCCESSFUL
;
620 /* Unmarshall response */
621 if (spoolss_io_r_getprinter("", &r
, &rbuf
, 0)) {
625 /* Return output parameters */
626 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
630 decode_printer_info_0(mem_ctx
, r
.buffer
, 1, &ctr
->printers_0
);
633 decode_printer_info_1(mem_ctx
, r
.buffer
, 1, &ctr
->printers_1
);
636 decode_printer_info_2(mem_ctx
, r
.buffer
, 1, &ctr
->printers_2
);
639 decode_printer_info_3(mem_ctx
, r
.buffer
, 1, &ctr
->printers_3
);
648 } while (result
== ERROR_INSUFFICIENT_BUFFER
);
653 /**********************************************************************
656 uint32
cli_spoolss_setprinter(
657 struct cli_state
*cli
,
661 PRINTER_INFO_CTR
*ctr
,
665 prs_struct qbuf
, rbuf
;
666 SPOOL_Q_SETPRINTER q
;
667 SPOOL_R_SETPRINTER r
;
668 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
673 /* Initialise input parameters */
674 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
675 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
677 make_spoolss_q_setprinter(mem_ctx
, &q
, pol
, level
, ctr
, command
);
679 /* Marshall data and send request */
680 result
= NT_STATUS_UNSUCCESSFUL
;
681 if (!spoolss_io_q_setprinter("", &q
, &qbuf
, 0) ||
682 !rpc_api_pipe_req(cli
, SPOOLSS_SETPRINTER
, &qbuf
, &rbuf
))
684 result
= NT_STATUS_UNSUCCESSFUL
;
688 /* Unmarshall response */
689 result
= NT_STATUS_UNSUCCESSFUL
;
690 if (!spoolss_io_r_setprinter("", &r
, &rbuf
, 0))
705 /**********************************************************************
706 * Get installed printer drivers for a given printer
708 uint32
cli_spoolss_getprinterdriver (
709 struct cli_state
*cli
,
714 PRINTER_DRIVER_CTR
*ctr
717 prs_struct qbuf
, rbuf
;
718 SPOOL_Q_GETPRINTERDRIVER2 q
;
719 SPOOL_R_GETPRINTERDRIVER2 r
;
721 uint32 needed
= 1024;
728 fstrcpy (server
, cli
->desthost
);
733 /* Initialise input parameters */
735 init_buffer(&buffer
, needed
, mem_ctx
);
737 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
738 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
741 /* write the request */
742 make_spoolss_q_getprinterdriver2(&q
, pol
, env
, level
, 2, 2, &buffer
, needed
);
744 /* Marshall data and send request */
745 if (!spoolss_io_q_getprinterdriver2 ("", &q
, &qbuf
, 0) ||
746 !rpc_api_pipe_req (cli
, SPOOLSS_GETPRINTERDRIVER2
, &qbuf
, &rbuf
))
748 result
= NT_STATUS_UNSUCCESSFUL
;
752 /* Unmarshall response */
753 if (spoolss_io_r_getprinterdriver2 ("", &r
, &rbuf
, 0))
758 /* Return output parameters */
759 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
)
765 decode_printer_driver_1(mem_ctx
, r
.buffer
, 1, &ctr
->info1
);
768 decode_printer_driver_2(mem_ctx
, r
.buffer
, 1, &ctr
->info2
);
771 decode_printer_driver_3(mem_ctx
, r
.buffer
, 1, &ctr
->info3
);
780 } while (result
== ERROR_INSUFFICIENT_BUFFER
);
785 /**********************************************************************
786 * Get installed printer drivers for a given printer
788 uint32
cli_spoolss_enumprinterdrivers (
789 struct cli_state
*cli
,
794 PRINTER_DRIVER_CTR
*ctr
797 prs_struct qbuf
, rbuf
;
798 SPOOL_Q_ENUMPRINTERDRIVERS q
;
799 SPOOL_R_ENUMPRINTERDRIVERS r
;
808 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
813 /* Initialise input parameters */
814 init_buffer(&buffer
, needed
, mem_ctx
);
816 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
817 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
820 /* write the request */
821 make_spoolss_q_enumprinterdrivers(&q
, server
, env
, level
, &buffer
, needed
);
823 /* Marshall data and send request */
824 if (!spoolss_io_q_enumprinterdrivers ("", &q
, &qbuf
, 0) ||
825 !rpc_api_pipe_req (cli
, SPOOLSS_ENUMPRINTERDRIVERS
, &qbuf
, &rbuf
))
827 result
= NT_STATUS_UNSUCCESSFUL
;
831 /* Unmarshall response */
832 if (spoolss_io_r_enumprinterdrivers ("", &r
, &rbuf
, 0))
837 /* Return output parameters */
838 if (((result
=r
.status
) == NT_STATUS_NOPROBLEMO
) &&
841 *returned
= r
.returned
;
846 decode_printer_driver_1(mem_ctx
, r
.buffer
, r
.returned
, &ctr
->info1
);
849 decode_printer_driver_2(mem_ctx
, r
.buffer
, r
.returned
, &ctr
->info2
);
852 decode_printer_driver_3(mem_ctx
, r
.buffer
, r
.returned
, &ctr
->info3
);
861 } while (result
== ERROR_INSUFFICIENT_BUFFER
);
867 /**********************************************************************
868 * Get installed printer drivers for a given printer
870 uint32
cli_spoolss_getprinterdriverdir (
871 struct cli_state
*cli
,
875 DRIVER_DIRECTORY_CTR
*ctr
878 prs_struct qbuf
, rbuf
;
879 SPOOL_Q_GETPRINTERDRIVERDIR q
;
880 SPOOL_R_GETPRINTERDRIVERDIR r
;
889 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
894 /* Initialise input parameters */
895 init_buffer(&buffer
, needed
, mem_ctx
);
897 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
898 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
901 /* write the request */
902 make_spoolss_q_getprinterdriverdir(&q
, server
, env
, level
, &buffer
, needed
);
904 /* Marshall data and send request */
905 if (!spoolss_io_q_getprinterdriverdir ("", &q
, &qbuf
, 0) ||
906 !rpc_api_pipe_req (cli
, SPOOLSS_GETPRINTERDRIVERDIRECTORY
, &qbuf
, &rbuf
))
908 result
= NT_STATUS_UNSUCCESSFUL
;
912 /* Unmarshall response */
913 if (spoolss_io_r_getprinterdriverdir ("", &r
, &rbuf
, 0))
918 /* Return output parameters */
919 if ((result
=r
.status
) == NT_STATUS_NOPROBLEMO
)
924 decode_printerdriverdir_1(mem_ctx
, r
.buffer
, 1, &ctr
->info1
);
933 } while (result
== ERROR_INSUFFICIENT_BUFFER
);
938 /**********************************************************************
939 * Install a printer driver
941 uint32
cli_spoolss_addprinterdriver (
942 struct cli_state
*cli
,
945 PRINTER_DRIVER_CTR
*ctr
948 prs_struct qbuf
, rbuf
;
949 SPOOL_Q_ADDPRINTERDRIVER q
;
950 SPOOL_R_ADDPRINTERDRIVER r
;
951 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
957 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
960 /* Initialise input parameters */
961 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
962 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
965 /* write the request */
966 make_spoolss_q_addprinterdriver (mem_ctx
, &q
, server
, level
, ctr
);
968 /* Marshall data and send request */
969 result
= NT_STATUS_UNSUCCESSFUL
;
970 if (!spoolss_io_q_addprinterdriver ("", &q
, &qbuf
, 0) ||
971 !rpc_api_pipe_req (cli
, SPOOLSS_ADDPRINTERDRIVER
, &qbuf
, &rbuf
))
977 /* Unmarshall response */
978 result
= NT_STATUS_UNSUCCESSFUL
;
979 if (!spoolss_io_r_addprinterdriver ("", &r
, &rbuf
, 0))
984 /* Return output parameters */
994 /**********************************************************************
997 uint32
cli_spoolss_addprinterex (
998 struct cli_state
*cli
,
1001 PRINTER_INFO_CTR
*ctr
1004 prs_struct qbuf
, rbuf
;
1005 SPOOL_Q_ADDPRINTEREX q
;
1006 SPOOL_R_ADDPRINTEREX r
;
1015 slprintf (client
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
1017 slprintf (server
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
1019 fstrcpy (user
, cli
->user_name
);
1022 /* Initialise input parameters */
1023 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1024 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1027 /* write the request */
1028 make_spoolss_q_addprinterex (mem_ctx
, &q
, server
, client
, user
, level
, ctr
);
1030 /* Marshall data and send request */
1031 result
= NT_STATUS_UNSUCCESSFUL
;
1032 if (!spoolss_io_q_addprinterex ("", &q
, &qbuf
, 0) ||
1033 !rpc_api_pipe_req (cli
, SPOOLSS_ADDPRINTEREX
, &qbuf
, &rbuf
))
1039 /* Unmarshall response */
1040 result
= NT_STATUS_UNSUCCESSFUL
;
1041 if (!spoolss_io_r_addprinterex ("", &r
, &rbuf
, 0))
1046 /* Return output parameters */
1050 prs_mem_free(&qbuf
);
1051 prs_mem_free(&rbuf
);