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 return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds);
41 NTSTATUS cli_spoolss_open_printer_ex(
42 struct cli_state *cli,
46 uint32 access_required,
52 prs_struct qbuf, rbuf;
53 SPOOL_Q_OPEN_PRINTER_EX q;
54 SPOOL_R_OPEN_PRINTER_EX r;
60 /* Initialise parse structures */
62 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
63 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
65 /* Initialise input parameters */
67 make_spoolss_q_open_printer_ex(&q, printername, datatype,
68 access_required, station, username);
70 /* Marshall data and send request */
72 if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
73 !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) {
74 result = NT_STATUS_UNSUCCESSFUL;
78 /* Unmarshall response */
80 if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) {
81 result = NT_STATUS_UNSUCCESSFUL;
85 /* Return output parameters */
87 if (W_ERROR_IS_OK(r.status)) {
88 result = NT_STATUS_OK;
91 result = werror_to_ntstatus(r.status);
101 /* Close a printer handle */
103 NTSTATUS cli_spoolss_close_printer(
104 struct cli_state *cli,
109 prs_struct qbuf, rbuf;
110 SPOOL_Q_CLOSEPRINTER q;
111 SPOOL_R_CLOSEPRINTER r;
117 /* Initialise parse structures */
119 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
120 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
122 /* Initialise input parameters */
124 make_spoolss_q_closeprinter(&q, pol);
126 /* Marshall data and send request */
128 if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
129 !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) {
130 result = NT_STATUS_UNSUCCESSFUL;
134 /* Unmarshall response */
136 if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) {
137 result = NT_STATUS_UNSUCCESSFUL;
141 /* Return output parameters */
143 if (W_ERROR_IS_OK(r.status)) {
145 result = NT_STATUS_OK;
147 result = werror_to_ntstatus(r.status);
157 /* Initialize a spoolss NEW_BUFFER */
159 static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
161 buffer->ptr = (size != 0);
163 buffer->string_at_end = size;
164 prs_init(&buffer->prs, size, ctx, MARSHALL);
165 buffer->struct_start = prs_offset(&buffer->prs);
168 /* Decode various printer info levels - perhaps this should live in
171 static void decode_printer_info_0(
175 PRINTER_INFO_0 **info
181 inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
183 buffer->prs.data_offset=0;
185 for (i=0; i<returned; i++) {
186 smb_io_printer_info_0("", buffer, &inf[i], 0);
192 static void decode_printer_info_1(
196 PRINTER_INFO_1 **info
202 inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1));
204 buffer->prs.data_offset=0;
206 for (i=0; i<returned; i++) {
207 smb_io_printer_info_1("", buffer, &inf[i], 0);
213 static void decode_printer_info_2(
217 PRINTER_INFO_2 **info
223 inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2));
225 buffer->prs.data_offset=0;
227 for (i=0; i<returned; i++) {
228 /* a little initialization as we go */
229 inf[i].secdesc = NULL;
230 smb_io_printer_info_2("", buffer, &inf[i], 0);
236 static void decode_printer_info_3(
240 PRINTER_INFO_3 **info
246 inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3));
248 buffer->prs.data_offset=0;
250 for (i=0; i<returned; i++) {
251 inf[i].secdesc = NULL;
252 smb_io_printer_info_3("", buffer, &inf[i], 0);
258 /**********************************************************************
259 Decode a PORT_INFO_1 struct from a NEW_BUFFER
260 **********************************************************************/
261 static void decode_port_info_1(
271 inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1));
273 prs_set_offset(&buffer->prs, 0);
275 for (i=0; i<returned; i++) {
276 smb_io_port_info_1("", buffer, &(inf[i]), 0);
282 /**********************************************************************
283 Decode a PORT_INFO_2 struct from a NEW_BUFFER
284 **********************************************************************/
285 static void decode_port_info_2(
294 inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2));
296 prs_set_offset(&buffer->prs, 0);
298 for (i=0; i<returned; i++) {
299 smb_io_port_info_2("", buffer, &(inf[i]), 0);
305 static void decode_printer_driver_1(
315 inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1));
317 buffer->prs.data_offset=0;
319 for (i=0; i<returned; i++) {
320 smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
326 static void decode_printer_driver_2(
336 inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2));
338 buffer->prs.data_offset=0;
340 for (i=0; i<returned; i++) {
341 smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
347 static void decode_printer_driver_3(
357 inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3));
359 buffer->prs.data_offset=0;
361 for (i=0; i<returned; i++) {
362 smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
368 static void decode_printerdriverdir_1 (
372 DRIVER_DIRECTORY_1 **info
375 DRIVER_DIRECTORY_1 *inf;
377 inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1));
379 prs_set_offset(&buffer->prs, 0);
381 smb_io_driverdir_1("", buffer, inf, 0);
387 /* Enumerate printers */
389 NTSTATUS cli_spoolss_enum_printers(
390 struct cli_state *cli,
395 PRINTER_INFO_CTR *ctr
398 prs_struct qbuf, rbuf;
399 SPOOL_Q_ENUMPRINTERS q;
400 SPOOL_R_ENUMPRINTERS r;
409 fstrcpy (server, cli->desthost);
413 /* Initialise input parameters */
415 init_buffer(&buffer, needed, mem_ctx);
417 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
418 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
420 make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
423 /* Marshall data and send request */
425 if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
426 !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) {
427 result = NT_STATUS_UNSUCCESSFUL;
431 /* Unmarshall response */
432 if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) {
436 /* Return output parameters */
437 if (!W_ERROR_IS_OK(r.status)) {
438 result = werror_to_ntstatus(r.status);
442 if ((*returned = r.returned)) {
445 decode_printer_info_1(mem_ctx, r.buffer, r.returned,
449 decode_printer_info_2(mem_ctx, r.buffer, r.returned,
453 decode_printer_info_3(mem_ctx, r.buffer, r.returned,
463 } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
468 /* Enumerate printer ports */
469 NTSTATUS cli_spoolss_enum_ports(
470 struct cli_state *cli,
477 prs_struct qbuf, rbuf;
488 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
492 /* Initialise input parameters */
494 init_buffer(&buffer, needed, mem_ctx);
496 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
497 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
499 make_spoolss_q_enumports(&q, server, level, &buffer, needed);
501 /* Marshall data and send request */
503 if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
504 !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) {
505 result = NT_STATUS_UNSUCCESSFUL;
509 /* Unmarshall response */
510 if (spoolss_io_r_enumports("", &r, &rbuf, 0)) {
514 /* Return output parameters */
515 result = werror_to_ntstatus(r.status);
517 if (NT_STATUS_IS_OK(result) &&
520 *returned = r.returned;
524 decode_port_info_1(mem_ctx, r.buffer, r.returned,
528 decode_port_info_2(mem_ctx, r.buffer, r.returned,
538 } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
543 /* Get printer info */
544 NTSTATUS cli_spoolss_getprinter(
545 struct cli_state *cli,
549 PRINTER_INFO_CTR *ctr
552 prs_struct qbuf, rbuf;
553 SPOOL_Q_GETPRINTER q;
554 SPOOL_R_GETPRINTER r;
563 /* Initialise input parameters */
565 init_buffer(&buffer, needed, mem_ctx);
567 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
568 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
570 make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, needed);
572 /* Marshall data and send request */
573 if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
574 !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
576 result = NT_STATUS_UNSUCCESSFUL;
580 /* Unmarshall response */
581 if (spoolss_io_r_getprinter("", &r, &rbuf, 0)) {
585 /* Return output parameters */
586 result = werror_to_ntstatus(r.status);
587 if (NT_STATUS_IS_OK(result)) {
590 decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
593 decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1);
596 decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2);
599 decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3);
608 } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
613 /**********************************************************************
616 NTSTATUS cli_spoolss_setprinter(
617 struct cli_state *cli,
621 PRINTER_INFO_CTR *ctr,
625 prs_struct qbuf, rbuf;
626 SPOOL_Q_SETPRINTER q;
627 SPOOL_R_SETPRINTER r;
628 NTSTATUS result = NT_STATUS_ACCESS_DENIED;
633 /* Initialise input parameters */
634 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
635 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
637 make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
639 /* Marshall data and send request */
640 if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
641 !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
643 result = NT_STATUS_ACCESS_DENIED;
647 /* Unmarshall response */
648 if (!spoolss_io_r_setprinter("", &r, &rbuf, 0))
653 result = werror_to_ntstatus(r.status);
663 /**********************************************************************
664 * Get installed printer drivers for a given printer
666 NTSTATUS cli_spoolss_getprinterdriver (
667 struct cli_state *cli,
672 PRINTER_DRIVER_CTR *ctr
675 prs_struct qbuf, rbuf;
676 SPOOL_Q_GETPRINTERDRIVER2 q;
677 SPOOL_R_GETPRINTERDRIVER2 r;
679 uint32 needed = 1024;
686 fstrcpy (server, cli->desthost);
691 /* Initialise input parameters */
693 init_buffer(&buffer, needed, mem_ctx);
695 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
696 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
699 /* write the request */
700 make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, &buffer, needed);
702 /* Marshall data and send request */
703 if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
704 !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
706 result = NT_STATUS_UNSUCCESSFUL;
710 /* Unmarshall response */
711 if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0))
716 /* Return output parameters */
717 result = werror_to_ntstatus(r.status);
718 if (NT_STATUS_IS_OK(result))
723 decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1);
726 decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2);
729 decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3);
738 } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
743 /**********************************************************************
744 * Get installed printer drivers for a given printer
746 NTSTATUS cli_spoolss_enumprinterdrivers (
747 struct cli_state *cli,
752 PRINTER_DRIVER_CTR *ctr
755 prs_struct qbuf, rbuf;
756 SPOOL_Q_ENUMPRINTERDRIVERS q;
757 SPOOL_R_ENUMPRINTERDRIVERS r;
766 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
771 /* Initialise input parameters */
772 init_buffer(&buffer, needed, mem_ctx);
774 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
775 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
778 /* write the request */
779 make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, needed);
781 /* Marshall data and send request */
782 if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
783 !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
785 result = NT_STATUS_UNSUCCESSFUL;
789 /* Unmarshall response */
790 if (spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0))
795 /* Return output parameters */
796 result = werror_to_ntstatus(r.status);
797 if (NT_STATUS_IS_OK(result) &&
800 *returned = r.returned;
805 decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1);
808 decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2);
811 decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3);
820 } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
826 /**********************************************************************
827 * Get installed printer drivers for a given printer
829 NTSTATUS cli_spoolss_getprinterdriverdir (
830 struct cli_state *cli,
834 DRIVER_DIRECTORY_CTR *ctr
837 prs_struct qbuf, rbuf;
838 SPOOL_Q_GETPRINTERDRIVERDIR q;
839 SPOOL_R_GETPRINTERDRIVERDIR r;
848 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
853 /* Initialise input parameters */
854 init_buffer(&buffer, needed, mem_ctx);
856 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
857 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
860 /* write the request */
861 make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, needed);
863 /* Marshall data and send request */
864 if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
865 !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &qbuf, &rbuf))
867 result = NT_STATUS_UNSUCCESSFUL;
871 /* Unmarshall response */
872 if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0))
877 /* Return output parameters */
878 result = werror_to_ntstatus(r.status);
879 if (NT_STATUS_IS_OK(result))
884 decode_printerdriverdir_1(mem_ctx, r.buffer, 1, &ctr->info1);
893 } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
898 /**********************************************************************
899 * Install a printer driver
901 NTSTATUS cli_spoolss_addprinterdriver (
902 struct cli_state *cli,
905 PRINTER_DRIVER_CTR *ctr
908 prs_struct qbuf, rbuf;
909 SPOOL_Q_ADDPRINTERDRIVER q;
910 SPOOL_R_ADDPRINTERDRIVER r;
911 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
917 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
920 /* Initialise input parameters */
921 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
922 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
925 /* write the request */
926 make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr);
928 /* Marshall data and send request */
929 result = NT_STATUS_UNSUCCESSFUL;
930 if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
931 !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
937 /* Unmarshall response */
938 result = NT_STATUS_UNSUCCESSFUL;
939 if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0))
944 /* Return output parameters */
945 result = werror_to_ntstatus(r.status);
954 /**********************************************************************
957 NTSTATUS cli_spoolss_addprinterex (
958 struct cli_state *cli,
961 PRINTER_INFO_CTR *ctr
964 prs_struct qbuf, rbuf;
965 SPOOL_Q_ADDPRINTEREX q;
966 SPOOL_R_ADDPRINTEREX r;
975 slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
977 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
979 fstrcpy (user, cli->user_name);
982 /* Initialise input parameters */
983 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
984 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
987 /* write the request */
988 make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, level, ctr);
990 /* Marshall data and send request */
991 result = NT_STATUS_UNSUCCESSFUL;
992 if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
993 !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
999 /* Unmarshall response */
1000 result = NT_STATUS_UNSUCCESSFUL;
1001 if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0))
1006 /* Return output parameters */
1007 result = werror_to_ntstatus(r.status);
1010 prs_mem_free(&qbuf);
1011 prs_mem_free(&rbuf);
1016 /**********************************************************************
1017 * Delete a Printer Driver from the server (does not remove
1020 NTSTATUS cli_spoolss_deleteprinterdriver (
1021 struct cli_state *cli,
1022 TALLOC_CTX *mem_ctx,
1027 prs_struct qbuf, rbuf;
1028 SPOOL_Q_DELETEPRINTERDRIVER q;
1029 SPOOL_R_DELETEPRINTERDRIVER r;
1037 /* Initialise input parameters */
1038 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1039 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1041 slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1044 /* write the request */
1045 make_spoolss_q_deleteprinterdriver (mem_ctx, &q, server, arch, driver);
1047 /* Marshall data and send request */
1048 result = NT_STATUS_UNSUCCESSFUL;
1049 if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
1050 !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
1056 /* Unmarshall response */
1057 result = NT_STATUS_UNSUCCESSFUL;
1058 if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0))
1063 /* Return output parameters */
1064 result = werror_to_ntstatus(r.status);
1067 prs_mem_free(&qbuf);
1068 prs_mem_free(&rbuf);