source: vendor/current/source3/rpcclient/cmd_spoolss.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 100.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
4
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
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 3 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, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26#include "rpcclient.h"
27#include "../librpc/gen_ndr/ndr_spoolss_c.h"
28#include "../librpc/gen_ndr/ndr_spoolss.h"
29#include "rpc_client/cli_spoolss.h"
30#include "rpc_client/init_spoolss.h"
31#include "nt_printing.h"
32#include "../libcli/security/display_sec.h"
33#include "../libcli/security/security_descriptor.h"
34#include "../libcli/registry/util_reg.h"
35#include "libsmb/libsmb.h"
36
37#define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
38{ \
39 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
40 _cli->srv_name_slash, _arg); \
41 W_ERROR_HAVE_NO_MEMORY(_printername); \
42}
43
44/* The version int is used by getdrivers. Note that
45 all architecture strings that support mutliple
46 versions must be grouped together since enumdrivers
47 uses this property to prevent issuing multiple
48 enumdriver calls for the same arch */
49
50
51static const struct print_architecture_table_node archi_table[]= {
52
53 {"Windows 4.0", "WIN40", 0 },
54 {"Windows NT x86", "W32X86", 2 },
55 {"Windows NT x86", "W32X86", 3 },
56 {"Windows NT R4000", "W32MIPS", 2 },
57 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
58 {"Windows NT PowerPC", "W32PPC", 2 },
59 {"Windows IA64", "IA64", 3 },
60 {"Windows x64", "x64", 3 },
61 {NULL, "", -1 }
62};
63
64/**
65 * @file
66 *
67 * rpcclient module for SPOOLSS rpc pipe.
68 *
69 * This generally just parses and checks command lines, and then calls
70 * a cli_spoolss function.
71 **/
72
73/****************************************************************************
74 function to do the mapping between the long architecture name and
75 the short one.
76****************************************************************************/
77
78static const char *cmd_spoolss_get_short_archi(const char *long_archi)
79{
80 int i=-1;
81
82 DEBUG(107,("Getting architecture dependent directory\n"));
83 do {
84 i++;
85 } while ( (archi_table[i].long_archi!=NULL ) &&
86 strcasecmp_m(long_archi, archi_table[i].long_archi) );
87
88 if (archi_table[i].long_archi==NULL) {
89 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
90 return NULL;
91 }
92
93 /* this might be client code - but shouldn't this be an fstrcpy etc? */
94
95
96 DEBUGADD(108,("index: [%d]\n", i));
97 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
98 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
99
100 return archi_table[i].short_archi;
101}
102
103/****************************************************************************
104****************************************************************************/
105
106static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
107 TALLOC_CTX *mem_ctx,
108 int argc, const char **argv)
109{
110 WERROR werror;
111 struct policy_handle hnd;
112 uint32_t access_mask = PRINTER_ALL_ACCESS;
113 struct dcerpc_binding_handle *b = cli->binding_handle;
114
115 if (argc < 2) {
116 printf("Usage: %s <printername> [access_mask]\n", argv[0]);
117 return WERR_OK;
118 }
119
120 if (argc >= 3) {
121 sscanf(argv[2], "%x", &access_mask);
122 }
123
124 /* Open the printer handle */
125
126 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
127 argv[1],
128 access_mask,
129 &hnd);
130 if (W_ERROR_IS_OK(werror)) {
131 printf("Printer %s opened successfully\n", argv[1]);
132 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &werror);
133
134 if (!W_ERROR_IS_OK(werror)) {
135 printf("Error closing printer handle! (%s)\n",
136 get_dos_error_msg(werror));
137 }
138 }
139
140 return werror;
141}
142
143/****************************************************************************
144****************************************************************************/
145
146static WERROR cmd_spoolss_open_printer(struct rpc_pipe_client *cli,
147 TALLOC_CTX *mem_ctx,
148 int argc, const char **argv)
149{
150 WERROR werror;
151 struct policy_handle hnd;
152 uint32_t access_mask = PRINTER_ALL_ACCESS;
153 NTSTATUS status;
154 struct spoolss_DevmodeContainer devmode_ctr;
155 struct dcerpc_binding_handle *b = cli->binding_handle;
156
157 ZERO_STRUCT(devmode_ctr);
158
159 if (argc < 2) {
160 printf("Usage: %s <printername> [access_mask]\n", argv[0]);
161 return WERR_OK;
162 }
163
164 if (argc >= 3) {
165 sscanf(argv[2], "%x", &access_mask);
166 }
167
168 /* Open the printer handle */
169
170 status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
171 argv[1],
172 NULL,
173 devmode_ctr,
174 access_mask,
175 &hnd,
176 &werror);
177 if (!NT_STATUS_IS_OK(status)) {
178 return ntstatus_to_werror(status);
179 }
180 if (W_ERROR_IS_OK(werror)) {
181 printf("Printer %s opened successfully\n", argv[1]);
182 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &werror);
183
184 if (!W_ERROR_IS_OK(werror)) {
185 printf("Error closing printer handle! (%s)\n",
186 get_dos_error_msg(werror));
187 }
188 }
189
190 return werror;
191}
192
193/****************************************************************************
194****************************************************************************/
195
196static void display_print_info0(struct spoolss_PrinterInfo0 *r)
197{
198 if (!r)
199 return;
200
201 printf("\tprintername:[%s]\n", r->printername);
202 printf("\tservername:[%s]\n", r->servername);
203 printf("\tcjobs:[0x%x]\n", r->cjobs);
204 printf("\ttotal_jobs:[0x%x]\n", r->total_jobs);
205 printf("\ttotal_bytes:[0x%x]\n", r->total_bytes);
206 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month,
207 r->time.day, r->time.day_of_week);
208 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute,
209 r->time.second, r->time.millisecond);
210
211 printf("\tglobal_counter:[0x%x]\n", r->global_counter);
212 printf("\ttotal_pages:[0x%x]\n", r->total_pages);
213
214 printf("\tversion:[0x%x]\n", r->version);
215 printf("\tfree_build:[0x%x]\n", r->free_build);
216 printf("\tspooling:[0x%x]\n", r->spooling);
217 printf("\tmax_spooling:[0x%x]\n", r->max_spooling);
218 printf("\tsession_counter:[0x%x]\n", r->session_counter);
219 printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper);
220 printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready);
221 printf("\tjob_error:[0x%x]\n", r->job_error);
222 printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors);
223 printf("\tprocessor_type:[0x%x]\n", r->processor_type);
224 printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes);
225 printf("\tchange_id:[0x%x]\n", r->change_id);
226 printf("\tlast_error: %s\n", win_errstr(r->last_error));
227 printf("\tstatus:[0x%x]\n", r->status);
228 printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers);
229 printf("\tc_setprinter:[0x%x]\n", r->c_setprinter);
230 printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture);
231 printf("\tprocessor_level:[0x%x]\n", r->processor_level);
232 printf("\tref_ic:[0x%x]\n", r->ref_ic);
233 printf("\treserved2:[0x%x]\n", r->reserved2);
234 printf("\treserved3:[0x%x]\n", r->reserved3);
235
236 printf("\n");
237}
238
239/****************************************************************************
240****************************************************************************/
241
242static void display_print_info1(struct spoolss_PrinterInfo1 *r)
243{
244 printf("\tflags:[0x%x]\n", r->flags);
245 printf("\tname:[%s]\n", r->name);
246 printf("\tdescription:[%s]\n", r->description);
247 printf("\tcomment:[%s]\n", r->comment);
248
249 printf("\n");
250}
251
252/****************************************************************************
253****************************************************************************/
254
255static void display_print_info2(struct spoolss_PrinterInfo2 *r)
256{
257 printf("\tservername:[%s]\n", r->servername);
258 printf("\tprintername:[%s]\n", r->printername);
259 printf("\tsharename:[%s]\n", r->sharename);
260 printf("\tportname:[%s]\n", r->portname);
261 printf("\tdrivername:[%s]\n", r->drivername);
262 printf("\tcomment:[%s]\n", r->comment);
263 printf("\tlocation:[%s]\n", r->location);
264 printf("\tsepfile:[%s]\n", r->sepfile);
265 printf("\tprintprocessor:[%s]\n", r->printprocessor);
266 printf("\tdatatype:[%s]\n", r->datatype);
267 printf("\tparameters:[%s]\n", r->parameters);
268 printf("\tattributes:[0x%x]\n", r->attributes);
269 printf("\tpriority:[0x%x]\n", r->priority);
270 printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority);
271 printf("\tstarttime:[0x%x]\n", r->starttime);
272 printf("\tuntiltime:[0x%x]\n", r->untiltime);
273 printf("\tstatus:[0x%x]\n", r->status);
274 printf("\tcjobs:[0x%x]\n", r->cjobs);
275 printf("\taverageppm:[0x%x]\n", r->averageppm);
276
277 if (r->secdesc)
278 display_sec_desc(r->secdesc);
279
280 printf("\n");
281}
282
283/****************************************************************************
284****************************************************************************/
285
286static void display_print_info3(struct spoolss_PrinterInfo3 *r)
287{
288 display_sec_desc(r->secdesc);
289
290 printf("\n");
291}
292
293/****************************************************************************
294****************************************************************************/
295
296static void display_print_info4(struct spoolss_PrinterInfo4 *r)
297{
298 printf("\tservername:[%s]\n", r->servername);
299 printf("\tprintername:[%s]\n", r->printername);
300 printf("\tattributes:[0x%x]\n", r->attributes);
301 printf("\n");
302}
303
304/****************************************************************************
305****************************************************************************/
306
307static void display_print_info5(struct spoolss_PrinterInfo5 *r)
308{
309 printf("\tprintername:[%s]\n", r->printername);
310 printf("\tportname:[%s]\n", r->portname);
311 printf("\tattributes:[0x%x]\n", r->attributes);
312 printf("\tdevice_not_selected_timeout:[0x%x]\n", r->device_not_selected_timeout);
313 printf("\ttransmission_retry_timeout:[0x%x]\n", r->transmission_retry_timeout);
314 printf("\n");
315}
316
317/****************************************************************************
318****************************************************************************/
319
320static void display_print_info6(struct spoolss_PrinterInfo6 *r)
321{
322 printf("\tstatus:[0x%x]\n", r->status);
323 printf("\n");
324}
325
326/****************************************************************************
327****************************************************************************/
328
329static void display_print_info7(struct spoolss_PrinterInfo7 *r)
330{
331 printf("\tguid:[%s]\n", r->guid);
332 printf("\taction:[0x%x]\n", r->action);
333 printf("\n");
334}
335
336/****************************************************************************
337****************************************************************************/
338
339static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
340 TALLOC_CTX *mem_ctx,
341 int argc, const char **argv)
342{
343 WERROR result;
344 uint32_t level = 1;
345 union spoolss_PrinterInfo *info;
346 uint32_t i, count;
347 const char *name;
348 uint32_t flags = PRINTER_ENUM_LOCAL;
349
350 if (argc > 4) {
351 printf("Usage: %s [level] [name] [flags]\n", argv[0]);
352 return WERR_OK;
353 }
354
355 if (argc >= 2) {
356 level = atoi(argv[1]);
357 }
358
359 if (argc >= 3) {
360 name = argv[2];
361 } else {
362 name = cli->srv_name_slash;
363 }
364
365 if (argc == 4) {
366 flags = atoi(argv[3]);
367 }
368
369 result = rpccli_spoolss_enumprinters(cli, mem_ctx,
370 flags,
371 name,
372 level,
373 0,
374 &count,
375 &info);
376 if (W_ERROR_IS_OK(result)) {
377
378 if (!count) {
379 printf ("No printers returned.\n");
380 goto done;
381 }
382
383 for (i = 0; i < count; i++) {
384 switch (level) {
385 case 0:
386 display_print_info0(&info[i].info0);
387 break;
388 case 1:
389 display_print_info1(&info[i].info1);
390 break;
391 case 2:
392 display_print_info2(&info[i].info2);
393 break;
394 case 3:
395 display_print_info3(&info[i].info3);
396 break;
397 case 4:
398 display_print_info4(&info[i].info4);
399 break;
400 case 5:
401 display_print_info5(&info[i].info5);
402 break;
403 case 6:
404 display_print_info6(&info[i].info6);
405 break;
406 default:
407 printf("unknown info level %d\n", level);
408 goto done;
409 }
410 }
411 }
412 done:
413
414 return result;
415}
416
417/****************************************************************************
418****************************************************************************/
419
420static void display_port_info_1(struct spoolss_PortInfo1 *r)
421{
422 printf("\tPort Name:\t[%s]\n", r->port_name);
423}
424
425/****************************************************************************
426****************************************************************************/
427
428static void display_port_info_2(struct spoolss_PortInfo2 *r)
429{
430 printf("\tPort Name:\t[%s]\n", r->port_name);
431 printf("\tMonitor Name:\t[%s]\n", r->monitor_name);
432 printf("\tDescription:\t[%s]\n", r->description);
433 printf("\tPort Type:\t" );
434 if (r->port_type) {
435 int comma = 0; /* hack */
436 printf( "[" );
437 if (r->port_type & SPOOLSS_PORT_TYPE_READ) {
438 printf( "Read" );
439 comma = 1;
440 }
441 if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) {
442 printf( "%sWrite", comma ? ", " : "" );
443 comma = 1;
444 }
445 /* These two have slightly different interpretations
446 on 95/98/ME but I'm disregarding that for now */
447 if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) {
448 printf( "%sRedirected", comma ? ", " : "" );
449 comma = 1;
450 }
451 if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) {
452 printf( "%sNet-Attached", comma ? ", " : "" );
453 }
454 printf( "]\n" );
455 } else {
456 printf( "[Unset]\n" );
457 }
458 printf("\tReserved:\t[%d]\n", r->reserved);
459 printf("\n");
460}
461
462/****************************************************************************
463****************************************************************************/
464
465static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
466 TALLOC_CTX *mem_ctx, int argc,
467 const char **argv)
468{
469 WERROR result;
470 uint32_t level = 1;
471 uint32_t count;
472 union spoolss_PortInfo *info;
473
474 if (argc > 2) {
475 printf("Usage: %s [level]\n", argv[0]);
476 return WERR_OK;
477 }
478
479 if (argc == 2) {
480 level = atoi(argv[1]);
481 }
482
483 /* Enumerate ports */
484
485 result = rpccli_spoolss_enumports(cli, mem_ctx,
486 cli->srv_name_slash,
487 level,
488 0,
489 &count,
490 &info);
491 if (W_ERROR_IS_OK(result)) {
492 int i;
493
494 for (i = 0; i < count; i++) {
495 switch (level) {
496 case 1:
497 display_port_info_1(&info[i].info1);
498 break;
499 case 2:
500 display_port_info_2(&info[i].info2);
501 break;
502 default:
503 printf("unknown info level %d\n", level);
504 break;
505 }
506 }
507 }
508
509 return result;
510}
511
512/****************************************************************************
513****************************************************************************/
514
515static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
516 TALLOC_CTX *mem_ctx,
517 int argc, const char **argv)
518{
519 struct policy_handle pol;
520 WERROR result;
521 NTSTATUS status;
522 uint32_t info_level = 2;
523 union spoolss_PrinterInfo info;
524 struct spoolss_SetPrinterInfoCtr info_ctr;
525 struct spoolss_SetPrinterInfo2 info2;
526 const char *printername, *comment = NULL;
527 struct spoolss_DevmodeContainer devmode_ctr;
528 struct sec_desc_buf secdesc_ctr;
529 struct dcerpc_binding_handle *b = cli->binding_handle;
530
531 if (argc == 1 || argc > 3) {
532 printf("Usage: %s printername comment\n", argv[0]);
533
534 return WERR_OK;
535 }
536
537 /* Open a printer handle */
538 if (argc == 3) {
539 comment = argv[2];
540 }
541
542 ZERO_STRUCT(devmode_ctr);
543 ZERO_STRUCT(secdesc_ctr);
544
545 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
546
547 /* get a printer handle */
548 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
549 printername,
550 PRINTER_ALL_ACCESS,
551 &pol);
552 if (!W_ERROR_IS_OK(result))
553 goto done;
554
555 /* Get printer info */
556 result = rpccli_spoolss_getprinter(cli, mem_ctx,
557 &pol,
558 info_level,
559 0,
560 &info);
561 if (!W_ERROR_IS_OK(result))
562 goto done;
563
564
565 /* Modify the comment. */
566 spoolss_printerinfo2_to_setprinterinfo2(&info.info2, &info2);
567 info2.comment = comment;
568
569 info_ctr.level = 2;
570 info_ctr.info.info2 = &info2;
571
572 status = dcerpc_spoolss_SetPrinter(b, mem_ctx,
573 &pol,
574 &info_ctr,
575 &devmode_ctr,
576 &secdesc_ctr,
577 0, /* command */
578 &result);
579 if (!NT_STATUS_IS_OK(status)) {
580 result = ntstatus_to_werror(status);
581 goto done;
582 }
583 if (W_ERROR_IS_OK(result))
584 printf("Success in setting comment.\n");
585
586 done:
587 if (is_valid_policy_hnd(&pol)) {
588 WERROR _result;
589 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
590 }
591
592 return result;
593}
594
595/****************************************************************************
596****************************************************************************/
597
598static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
599 TALLOC_CTX *mem_ctx,
600 int argc, const char **argv)
601{
602 struct policy_handle pol;
603 WERROR result;
604 NTSTATUS status;
605 uint32_t info_level = 2;
606 union spoolss_PrinterInfo info;
607 const char *printername,
608 *new_printername = NULL;
609 struct spoolss_SetPrinterInfoCtr info_ctr;
610 struct spoolss_SetPrinterInfo2 info2;
611 struct spoolss_DevmodeContainer devmode_ctr;
612 struct sec_desc_buf secdesc_ctr;
613 struct dcerpc_binding_handle *b = cli->binding_handle;
614
615 ZERO_STRUCT(devmode_ctr);
616 ZERO_STRUCT(secdesc_ctr);
617
618 if (argc == 1 || argc > 3) {
619 printf("Usage: %s printername new_printername\n", argv[0]);
620
621 return WERR_OK;
622 }
623
624 /* Open a printer handle */
625 if (argc == 3) {
626 new_printername = argv[2];
627 }
628
629 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
630
631 /* get a printer handle */
632 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
633 printername,
634 PRINTER_ALL_ACCESS,
635 &pol);
636 if (!W_ERROR_IS_OK(result))
637 goto done;
638
639 /* Get printer info */
640 result = rpccli_spoolss_getprinter(cli, mem_ctx,
641 &pol,
642 info_level,
643 0,
644 &info);
645 if (!W_ERROR_IS_OK(result))
646 goto done;
647
648 /* Modify the printername. */
649 spoolss_printerinfo2_to_setprinterinfo2(&info.info2, &info2);
650 info2.printername = new_printername;
651
652 info_ctr.level = 2;
653 info_ctr.info.info2 = &info2;
654
655 status = dcerpc_spoolss_SetPrinter(b, mem_ctx,
656 &pol,
657 &info_ctr,
658 &devmode_ctr,
659 &secdesc_ctr,
660 0, /* command */
661 &result);
662 if (!NT_STATUS_IS_OK(status)) {
663 result = ntstatus_to_werror(status);
664 goto done;
665 }
666 if (W_ERROR_IS_OK(result))
667 printf("Success in setting printername.\n");
668
669 done:
670 if (is_valid_policy_hnd(&pol)) {
671 WERROR _result;
672 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
673 }
674
675 return result;
676}
677
678/****************************************************************************
679****************************************************************************/
680
681static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
682 TALLOC_CTX *mem_ctx,
683 int argc, const char **argv)
684{
685 struct policy_handle pol;
686 WERROR result;
687 uint32_t level = 1;
688 const char *printername;
689 union spoolss_PrinterInfo info;
690 struct dcerpc_binding_handle *b = cli->binding_handle;
691
692 if (argc == 1 || argc > 3) {
693 printf("Usage: %s <printername> [level]\n", argv[0]);
694 return WERR_OK;
695 }
696
697 /* Open a printer handle */
698 if (argc == 3) {
699 level = atoi(argv[2]);
700 }
701
702 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
703
704 /* get a printer handle */
705
706 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
707 printername,
708 SEC_FLAG_MAXIMUM_ALLOWED,
709 &pol);
710 if (!W_ERROR_IS_OK(result)) {
711 goto done;
712 }
713
714 /* Get printer info */
715
716 result = rpccli_spoolss_getprinter(cli, mem_ctx,
717 &pol,
718 level,
719 0,
720 &info);
721 if (!W_ERROR_IS_OK(result)) {
722 goto done;
723 }
724
725 /* Display printer info */
726 switch (level) {
727 case 0:
728 display_print_info0(&info.info0);
729 break;
730 case 1:
731 display_print_info1(&info.info1);
732 break;
733 case 2:
734 display_print_info2(&info.info2);
735 break;
736 case 3:
737 display_print_info3(&info.info3);
738 break;
739 case 4:
740 display_print_info4(&info.info4);
741 break;
742 case 5:
743 display_print_info5(&info.info5);
744 break;
745 case 6:
746 display_print_info6(&info.info6);
747 break;
748 case 7:
749 display_print_info7(&info.info7);
750 break;
751 default:
752 printf("unknown info level %d\n", level);
753 break;
754 }
755 done:
756 if (is_valid_policy_hnd(&pol)) {
757 WERROR _result;
758 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
759 }
760
761 return result;
762}
763
764/****************************************************************************
765****************************************************************************/
766
767static void display_reg_value(const char *name, enum winreg_Type type, DATA_BLOB blob)
768{
769 const char *text = NULL;
770
771 switch(type) {
772 case REG_DWORD:
773 if (blob.length == sizeof(uint32_t)) {
774 printf("%s: REG_DWORD: 0x%08x\n", name, IVAL(blob.data,0));
775 } else {
776 printf("%s: REG_DWORD: <invalid>\n", name);
777 }
778 break;
779 case REG_SZ:
780 pull_reg_sz(talloc_tos(), &blob, &text);
781 printf("%s: REG_SZ: %s\n", name, text ? text : "");
782 break;
783 case REG_BINARY: {
784 char *hex = hex_encode_talloc(NULL, blob.data, blob.length);
785 size_t i, len;
786 printf("%s: REG_BINARY:", name);
787 len = strlen(hex);
788 for (i=0; i<len; i++) {
789 if (hex[i] == '\0') {
790 break;
791 }
792 if (i%40 == 0) {
793 putchar('\n');
794 }
795 putchar(hex[i]);
796 }
797 TALLOC_FREE(hex);
798 putchar('\n');
799 break;
800 }
801 case REG_MULTI_SZ: {
802 uint32_t i;
803 const char **values;
804
805 if (!pull_reg_multi_sz(NULL, &blob, &values)) {
806 d_printf("pull_reg_multi_sz failed\n");
807 break;
808 }
809
810 printf("%s: REG_MULTI_SZ: \n", name);
811 for (i=0; values[i] != NULL; i++) {
812 d_printf("%s\n", values[i]);
813 }
814 TALLOC_FREE(values);
815 break;
816 }
817 default:
818 printf("%s: unknown type %d\n", name, type);
819 }
820
821}
822
823/****************************************************************************
824****************************************************************************/
825
826static void display_printer_data(const char *v,
827 enum winreg_Type type,
828 uint8_t *data,
829 uint32_t length)
830{
831 int i;
832 union spoolss_PrinterData r;
833 DATA_BLOB blob = data_blob_const(data, length);
834 WERROR result;
835 enum ndr_err_code ndr_err;
836
837 result = pull_spoolss_PrinterData(talloc_tos(), &blob, &r, type);
838 if (!W_ERROR_IS_OK(result)) {
839 return;
840 }
841
842 switch (type) {
843 case REG_DWORD:
844 printf("%s: REG_DWORD: 0x%08x\n", v, r.value);
845 break;
846 case REG_SZ:
847 printf("%s: REG_SZ: %s\n", v, r.string);
848 break;
849 case REG_BINARY: {
850 char *hex = hex_encode_talloc(NULL,
851 r.binary.data, r.binary.length);
852 size_t len;
853 printf("%s: REG_BINARY:", v);
854 len = strlen(hex);
855 for (i=0; i<len; i++) {
856 if (hex[i] == '\0') {
857 break;
858 }
859 if (i%40 == 0) {
860 putchar('\n');
861 }
862 putchar(hex[i]);
863 }
864 TALLOC_FREE(hex);
865 putchar('\n');
866 putchar('\n');
867
868 if (strequal(v, "OsVersion")) {
869 struct spoolss_OSVersion os;
870 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &os,
871 (ndr_pull_flags_fn_t)ndr_pull_spoolss_OSVersion);
872 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
873 // add output here;
874 printf("OsMajor: %u\n", os.major);
875 printf("OsMinor: %u\n", os.minor);
876 printf("OsBuild: %u\n", os.build);
877 NDR_PRINT_DEBUG(spoolss_OSVersion, &os);
878 }
879 }
880 if (strequal(v, "OsVersionEx")) {
881 struct spoolss_OSVersionEx os;
882 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &os,
883 (ndr_pull_flags_fn_t)ndr_pull_spoolss_OSVersionEx);
884 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
885 printf("OsMajor: %u\n", os.major);
886 printf("OsMinor: %u\n", os.minor);
887 printf("OsBuild: %u\n", os.build);
888 printf("ServicePackMajor: %u\n", os.service_pack_major);
889 printf("ServicePackMinor: %u\n", os.service_pack_minor);
890 NDR_PRINT_DEBUG(spoolss_OSVersionEx, &os);
891 }
892 }
893 break;
894 }
895 case REG_MULTI_SZ:
896 printf("%s: REG_MULTI_SZ: ", v);
897 for (i=0; r.string_array[i] != NULL; i++) {
898 printf("%s ", r.string_array[i]);
899 }
900 printf("\n");
901 break;
902 default:
903 printf("%s: unknown type 0x%02x:\n", v, type);
904 break;
905 }
906}
907
908/****************************************************************************
909****************************************************************************/
910
911static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
912 TALLOC_CTX *mem_ctx,
913 int argc, const char **argv)
914{
915 struct policy_handle pol;
916 WERROR result;
917 fstring printername;
918 const char *valuename;
919 enum winreg_Type type;
920 uint8_t *data;
921 uint32_t needed;
922 struct dcerpc_binding_handle *b = cli->binding_handle;
923
924 if (argc != 3) {
925 printf("Usage: %s <printername> <valuename>\n", argv[0]);
926 printf("<printername> of . queries print server\n");
927 return WERR_OK;
928 }
929 valuename = argv[2];
930
931 /* Open a printer handle */
932
933 if (strncmp(argv[1], ".", sizeof(".")) == 0)
934 fstrcpy(printername, cli->srv_name_slash);
935 else
936 slprintf(printername, sizeof(printername)-1, "%s\\%s",
937 cli->srv_name_slash, argv[1]);
938
939 /* get a printer handle */
940
941 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
942 printername,
943 SEC_FLAG_MAXIMUM_ALLOWED,
944 &pol);
945 if (!W_ERROR_IS_OK(result))
946 goto done;
947
948 /* Get printer info */
949
950 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
951 &pol,
952 valuename,
953 0,
954 &type,
955 &needed,
956 &data);
957 if (!W_ERROR_IS_OK(result))
958 goto done;
959
960 /* Display printer data */
961
962 display_printer_data(valuename, type, data, needed);
963
964 done:
965 if (is_valid_policy_hnd(&pol)) {
966 WERROR _result;
967 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
968 }
969
970 return result;
971}
972
973/****************************************************************************
974****************************************************************************/
975
976static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
977 TALLOC_CTX *mem_ctx,
978 int argc, const char **argv)
979{
980 struct policy_handle pol;
981 WERROR result;
982 NTSTATUS status;
983 fstring printername;
984 const char *valuename, *keyname;
985
986 enum winreg_Type type;
987 uint8_t *data = NULL;
988 uint32_t offered = 0;
989 uint32_t needed;
990 struct dcerpc_binding_handle *b = cli->binding_handle;
991
992 if (argc != 4) {
993 printf("Usage: %s <printername> <keyname> <valuename>\n",
994 argv[0]);
995 printf("<printername> of . queries print server\n");
996 return WERR_OK;
997 }
998 valuename = argv[3];
999 keyname = argv[2];
1000
1001 /* Open a printer handle */
1002
1003 if (strncmp(argv[1], ".", sizeof(".")) == 0)
1004 fstrcpy(printername, cli->srv_name_slash);
1005 else
1006 slprintf(printername, sizeof(printername)-1, "%s\\%s",
1007 cli->srv_name_slash, argv[1]);
1008
1009 /* get a printer handle */
1010
1011 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1012 printername,
1013 SEC_FLAG_MAXIMUM_ALLOWED,
1014 &pol);
1015 if (!W_ERROR_IS_OK(result))
1016 goto done;
1017
1018 /* Get printer info */
1019
1020 data = talloc_zero_array(mem_ctx, uint8_t, offered);
1021 if (!data) {
1022 goto done;
1023 }
1024
1025 status = dcerpc_spoolss_GetPrinterDataEx(b, mem_ctx,
1026 &pol,
1027 keyname,
1028 valuename,
1029 &type,
1030 data,
1031 offered,
1032 &needed,
1033 &result);
1034 if (!NT_STATUS_IS_OK(status)) {
1035 result = ntstatus_to_werror(status);
1036 goto done;
1037 }
1038 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
1039 offered = needed;
1040 data = talloc_zero_array(mem_ctx, uint8_t, offered);
1041 if (!data) {
1042 goto done;
1043 }
1044 status = dcerpc_spoolss_GetPrinterDataEx(b, mem_ctx,
1045 &pol,
1046 keyname,
1047 valuename,
1048 &type,
1049 data,
1050 offered,
1051 &needed,
1052 &result);
1053 }
1054
1055 if (!NT_STATUS_IS_OK(status)) {
1056 result = ntstatus_to_werror(status);
1057 goto done;
1058 }
1059
1060 if (!W_ERROR_IS_OK(result))
1061 goto done;
1062
1063 /* Display printer data */
1064
1065 display_printer_data(valuename, type, data, needed);
1066
1067
1068 done:
1069 if (is_valid_policy_hnd(&pol)) {
1070 WERROR _result;
1071 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
1072 }
1073
1074 return result;
1075}
1076
1077/****************************************************************************
1078****************************************************************************/
1079
1080static void display_print_driver1(struct spoolss_DriverInfo1 *r)
1081{
1082 if (!r) {
1083 return;
1084 }
1085
1086 printf("Printer Driver Info 1:\n");
1087 printf("\tDriver Name: [%s]\n", r->driver_name);
1088 printf("\n");
1089}
1090
1091/****************************************************************************
1092****************************************************************************/
1093
1094static void display_print_driver2(struct spoolss_DriverInfo2 *r)
1095{
1096 if (!r) {
1097 return;
1098 }
1099
1100 printf("Printer Driver Info 2:\n");
1101 printf("\tVersion: [%x]\n", r->version);
1102 printf("\tDriver Name: [%s]\n", r->driver_name);
1103 printf("\tArchitecture: [%s]\n", r->architecture);
1104 printf("\tDriver Path: [%s]\n", r->driver_path);
1105 printf("\tDatafile: [%s]\n", r->data_file);
1106 printf("\tConfigfile: [%s]\n", r->config_file);
1107 printf("\n");
1108}
1109
1110/****************************************************************************
1111****************************************************************************/
1112
1113static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1114{
1115 int i;
1116
1117 if (!r) {
1118 return;
1119 }
1120
1121 printf("Printer Driver Info 3:\n");
1122 printf("\tVersion: [%x]\n", r->version);
1123 printf("\tDriver Name: [%s]\n", r->driver_name);
1124 printf("\tArchitecture: [%s]\n", r->architecture);
1125 printf("\tDriver Path: [%s]\n", r->driver_path);
1126 printf("\tDatafile: [%s]\n", r->data_file);
1127 printf("\tConfigfile: [%s]\n", r->config_file);
1128 printf("\tHelpfile: [%s]\n", r->help_file);
1129
1130 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1131 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1132 }
1133
1134 printf("\tMonitorname: [%s]\n", r->monitor_name);
1135 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1136 printf("\n");
1137}
1138
1139/****************************************************************************
1140****************************************************************************/
1141
1142static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1143{
1144 int i;
1145
1146 if (!r) {
1147 return;
1148 }
1149
1150 printf("Printer Driver Info 4:\n");
1151 printf("\tVersion: [%x]\n", r->version);
1152 printf("\tDriver Name: [%s]\n", r->driver_name);
1153 printf("\tArchitecture: [%s]\n", r->architecture);
1154 printf("\tDriver Path: [%s]\n", r->driver_path);
1155 printf("\tDatafile: [%s]\n", r->data_file);
1156 printf("\tConfigfile: [%s]\n", r->config_file);
1157 printf("\tHelpfile: [%s]\n", r->help_file);
1158
1159 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1160 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1161 }
1162
1163 printf("\tMonitorname: [%s]\n", r->monitor_name);
1164 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1165
1166 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1167 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1168 }
1169 printf("\n");
1170}
1171
1172/****************************************************************************
1173****************************************************************************/
1174
1175static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1176{
1177 if (!r) {
1178 return;
1179 }
1180
1181 printf("Printer Driver Info 5:\n");
1182 printf("\tVersion: [%x]\n", r->version);
1183 printf("\tDriver Name: [%s]\n", r->driver_name);
1184 printf("\tArchitecture: [%s]\n", r->architecture);
1185 printf("\tDriver Path: [%s]\n", r->driver_path);
1186 printf("\tDatafile: [%s]\n", r->data_file);
1187 printf("\tConfigfile: [%s]\n", r->config_file);
1188 printf("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1189 printf("\tConfig Version: [0x%x]\n", r->config_version);
1190 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1191 printf("\n");
1192}
1193
1194/****************************************************************************
1195****************************************************************************/
1196
1197static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1198{
1199 int i;
1200
1201 if (!r) {
1202 return;
1203 }
1204
1205 printf("Printer Driver Info 6:\n");
1206 printf("\tVersion: [%x]\n", r->version);
1207 printf("\tDriver Name: [%s]\n", r->driver_name);
1208 printf("\tArchitecture: [%s]\n", r->architecture);
1209 printf("\tDriver Path: [%s]\n", r->driver_path);
1210 printf("\tDatafile: [%s]\n", r->data_file);
1211 printf("\tConfigfile: [%s]\n", r->config_file);
1212 printf("\tHelpfile: [%s]\n", r->help_file);
1213
1214 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1215 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1216 }
1217
1218 printf("\tMonitorname: [%s]\n", r->monitor_name);
1219 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1220
1221 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1222 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1223 }
1224
1225 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1226 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1227 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1228 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1229 printf("\tHardware ID: [%s]\n", r->hardware_id);
1230 printf("\tProvider: [%s]\n", r->provider);
1231
1232 printf("\n");
1233}
1234
1235/****************************************************************************
1236****************************************************************************/
1237
1238static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1239{
1240 int i;
1241
1242 if (!r) {
1243 return;
1244 }
1245
1246 printf("Printer Driver Info 8:\n");
1247 printf("\tVersion: [%x]\n", r->version);
1248 printf("\tDriver Name: [%s]\n", r->driver_name);
1249 printf("\tArchitecture: [%s]\n", r->architecture);
1250 printf("\tDriver Path: [%s]\n", r->driver_path);
1251 printf("\tDatafile: [%s]\n", r->data_file);
1252 printf("\tConfigfile: [%s]\n", r->config_file);
1253 printf("\tHelpfile: [%s]\n", r->help_file);
1254 printf("\tMonitorname: [%s]\n", r->monitor_name);
1255 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1256
1257 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1258 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1259 }
1260
1261 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1262 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1263 }
1264
1265 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1266 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r->driver_version);
1267 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1268 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1269 printf("\tHardware ID: [%s]\n", r->hardware_id);
1270 printf("\tProvider: [%s]\n", r->provider);
1271 printf("\tPrint Processor: [%s]\n", r->print_processor);
1272 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1273 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1274 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1275 }
1276 printf("\tInf Path: [%s]\n", r->inf_path);
1277 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1278 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1279 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1280 }
1281 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1282 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1283 (long long unsigned int)r->min_inbox_driver_ver_version);
1284
1285 printf("\n");
1286}
1287
1288/****************************************************************************
1289****************************************************************************/
1290
1291static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1292 TALLOC_CTX *mem_ctx,
1293 int argc, const char **argv)
1294{
1295 struct policy_handle pol;
1296 WERROR werror;
1297 uint32_t level = 3;
1298 const char *printername;
1299 uint32_t i;
1300 bool success = false;
1301 union spoolss_DriverInfo info;
1302 uint32_t server_major_version;
1303 uint32_t server_minor_version;
1304 struct dcerpc_binding_handle *b = cli->binding_handle;
1305
1306 if ((argc == 1) || (argc > 3)) {
1307 printf("Usage: %s <printername> [level]\n", argv[0]);
1308 return WERR_OK;
1309 }
1310
1311 /* get the arguments need to open the printer handle */
1312
1313 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1314
1315 if (argc == 3) {
1316 level = atoi(argv[2]);
1317 }
1318
1319 /* Open a printer handle */
1320
1321 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1322 printername,
1323 PRINTER_ACCESS_USE,
1324 &pol);
1325 if (!W_ERROR_IS_OK(werror)) {
1326 printf("Error opening printer handle for %s!\n", printername);
1327 return werror;
1328 }
1329
1330 /* loop through and print driver info level for each architecture */
1331
1332 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1333
1334 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1335 &pol,
1336 archi_table[i].long_archi,
1337 level,
1338 0, /* offered */
1339 archi_table[i].version,
1340 2,
1341 &info,
1342 &server_major_version,
1343 &server_minor_version);
1344 if (!W_ERROR_IS_OK(werror)) {
1345 continue;
1346 }
1347
1348 /* need at least one success */
1349
1350 success = true;
1351
1352 printf("\n[%s]\n", archi_table[i].long_archi);
1353
1354 switch (level) {
1355 case 1:
1356 display_print_driver1(&info.info1);
1357 break;
1358 case 2:
1359 display_print_driver2(&info.info2);
1360 break;
1361 case 3:
1362 display_print_driver3(&info.info3);
1363 break;
1364 case 4:
1365 display_print_driver4(&info.info4);
1366 break;
1367 case 5:
1368 display_print_driver5(&info.info5);
1369 break;
1370 case 6:
1371 display_print_driver6(&info.info6);
1372 break;
1373 case 8:
1374 display_print_driver8(&info.info8);
1375 break;
1376 default:
1377 printf("unknown info level %d\n", level);
1378 break;
1379 }
1380 }
1381
1382 /* Cleanup */
1383
1384 if (is_valid_policy_hnd(&pol)) {
1385 WERROR _result;
1386 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
1387 }
1388
1389 if (success) {
1390 werror = WERR_OK;
1391 }
1392
1393 return werror;
1394}
1395
1396/****************************************************************************
1397****************************************************************************/
1398
1399static WERROR enum_driver_by_architecture(struct rpc_pipe_client *cli,
1400 TALLOC_CTX *mem_ctx,
1401 const char *architecture,
1402 uint32_t level)
1403{
1404 WERROR werror;
1405 uint32_t count = 0;
1406 union spoolss_DriverInfo *info = NULL;
1407 uint32_t j;
1408
1409 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1410 cli->srv_name_slash,
1411 architecture,
1412 level,
1413 0,
1414 &count,
1415 &info);
1416
1417 if (W_ERROR_EQUAL(werror, WERR_INVALID_ENVIRONMENT)) {
1418 printf("Server does not support environment [%s]\n",
1419 architecture);
1420 return WERR_OK;
1421 }
1422
1423 if (count == 0) {
1424 return WERR_OK;
1425 }
1426
1427 if (!W_ERROR_IS_OK(werror)) {
1428 printf("Error getting driver for environment [%s] - %s\n",
1429 architecture, win_errstr(werror));
1430 return werror;
1431 }
1432
1433 printf("\n[%s]\n", architecture);
1434
1435 switch (level) {
1436 case 1:
1437 for (j=0; j < count; j++) {
1438 display_print_driver1(&info[j].info1);
1439 }
1440 break;
1441 case 2:
1442 for (j=0; j < count; j++) {
1443 display_print_driver2(&info[j].info2);
1444 }
1445 break;
1446 case 3:
1447 for (j=0; j < count; j++) {
1448 display_print_driver3(&info[j].info3);
1449 }
1450 break;
1451 case 4:
1452 for (j=0; j < count; j++) {
1453 display_print_driver4(&info[j].info4);
1454 }
1455 break;
1456 case 5:
1457 for (j=0; j < count; j++) {
1458 display_print_driver5(&info[j].info5);
1459 }
1460 break;
1461 case 6:
1462 for (j=0; j < count; j++) {
1463 display_print_driver6(&info[j].info6);
1464 }
1465 break;
1466 case 8:
1467 for (j=0; j < count; j++) {
1468 display_print_driver8(&info[j].info8);
1469 }
1470 break;
1471 default:
1472 printf("unknown info level %d\n", level);
1473 return WERR_UNKNOWN_LEVEL;
1474 }
1475
1476 return werror;
1477}
1478
1479static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1480 TALLOC_CTX *mem_ctx,
1481 int argc, const char **argv)
1482{
1483 WERROR werror = WERR_OK;
1484 uint32_t level = 1;
1485 uint32_t i;
1486 const char *architecture = NULL;
1487
1488 if (argc > 3) {
1489 printf("Usage: enumdrivers [level] [architecture]\n");
1490 return WERR_OK;
1491 }
1492
1493 if (argc >= 2) {
1494 level = atoi(argv[1]);
1495 }
1496
1497 if (argc == 3) {
1498 architecture = argv[2];
1499 }
1500
1501 if (architecture) {
1502 return enum_driver_by_architecture(cli, mem_ctx,
1503 architecture,
1504 level);
1505 }
1506
1507 /* loop through and print driver info level for each architecture */
1508 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1509 /* check to see if we already asked for this architecture string */
1510
1511 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1512 continue;
1513 }
1514
1515 werror = enum_driver_by_architecture(cli, mem_ctx,
1516 archi_table[i].long_archi,
1517 level);
1518 if (!W_ERROR_IS_OK(werror)) {
1519 break;
1520 }
1521 }
1522
1523 return werror;
1524}
1525
1526/****************************************************************************
1527****************************************************************************/
1528
1529static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1530{
1531 printf("\tDirectory Name:[%s]\n", r->directory_name);
1532}
1533
1534/****************************************************************************
1535****************************************************************************/
1536
1537static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1538 TALLOC_CTX *mem_ctx,
1539 int argc, const char **argv)
1540{
1541 WERROR result;
1542 NTSTATUS status;
1543 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1544 DATA_BLOB buffer;
1545 uint32_t offered;
1546 union spoolss_DriverDirectoryInfo info;
1547 uint32_t needed;
1548 struct dcerpc_binding_handle *b = cli->binding_handle;
1549
1550 if (argc > 2) {
1551 printf("Usage: %s [environment]\n", argv[0]);
1552 return WERR_OK;
1553 }
1554
1555 /* Get the arguments need to open the printer handle */
1556
1557 if (argc == 2) {
1558 env = argv[1];
1559 }
1560
1561 /* Get the directory. Only use Info level 1 */
1562
1563 status = dcerpc_spoolss_GetPrinterDriverDirectory(b, mem_ctx,
1564 cli->srv_name_slash,
1565 env,
1566 1,
1567 NULL, /* buffer */
1568 0, /* offered */
1569 NULL, /* info */
1570 &needed,
1571 &result);
1572 if (!NT_STATUS_IS_OK(status)) {
1573 return ntstatus_to_werror(status);
1574 }
1575 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1576 offered = needed;
1577 buffer = data_blob_talloc_zero(mem_ctx, needed);
1578
1579 status = dcerpc_spoolss_GetPrinterDriverDirectory(b, mem_ctx,
1580 cli->srv_name_slash,
1581 env,
1582 1,
1583 &buffer,
1584 offered,
1585 &info,
1586 &needed,
1587 &result);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 return ntstatus_to_werror(status);
1590 }
1591 }
1592
1593 if (W_ERROR_IS_OK(result)) {
1594 display_printdriverdir_1(&info.info1);
1595 }
1596
1597 return result;
1598}
1599
1600/****************************************************************************
1601****************************************************************************/
1602
1603static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1604 struct spoolss_AddDriverInfo3 *info,
1605 const char *arch)
1606{
1607
1608 int i;
1609
1610 for (i=0; archi_table[i].long_archi != NULL; i++)
1611 {
1612 if (strcmp(arch, archi_table[i].short_archi) == 0)
1613 {
1614 info->version = archi_table[i].version;
1615 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1616 break;
1617 }
1618 }
1619
1620 if (archi_table[i].long_archi == NULL)
1621 {
1622 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1623 }
1624
1625 return;
1626}
1627
1628
1629/**************************************************************************
1630 wrapper for strtok to get the next parameter from a delimited list.
1631 Needed to handle the empty parameter string denoted by "NULL"
1632 *************************************************************************/
1633
1634static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1635 const char *delim, const char **dest,
1636 char **saveptr)
1637{
1638 char *ptr;
1639
1640 /* get the next token */
1641 ptr = strtok_r(str, delim, saveptr);
1642
1643 /* a string of 'NULL' is used to represent an empty
1644 parameter because two consecutive delimiters
1645 will not return an empty string. See man strtok(3)
1646 for details */
1647 if (ptr && (strcasecmp_m(ptr, "NULL") == 0)) {
1648 ptr = NULL;
1649 }
1650
1651 if (dest != NULL) {
1652 *dest = talloc_strdup(mem_ctx, ptr);
1653 }
1654
1655 return ptr;
1656}
1657
1658/********************************************************************************
1659 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1660 string in the form of
1661 <Long Driver Name>:<Driver File Name>:<Data File Name>:\
1662 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1663 <Default Data Type>:<Comma Separated list of Files>
1664 *******************************************************************************/
1665
1666static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1667 char *args)
1668{
1669 char *str, *str2;
1670 size_t count = 0;
1671 char *saveptr = NULL;
1672 struct spoolss_StringArray *deps;
1673 const char **file_array = NULL;
1674 int i;
1675
1676 /* fill in the UNISTR fields */
1677 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1678 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1679 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1680 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1681 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1682 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1683 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1684
1685 /* <Comma Separated List of Dependent Files> */
1686 /* save the beginning of the string */
1687 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1688 str = str2;
1689
1690 /* begin to strip out each filename */
1691 str = strtok_r(str, ",", &saveptr);
1692
1693 /* no dependent files, we are done */
1694 if (!str) {
1695 return true;
1696 }
1697
1698 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1699 if (!deps) {
1700 return false;
1701 }
1702
1703 while (str != NULL) {
1704 bool ok;
1705 ok = add_string_to_array(deps, str, &file_array, &count);
1706 if (!ok) {
1707 return false;
1708 }
1709 str = strtok_r(NULL, ",", &saveptr);
1710 }
1711
1712 deps->string = talloc_zero_array(deps, const char *, count + 1);
1713 if (!deps->string) {
1714 return false;
1715 }
1716
1717 for (i=0; i < count; i++) {
1718 deps->string[i] = file_array[i];
1719 }
1720
1721 r->dependent_files = deps;
1722
1723 return true;
1724}
1725
1726/****************************************************************************
1727****************************************************************************/
1728
1729static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1730 TALLOC_CTX *mem_ctx,
1731 int argc, const char **argv)
1732{
1733 WERROR result;
1734 NTSTATUS status;
1735 uint32_t level = 3;
1736 struct spoolss_AddDriverInfoCtr info_ctr;
1737 struct spoolss_AddDriverInfo3 info3;
1738 const char *arch;
1739 char *driver_args;
1740 struct dcerpc_binding_handle *b = cli->binding_handle;
1741
1742 /* parse the command arguments */
1743 if (argc != 3 && argc != 4)
1744 {
1745 printf ("Usage: %s <Environment> \\\n", argv[0]);
1746 printf ("\t<Long Driver Name>:<Driver File Name>:<Data File Name>:\\\n");
1747 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1748 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1749 printf ("\t[version]\n");
1750
1751 return WERR_OK;
1752 }
1753
1754 /* Fill in the spoolss_AddDriverInfo3 struct */
1755 ZERO_STRUCT(info3);
1756
1757 arch = cmd_spoolss_get_short_archi(argv[1]);
1758 if (!arch) {
1759 printf ("Error Unknown architecture [%s]\n", argv[1]);
1760 return WERR_INVALID_PARAM;
1761 }
1762
1763 set_drv_info_3_env(mem_ctx, &info3, arch);
1764
1765 driver_args = talloc_strdup( mem_ctx, argv[2] );
1766 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1767 {
1768 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1769 return WERR_INVALID_PARAM;
1770 }
1771
1772 /* if printer driver version specified, override the default version
1773 * used by the architecture. This allows installation of Windows
1774 * 2000 (version 3) printer drivers. */
1775 if (argc == 4)
1776 {
1777 info3.version = atoi(argv[3]);
1778 }
1779
1780
1781 info_ctr.level = level;
1782 info_ctr.info.info3 = &info3;
1783
1784 status = dcerpc_spoolss_AddPrinterDriver(b, mem_ctx,
1785 cli->srv_name_slash,
1786 &info_ctr,
1787 &result);
1788 if (!NT_STATUS_IS_OK(status)) {
1789 return ntstatus_to_werror(status);
1790 }
1791 if (W_ERROR_IS_OK(result)) {
1792 printf ("Printer Driver %s successfully installed.\n",
1793 info3.driver_name);
1794 }
1795
1796 return result;
1797}
1798
1799
1800/****************************************************************************
1801****************************************************************************/
1802
1803static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1804 TALLOC_CTX *mem_ctx,
1805 int argc, const char **argv)
1806{
1807 WERROR result;
1808 struct spoolss_SetPrinterInfoCtr info_ctr;
1809 struct spoolss_SetPrinterInfo2 info2;
1810
1811 /* parse the command arguments */
1812 if (argc != 5)
1813 {
1814 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1815 return WERR_OK;
1816 }
1817
1818 /* Fill in the DRIVER_INFO_2 struct */
1819 ZERO_STRUCT(info2);
1820
1821 info2.printername = argv[1];
1822 info2.drivername = argv[3];
1823 info2.sharename = argv[2];
1824 info2.portname = argv[4];
1825 info2.comment = "Created by rpcclient";
1826 info2.printprocessor = "winprint";
1827 info2.datatype = "RAW";
1828 info2.devmode_ptr = NULL;
1829 info2.secdesc_ptr = NULL;
1830 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1831 info2.priority = 0;
1832 info2.defaultpriority = 0;
1833 info2.starttime = 0;
1834 info2.untiltime = 0;
1835
1836 /* These three fields must not be used by AddPrinter()
1837 as defined in the MS Platform SDK documentation..
1838 --jerry
1839 info2.status = 0;
1840 info2.cjobs = 0;
1841 info2.averageppm = 0;
1842 */
1843
1844 info_ctr.level = 2;
1845 info_ctr.info.info2 = &info2;
1846
1847 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1848 &info_ctr);
1849 if (W_ERROR_IS_OK(result))
1850 printf ("Printer %s successfully installed.\n", argv[1]);
1851
1852 return result;
1853}
1854
1855/****************************************************************************
1856****************************************************************************/
1857
1858static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1859 TALLOC_CTX *mem_ctx,
1860 int argc, const char **argv)
1861{
1862 struct policy_handle pol;
1863 WERROR result;
1864 NTSTATUS status;
1865 uint32_t level = 2;
1866 const char *printername;
1867 union spoolss_PrinterInfo info;
1868 struct spoolss_SetPrinterInfoCtr info_ctr;
1869 struct spoolss_SetPrinterInfo2 info2;
1870 struct spoolss_DevmodeContainer devmode_ctr;
1871 struct sec_desc_buf secdesc_ctr;
1872 struct dcerpc_binding_handle *b = cli->binding_handle;
1873
1874 ZERO_STRUCT(devmode_ctr);
1875 ZERO_STRUCT(secdesc_ctr);
1876
1877 /* parse the command arguments */
1878 if (argc != 3)
1879 {
1880 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1881 return WERR_OK;
1882 }
1883
1884 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1885
1886 /* Get a printer handle */
1887
1888 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1889 printername,
1890 PRINTER_ALL_ACCESS,
1891 &pol);
1892 if (!W_ERROR_IS_OK(result))
1893 goto done;
1894
1895 /* Get printer info */
1896
1897 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1898 &pol,
1899 level,
1900 0,
1901 &info);
1902 if (!W_ERROR_IS_OK(result)) {
1903 printf ("Unable to retrieve printer information!\n");
1904 goto done;
1905 }
1906
1907 /* Set the printer driver */
1908
1909 spoolss_printerinfo2_to_setprinterinfo2(&info.info2, &info2);
1910 info2.drivername = argv[2];
1911
1912 info_ctr.level = 2;
1913 info_ctr.info.info2 = &info2;
1914
1915 status = dcerpc_spoolss_SetPrinter(b, mem_ctx,
1916 &pol,
1917 &info_ctr,
1918 &devmode_ctr,
1919 &secdesc_ctr,
1920 0, /* command */
1921 &result);
1922 if (!NT_STATUS_IS_OK(status)) {
1923 result = ntstatus_to_werror(status);
1924 goto done;
1925 }
1926 if (!W_ERROR_IS_OK(result)) {
1927 printf("SetPrinter call failed!\n");
1928 goto done;
1929 }
1930
1931 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1932
1933done:
1934 /* Cleanup */
1935
1936 if (is_valid_policy_hnd(&pol)) {
1937 WERROR _result;
1938 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
1939 }
1940
1941 return result;
1942}
1943
1944
1945/****************************************************************************
1946****************************************************************************/
1947
1948static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1949 TALLOC_CTX *mem_ctx,
1950 int argc, const char **argv)
1951{
1952 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1953 NTSTATUS status;
1954 struct dcerpc_binding_handle *b = cli->binding_handle;
1955
1956 int i;
1957 int vers = -1;
1958
1959 const char *arch = NULL;
1960 uint32_t delete_flags = 0;
1961
1962 /* parse the command arguments */
1963 if (argc < 2 || argc > 5) {
1964 printf("Usage: %s <driver> [arch] [version] [flags]\n", argv[0]);
1965 return WERR_OK;
1966 }
1967
1968 if (argc >= 3)
1969 arch = argv[2];
1970 if (argc >= 4) {
1971 vers = atoi(argv[3]);
1972 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1973 }
1974 if (argc == 5)
1975 delete_flags = atoi(argv[4]);
1976
1977 /* delete the driver for all architectures */
1978 for (i=0; archi_table[i].long_archi; i++) {
1979
1980 if (arch && !strequal(archi_table[i].long_archi, arch))
1981 continue;
1982
1983 if (vers >= 0 && archi_table[i].version != vers)
1984 continue;
1985
1986 /* make the call to remove the driver */
1987 status = dcerpc_spoolss_DeletePrinterDriverEx(b, mem_ctx,
1988 cli->srv_name_slash,
1989 archi_table[i].long_archi,
1990 argv[1],
1991 delete_flags,
1992 archi_table[i].version,
1993 &result);
1994 if (!NT_STATUS_IS_OK(status)) {
1995 return ntstatus_to_werror(status);
1996 }
1997 if ( !W_ERROR_IS_OK(result) )
1998 {
1999 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
2000 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
2001 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
2002 }
2003 }
2004 else
2005 {
2006 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
2007 archi_table[i].long_archi, archi_table[i].version);
2008 ret = WERR_OK;
2009 }
2010 }
2011
2012 return ret;
2013}
2014
2015
2016/****************************************************************************
2017****************************************************************************/
2018
2019static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
2020 TALLOC_CTX *mem_ctx,
2021 int argc, const char **argv)
2022{
2023 WERROR result = WERR_OK;
2024 NTSTATUS status;
2025 int i;
2026 struct dcerpc_binding_handle *b = cli->binding_handle;
2027
2028 /* parse the command arguments */
2029 if (argc != 2) {
2030 printf ("Usage: %s <driver>\n", argv[0]);
2031 return WERR_OK;
2032 }
2033
2034 /* delete the driver for all architectures */
2035 for (i=0; archi_table[i].long_archi; i++) {
2036 result = WERR_OK;
2037
2038 /* make the call to remove the driver */
2039 status = dcerpc_spoolss_DeletePrinterDriver(b, mem_ctx,
2040 cli->srv_name_slash,
2041 archi_table[i].long_archi,
2042 argv[1],
2043 &result);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 result = ntstatus_to_werror(status);
2046 continue;
2047 }
2048 if ( !W_ERROR_IS_OK(result) ) {
2049 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
2050 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
2051 argv[1], archi_table[i].long_archi,
2052 win_errstr(result));
2053 }
2054 } else {
2055 printf ("Driver %s removed for arch [%s].\n", argv[1],
2056 archi_table[i].long_archi);
2057 }
2058 }
2059
2060 return result;
2061}
2062
2063/****************************************************************************
2064****************************************************************************/
2065
2066static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
2067 TALLOC_CTX *mem_ctx,
2068 int argc, const char **argv)
2069{
2070 WERROR result;
2071 NTSTATUS status;
2072 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
2073 DATA_BLOB buffer;
2074 uint32_t offered;
2075 union spoolss_PrintProcessorDirectoryInfo info;
2076 uint32_t needed;
2077 struct dcerpc_binding_handle *b = cli->binding_handle;
2078
2079 /* parse the command arguments */
2080 if (argc > 2) {
2081 printf ("Usage: %s [environment]\n", argv[0]);
2082 return WERR_OK;
2083 }
2084
2085 if (argc == 2) {
2086 environment = argv[1];
2087 }
2088
2089 status = dcerpc_spoolss_GetPrintProcessorDirectory(b, mem_ctx,
2090 cli->srv_name_slash,
2091 environment,
2092 1,
2093 NULL, /* buffer */
2094 0, /* offered */
2095 NULL, /* info */
2096 &needed,
2097 &result);
2098 if (!NT_STATUS_IS_OK(status)) {
2099 return ntstatus_to_werror(status);
2100 }
2101 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
2102 offered = needed;
2103 buffer = data_blob_talloc_zero(mem_ctx, needed);
2104
2105 status = dcerpc_spoolss_GetPrintProcessorDirectory(b, mem_ctx,
2106 cli->srv_name_slash,
2107 environment,
2108 1,
2109 &buffer,
2110 offered,
2111 &info,
2112 &needed,
2113 &result);
2114 if (!NT_STATUS_IS_OK(status)) {
2115 return ntstatus_to_werror(status);
2116 }
2117 }
2118
2119 if (W_ERROR_IS_OK(result)) {
2120 printf("%s\n", info.info1.directory_name);
2121 }
2122
2123 return result;
2124}
2125
2126/****************************************************************************
2127****************************************************************************/
2128
2129static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2130 int argc, const char **argv)
2131{
2132 struct policy_handle handle;
2133 WERROR werror;
2134 NTSTATUS status;
2135 const char *printername;
2136 struct spoolss_AddFormInfoCtr info_ctr;
2137 struct spoolss_AddFormInfo1 info1;
2138 struct spoolss_AddFormInfo2 info2;
2139 uint32_t level = 1;
2140 struct dcerpc_binding_handle *b = cli->binding_handle;
2141
2142 /* Parse the command arguments */
2143
2144 if (argc < 3 || argc > 5) {
2145 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2146 return WERR_OK;
2147 }
2148
2149 /* Get a printer handle */
2150
2151 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2152
2153 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2154 printername,
2155 PRINTER_ALL_ACCESS,
2156 &handle);
2157 if (!W_ERROR_IS_OK(werror))
2158 goto done;
2159
2160 /* Dummy up some values for the form data */
2161
2162 if (argc == 4) {
2163 level = atoi(argv[3]);
2164 }
2165
2166 switch (level) {
2167 case 1:
2168 info1.flags = SPOOLSS_FORM_USER;
2169 info1.form_name = argv[2];
2170 info1.size.width = 100;
2171 info1.size.height = 100;
2172 info1.area.left = 0;
2173 info1.area.top = 10;
2174 info1.area.right = 20;
2175 info1.area.bottom = 30;
2176
2177 info_ctr.level = 1;
2178 info_ctr.info.info1 = &info1;
2179
2180 break;
2181 case 2:
2182 info2.flags = SPOOLSS_FORM_USER;
2183 info2.form_name = argv[2];
2184 info2.size.width = 100;
2185 info2.size.height = 100;
2186 info2.area.left = 0;
2187 info2.area.top = 10;
2188 info2.area.right = 20;
2189 info2.area.bottom = 30;
2190 info2.keyword = argv[2];
2191 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2192 info2.mui_dll = NULL;
2193 info2.ressource_id = 0;
2194 info2.display_name = argv[2];
2195 info2.lang_id = 0;
2196
2197 info_ctr.level = 2;
2198 info_ctr.info.info2 = &info2;
2199
2200 break;
2201 default:
2202 werror = WERR_INVALID_PARAM;
2203 goto done;
2204 }
2205
2206 /* Add the form */
2207
2208 status = dcerpc_spoolss_AddForm(b, mem_ctx,
2209 &handle,
2210 &info_ctr,
2211 &werror);
2212 if (!NT_STATUS_IS_OK(status)) {
2213 werror = ntstatus_to_werror(status);
2214 goto done;
2215 }
2216 done:
2217 if (is_valid_policy_hnd(&handle)) {
2218 WERROR _result;
2219 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
2220 }
2221
2222 return werror;
2223}
2224
2225/****************************************************************************
2226****************************************************************************/
2227
2228static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2229 int argc, const char **argv)
2230{
2231 struct policy_handle handle;
2232 WERROR werror;
2233 NTSTATUS status;
2234 const char *printername;
2235 struct spoolss_AddFormInfoCtr info_ctr;
2236 struct spoolss_AddFormInfo1 info1;
2237 struct dcerpc_binding_handle *b = cli->binding_handle;
2238
2239 /* Parse the command arguments */
2240
2241 if (argc != 3) {
2242 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2243 return WERR_OK;
2244 }
2245
2246 /* Get a printer handle */
2247
2248 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2249
2250 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2251 printername,
2252 SEC_FLAG_MAXIMUM_ALLOWED,
2253 &handle);
2254 if (!W_ERROR_IS_OK(werror))
2255 goto done;
2256
2257 /* Dummy up some values for the form data */
2258
2259 info1.flags = SPOOLSS_FORM_PRINTER;
2260 info1.size.width = 100;
2261 info1.size.height = 100;
2262 info1.area.left = 0;
2263 info1.area.top = 1000;
2264 info1.area.right = 2000;
2265 info1.area.bottom = 3000;
2266 info1.form_name = argv[2];
2267
2268 info_ctr.info.info1 = &info1;
2269 info_ctr.level = 1;
2270
2271 /* Set the form */
2272
2273 status = dcerpc_spoolss_SetForm(b, mem_ctx,
2274 &handle,
2275 argv[2],
2276 &info_ctr,
2277 &werror);
2278 if (!NT_STATUS_IS_OK(status)) {
2279 werror = ntstatus_to_werror(status);
2280 goto done;
2281 }
2282 done:
2283 if (is_valid_policy_hnd(&handle)) {
2284 WERROR _result;
2285 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
2286 }
2287
2288 return werror;
2289}
2290
2291/****************************************************************************
2292****************************************************************************/
2293
2294static const char *get_form_flag(int form_flag)
2295{
2296 switch (form_flag) {
2297 case SPOOLSS_FORM_USER:
2298 return "FORM_USER";
2299 case SPOOLSS_FORM_BUILTIN:
2300 return "FORM_BUILTIN";
2301 case SPOOLSS_FORM_PRINTER:
2302 return "FORM_PRINTER";
2303 default:
2304 return "unknown";
2305 }
2306}
2307
2308/****************************************************************************
2309****************************************************************************/
2310
2311static void display_form_info1(struct spoolss_FormInfo1 *r)
2312{
2313 printf("%s\n" \
2314 "\tflag: %s (%d)\n" \
2315 "\twidth: %d, length: %d\n" \
2316 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2317 r->form_name, get_form_flag(r->flags), r->flags,
2318 r->size.width, r->size.height,
2319 r->area.left, r->area.right,
2320 r->area.top, r->area.bottom);
2321}
2322
2323/****************************************************************************
2324****************************************************************************/
2325
2326static void display_form_info2(struct spoolss_FormInfo2 *r)
2327{
2328 printf("%s\n" \
2329 "\tflag: %s (%d)\n" \
2330 "\twidth: %d, length: %d\n" \
2331 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2332 r->form_name, get_form_flag(r->flags), r->flags,
2333 r->size.width, r->size.height,
2334 r->area.left, r->area.right,
2335 r->area.top, r->area.bottom);
2336 printf("\tkeyword: %s\n", r->keyword);
2337 printf("\tstring_type: 0x%08x\n", r->string_type);
2338 printf("\tmui_dll: %s\n", r->mui_dll);
2339 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2340 printf("\tdisplay_name: %s\n", r->display_name);
2341 printf("\tlang_id: %d\n", r->lang_id);
2342 printf("\n");
2343}
2344
2345/****************************************************************************
2346****************************************************************************/
2347
2348static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2349 int argc, const char **argv)
2350{
2351 struct policy_handle handle;
2352 WERROR werror;
2353 NTSTATUS status;
2354 const char *printername;
2355 DATA_BLOB buffer;
2356 uint32_t offered = 0;
2357 union spoolss_FormInfo info;
2358 uint32_t needed;
2359 uint32_t level = 1;
2360 struct dcerpc_binding_handle *b = cli->binding_handle;
2361
2362 /* Parse the command arguments */
2363
2364 if (argc < 3 || argc > 5) {
2365 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2366 return WERR_OK;
2367 }
2368
2369 /* Get a printer handle */
2370
2371 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2372
2373 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2374 printername,
2375 SEC_FLAG_MAXIMUM_ALLOWED,
2376 &handle);
2377 if (!W_ERROR_IS_OK(werror))
2378 goto done;
2379
2380 if (argc == 4) {
2381 level = atoi(argv[3]);
2382 }
2383
2384 /* Get the form */
2385
2386 status = dcerpc_spoolss_GetForm(b, mem_ctx,
2387 &handle,
2388 argv[2],
2389 level,
2390 NULL,
2391 offered,
2392 &info,
2393 &needed,
2394 &werror);
2395 if (!NT_STATUS_IS_OK(status)) {
2396 werror = ntstatus_to_werror(status);
2397 goto done;
2398 }
2399 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2400 buffer = data_blob_talloc_zero(mem_ctx, needed);
2401 offered = needed;
2402 status = dcerpc_spoolss_GetForm(b, mem_ctx,
2403 &handle,
2404 argv[2],
2405 level,
2406 &buffer,
2407 offered,
2408 &info,
2409 &needed,
2410 &werror);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 werror = ntstatus_to_werror(status);
2413 goto done;
2414 }
2415 }
2416
2417 if (!W_ERROR_IS_OK(werror)) {
2418 goto done;
2419 }
2420
2421 switch (level) {
2422 case 1:
2423 display_form_info1(&info.info1);
2424 break;
2425 case 2:
2426 display_form_info2(&info.info2);
2427 break;
2428 }
2429
2430 done:
2431 if (is_valid_policy_hnd(&handle)) {
2432 WERROR _result;
2433 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
2434 }
2435
2436 return werror;
2437}
2438
2439/****************************************************************************
2440****************************************************************************/
2441
2442static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2443 TALLOC_CTX *mem_ctx, int argc,
2444 const char **argv)
2445{
2446 struct policy_handle handle;
2447 WERROR werror;
2448 NTSTATUS status;
2449 const char *printername;
2450 struct dcerpc_binding_handle *b = cli->binding_handle;
2451
2452 /* Parse the command arguments */
2453
2454 if (argc != 3) {
2455 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2456 return WERR_OK;
2457 }
2458
2459 /* Get a printer handle */
2460
2461 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2462
2463 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2464 printername,
2465 SEC_FLAG_MAXIMUM_ALLOWED,
2466 &handle);
2467 if (!W_ERROR_IS_OK(werror))
2468 goto done;
2469
2470 /* Delete the form */
2471
2472 status = dcerpc_spoolss_DeleteForm(b, mem_ctx,
2473 &handle,
2474 argv[2],
2475 &werror);
2476 if (!NT_STATUS_IS_OK(status)) {
2477 werror = ntstatus_to_werror(status);
2478 goto done;
2479 }
2480
2481 done:
2482 if (is_valid_policy_hnd(&handle)) {
2483 WERROR _result;
2484 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
2485 }
2486
2487 return werror;
2488}
2489
2490/****************************************************************************
2491****************************************************************************/
2492
2493static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2494 TALLOC_CTX *mem_ctx, int argc,
2495 const char **argv)
2496{
2497 struct policy_handle handle;
2498 WERROR werror;
2499 const char *printername;
2500 uint32_t num_forms, level = 1, i;
2501 union spoolss_FormInfo *forms;
2502 struct dcerpc_binding_handle *b = cli->binding_handle;
2503
2504 /* Parse the command arguments */
2505
2506 if (argc < 2 || argc > 4) {
2507 printf ("Usage: %s <printer> [level]\n", argv[0]);
2508 return WERR_OK;
2509 }
2510
2511 /* Get a printer handle */
2512
2513 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2514
2515 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2516 printername,
2517 SEC_FLAG_MAXIMUM_ALLOWED,
2518 &handle);
2519 if (!W_ERROR_IS_OK(werror))
2520 goto done;
2521
2522 if (argc == 3) {
2523 level = atoi(argv[2]);
2524 }
2525
2526 /* Enumerate forms */
2527
2528 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2529 &handle,
2530 level,
2531 0,
2532 &num_forms,
2533 &forms);
2534
2535 if (!W_ERROR_IS_OK(werror))
2536 goto done;
2537
2538 /* Display output */
2539
2540 for (i = 0; i < num_forms; i++) {
2541 switch (level) {
2542 case 1:
2543 display_form_info1(&forms[i].info1);
2544 break;
2545 case 2:
2546 display_form_info2(&forms[i].info2);
2547 break;
2548 }
2549 }
2550
2551 done:
2552 if (is_valid_policy_hnd(&handle)) {
2553 WERROR _result;
2554 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
2555 }
2556
2557 return werror;
2558}
2559
2560/****************************************************************************
2561****************************************************************************/
2562
2563static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2564 TALLOC_CTX *mem_ctx,
2565 int argc, const char **argv)
2566{
2567 WERROR result;
2568 NTSTATUS status;
2569 const char *printername;
2570 struct policy_handle pol = { 0, };
2571 union spoolss_PrinterInfo info;
2572 enum winreg_Type type;
2573 union spoolss_PrinterData data;
2574 DATA_BLOB blob;
2575 struct dcerpc_binding_handle *b = cli->binding_handle;
2576
2577 /* parse the command arguments */
2578 if (argc < 5) {
2579 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2580 " <value> <data>\n",
2581 argv[0]);
2582 return WERR_OK;
2583 }
2584
2585 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2586
2587 type = REG_NONE;
2588
2589 if (strequal(argv[2], "string")) {
2590 type = REG_SZ;
2591 }
2592
2593 if (strequal(argv[2], "binary")) {
2594 type = REG_BINARY;
2595 }
2596
2597 if (strequal(argv[2], "dword")) {
2598 type = REG_DWORD;
2599 }
2600
2601 if (strequal(argv[2], "multistring")) {
2602 type = REG_MULTI_SZ;
2603 }
2604
2605 if (type == REG_NONE) {
2606 printf("Unknown data type: %s\n", argv[2]);
2607 result = WERR_INVALID_PARAM;
2608 goto done;
2609 }
2610
2611 /* get a printer handle */
2612
2613 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2614 printername,
2615 SEC_FLAG_MAXIMUM_ALLOWED,
2616 &pol);
2617 if (!W_ERROR_IS_OK(result)) {
2618 goto done;
2619 }
2620
2621 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2622 &pol,
2623 0,
2624 0,
2625 &info);
2626 if (!W_ERROR_IS_OK(result)) {
2627 goto done;
2628 }
2629
2630 printf("%s\n", current_timestring(mem_ctx, true));
2631 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2632
2633 /* Set the printer data */
2634
2635 switch (type) {
2636 case REG_SZ:
2637 data.string = talloc_strdup(mem_ctx, argv[4]);
2638 W_ERROR_HAVE_NO_MEMORY(data.string);
2639 break;
2640 case REG_DWORD:
2641 data.value = strtoul(argv[4], NULL, 10);
2642 break;
2643 case REG_BINARY:
2644 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2645 break;
2646 case REG_MULTI_SZ: {
2647 int i;
2648 size_t num_strings;
2649 const char **strings = NULL;
2650
2651 num_strings = 0;
2652
2653 for (i=4; i<argc; i++) {
2654 if (strcmp(argv[i], "NULL") == 0) {
2655 argv[i] = "";
2656 }
2657 if (!add_string_to_array(mem_ctx, argv[i],
2658 &strings,
2659 &num_strings)) {
2660 result = WERR_NOMEM;
2661 goto done;
2662 }
2663 }
2664 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2665 if (!data.string_array) {
2666 result = WERR_NOMEM;
2667 goto done;
2668 }
2669 for (i=0; i < num_strings; i++) {
2670 data.string_array[i] = strings[i];
2671 }
2672 break;
2673 }
2674 default:
2675 printf("Unknown data type: %s\n", argv[2]);
2676 result = WERR_INVALID_PARAM;
2677 goto done;
2678 }
2679
2680 result = push_spoolss_PrinterData(mem_ctx, &blob, type, &data);
2681 if (!W_ERROR_IS_OK(result)) {
2682 goto done;
2683 }
2684
2685 status = dcerpc_spoolss_SetPrinterData(b, mem_ctx,
2686 &pol,
2687 argv[3], /* value_name */
2688 type,
2689 blob.data,
2690 blob.length,
2691 &result);
2692 if (!NT_STATUS_IS_OK(status)) {
2693 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2694 result = ntstatus_to_werror(status);
2695 goto done;
2696 }
2697 if (!W_ERROR_IS_OK(result)) {
2698 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2699 goto done;
2700 }
2701 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2702
2703 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2704 &pol,
2705 0,
2706 0,
2707 &info);
2708 if (!W_ERROR_IS_OK(result)) {
2709 goto done;
2710 }
2711
2712 printf("%s\n", current_timestring(mem_ctx, true));
2713 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2714
2715done:
2716 /* cleanup */
2717 if (is_valid_policy_hnd(&pol)) {
2718 WERROR _result;
2719 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &pol, &_result);
2720 }
2721
2722 return result;
2723}
2724
2725/****************************************************************************
2726****************************************************************************/
2727
2728static void display_job_info1(struct spoolss_JobInfo1 *r)
2729{
2730 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2731 r->user_name, r->document_name, r->text_status, r->pages_printed,
2732 r->total_pages);
2733}
2734
2735/****************************************************************************
2736****************************************************************************/
2737
2738static void display_job_info2(struct spoolss_JobInfo2 *r)
2739{
2740 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2741 r->position, r->job_id,
2742 r->user_name, r->document_name, r->text_status, r->pages_printed,
2743 r->total_pages, r->size);
2744}
2745
2746/****************************************************************************
2747****************************************************************************/
2748
2749static void display_job_info3(struct spoolss_JobInfo3 *r)
2750{
2751 printf("jobid[%d], next_jobid[%d]\n",
2752 r->job_id, r->next_job_id);
2753}
2754
2755/****************************************************************************
2756****************************************************************************/
2757
2758static void display_job_info4(struct spoolss_JobInfo4 *r)
2759{
2760 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2761 r->position, r->job_id,
2762 r->user_name, r->document_name, r->text_status, r->pages_printed,
2763 r->total_pages, r->size, r->size_high);
2764}
2765
2766/****************************************************************************
2767****************************************************************************/
2768
2769static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2770 TALLOC_CTX *mem_ctx, int argc,
2771 const char **argv)
2772{
2773 WERROR result;
2774 uint32_t level = 1, count, i;
2775 const char *printername;
2776 struct policy_handle hnd;
2777 union spoolss_JobInfo *info;
2778 struct dcerpc_binding_handle *b = cli->binding_handle;
2779
2780 if (argc < 2 || argc > 3) {
2781 printf("Usage: %s printername [level]\n", argv[0]);
2782 return WERR_OK;
2783 }
2784
2785 if (argc == 3) {
2786 level = atoi(argv[2]);
2787 }
2788
2789 /* Open printer handle */
2790
2791 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2792
2793 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2794 printername,
2795 SEC_FLAG_MAXIMUM_ALLOWED,
2796 &hnd);
2797 if (!W_ERROR_IS_OK(result))
2798 goto done;
2799
2800 /* Enumerate ports */
2801
2802 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2803 &hnd,
2804 0, /* firstjob */
2805 1000, /* numjobs */
2806 level,
2807 0,
2808 &count,
2809 &info);
2810 if (!W_ERROR_IS_OK(result)) {
2811 goto done;
2812 }
2813
2814 for (i = 0; i < count; i++) {
2815 switch (level) {
2816 case 1:
2817 display_job_info1(&info[i].info1);
2818 break;
2819 case 2:
2820 display_job_info2(&info[i].info2);
2821 break;
2822 default:
2823 d_printf("unknown info level %d\n", level);
2824 break;
2825 }
2826 }
2827
2828done:
2829 if (is_valid_policy_hnd(&hnd)) {
2830 WERROR _result;
2831 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
2832 }
2833
2834 return result;
2835}
2836
2837/****************************************************************************
2838****************************************************************************/
2839
2840static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2841 TALLOC_CTX *mem_ctx, int argc,
2842 const char **argv)
2843{
2844 WERROR result;
2845 const char *printername;
2846 struct policy_handle hnd;
2847 uint32_t job_id;
2848 uint32_t level = 1;
2849 union spoolss_JobInfo info;
2850 struct dcerpc_binding_handle *b = cli->binding_handle;
2851
2852 if (argc < 3 || argc > 4) {
2853 printf("Usage: %s printername job_id [level]\n", argv[0]);
2854 return WERR_OK;
2855 }
2856
2857 job_id = atoi(argv[2]);
2858
2859 if (argc == 4) {
2860 level = atoi(argv[3]);
2861 }
2862
2863 /* Open printer handle */
2864
2865 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2866
2867 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2868 printername,
2869 SEC_FLAG_MAXIMUM_ALLOWED,
2870 &hnd);
2871 if (!W_ERROR_IS_OK(result)) {
2872 goto done;
2873 }
2874
2875 /* Enumerate ports */
2876
2877 result = rpccli_spoolss_getjob(cli, mem_ctx,
2878 &hnd,
2879 job_id,
2880 level,
2881 0,
2882 &info);
2883
2884 if (!W_ERROR_IS_OK(result)) {
2885 goto done;
2886 }
2887
2888 switch (level) {
2889 case 1:
2890 display_job_info1(&info.info1);
2891 break;
2892 case 2:
2893 display_job_info2(&info.info2);
2894 break;
2895 case 3:
2896 display_job_info3(&info.info3);
2897 break;
2898 case 4:
2899 display_job_info4(&info.info4);
2900 break;
2901 default:
2902 d_printf("unknown info level %d\n", level);
2903 break;
2904 }
2905
2906done:
2907 if (is_valid_policy_hnd(&hnd)) {
2908 WERROR _result;
2909 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
2910 }
2911
2912 return result;
2913}
2914
2915/****************************************************************************
2916****************************************************************************/
2917
2918static struct {
2919 const char *name;
2920 enum spoolss_JobControl val;
2921} cmdvals[] = {
2922 {"PAUSE", SPOOLSS_JOB_CONTROL_PAUSE},
2923 {"RESUME", SPOOLSS_JOB_CONTROL_RESUME},
2924 {"CANCEL", SPOOLSS_JOB_CONTROL_CANCEL},
2925 {"RESTART", SPOOLSS_JOB_CONTROL_RESTART},
2926 {"DELETE", SPOOLSS_JOB_CONTROL_DELETE},
2927 {"SEND_TO_PRINTER", SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER},
2928 {"EJECTED", SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED},
2929 {"RETAIN", SPOOLSS_JOB_CONTROL_RETAIN},
2930 {"RELEASE", SPOOLSS_JOB_CONTROL_RELEASE}
2931};
2932
2933static enum spoolss_JobControl parse_setjob_command(const char *cmd)
2934{
2935 int i;
2936
2937 for (i = 0; i < sizeof(cmdvals)/sizeof(cmdvals[0]); i++) {
2938 if (strequal(cmdvals[i].name, cmd)) {
2939 return cmdvals[i].val;
2940 }
2941 }
2942 return (enum spoolss_JobControl)atoi(cmd);
2943}
2944
2945static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2946 TALLOC_CTX *mem_ctx, int argc,
2947 const char **argv)
2948{
2949 WERROR result;
2950 NTSTATUS status;
2951 const char *printername;
2952 struct policy_handle hnd;
2953 uint32_t job_id;
2954 enum spoolss_JobControl command;
2955 struct dcerpc_binding_handle *b = cli->binding_handle;
2956
2957 if (argc != 4) {
2958 printf("Usage: %s printername job_id command\n", argv[0]);
2959 printf("command = [PAUSE|RESUME|CANCEL|RESTART|DELETE|"
2960 "SEND_TO_PRINTER|EJECTED|RETAIN|RELEASE]\n");
2961 return WERR_OK;
2962 }
2963
2964 job_id = atoi(argv[2]);
2965 command = parse_setjob_command(argv[3]);
2966
2967 /* Open printer handle */
2968
2969 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2970
2971 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2972 printername,
2973 SEC_FLAG_MAXIMUM_ALLOWED,
2974 &hnd);
2975 if (!W_ERROR_IS_OK(result)) {
2976 goto done;
2977 }
2978
2979 /* Set Job */
2980
2981 status = dcerpc_spoolss_SetJob(b, mem_ctx,
2982 &hnd,
2983 job_id,
2984 NULL,
2985 command,
2986 &result);
2987 if (!NT_STATUS_IS_OK(status)) {
2988 result = ntstatus_to_werror(status);
2989 goto done;
2990 }
2991 if (!W_ERROR_IS_OK(result)) {
2992 goto done;
2993 }
2994
2995done:
2996 if (is_valid_policy_hnd(&hnd)) {
2997 WERROR _result;
2998 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
2999 }
3000
3001 return result;
3002}
3003
3004/****************************************************************************
3005****************************************************************************/
3006
3007static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
3008 TALLOC_CTX *mem_ctx, int argc,
3009 const char **argv)
3010{
3011 WERROR result;
3012 NTSTATUS status;
3013 const char *printername;
3014 struct policy_handle hnd;
3015 uint32_t value_needed;
3016 enum winreg_Type type;
3017 uint32_t data_needed;
3018 struct dcerpc_binding_handle *b = cli->binding_handle;
3019 struct spoolss_EnumPrinterData r;
3020
3021 if (argc != 2) {
3022 printf("Usage: %s printername\n", argv[0]);
3023 return WERR_OK;
3024 }
3025
3026 /* Open printer handle */
3027
3028 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3029
3030 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3031 printername,
3032 SEC_FLAG_MAXIMUM_ALLOWED,
3033 &hnd);
3034 if (!W_ERROR_IS_OK(result)) {
3035 goto done;
3036 }
3037
3038 /* Enumerate data */
3039
3040 r.in.handle = &hnd;
3041 r.in.enum_index = 0;
3042 r.in.value_offered = 0;
3043 r.in.data_offered = 0;
3044 r.out.value_name = NULL;
3045 r.out.value_needed = &value_needed;
3046 r.out.type = &type;
3047 r.out.data = NULL;
3048 r.out.data_needed = &data_needed;
3049
3050 status = dcerpc_spoolss_EnumPrinterData_r(b, mem_ctx, &r);
3051 if (!NT_STATUS_IS_OK(status)) {
3052 result = ntstatus_to_werror(status);
3053 goto done;
3054 }
3055
3056 if (!W_ERROR_IS_OK(r.out.result)) {
3057 result = r.out.result;
3058 goto done;
3059 }
3060
3061 r.in.data_offered = *r.out.data_needed;
3062 r.in.value_offered = *r.out.value_needed;
3063 r.out.data = talloc_zero_array(mem_ctx, uint8_t, r.in.data_offered);
3064 r.out.value_name = talloc_zero_array(mem_ctx, char, r.in.value_offered);
3065
3066 do {
3067
3068 status = dcerpc_spoolss_EnumPrinterData_r(b, mem_ctx, &r);
3069 if (!NT_STATUS_IS_OK(status)) {
3070 result = ntstatus_to_werror(status);
3071 goto done;
3072 }
3073
3074 if (W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
3075 result = WERR_OK;
3076 break;
3077 }
3078
3079 r.in.enum_index++;
3080
3081 display_reg_value(r.out.value_name, *r.out.type,
3082 data_blob_const(r.out.data, r.in.data_offered));
3083
3084 } while (W_ERROR_IS_OK(r.out.result));
3085
3086done:
3087 if (is_valid_policy_hnd(&hnd)) {
3088 WERROR _result;
3089 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
3090 }
3091
3092 return result;
3093}
3094
3095/****************************************************************************
3096****************************************************************************/
3097
3098static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
3099 TALLOC_CTX *mem_ctx, int argc,
3100 const char **argv)
3101{
3102 WERROR result;
3103 uint32_t i;
3104 const char *printername;
3105 struct policy_handle hnd;
3106 uint32_t count;
3107 struct spoolss_PrinterEnumValues *info;
3108 struct dcerpc_binding_handle *b = cli->binding_handle;
3109
3110 if (argc != 3) {
3111 printf("Usage: %s printername <keyname>\n", argv[0]);
3112 return WERR_OK;
3113 }
3114
3115 /* Open printer handle */
3116
3117 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3118
3119 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3120 printername,
3121 SEC_FLAG_MAXIMUM_ALLOWED,
3122 &hnd);
3123 if (!W_ERROR_IS_OK(result)) {
3124 goto done;
3125 }
3126
3127 /* Enumerate subkeys */
3128
3129 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
3130 &hnd,
3131 argv[2],
3132 0,
3133 &count,
3134 &info);
3135 if (!W_ERROR_IS_OK(result)) {
3136 goto done;
3137 }
3138
3139 for (i=0; i < count; i++) {
3140 display_printer_data(info[i].value_name,
3141 info[i].type,
3142 info[i].data->data,
3143 info[i].data->length);
3144 }
3145
3146 done:
3147 if (is_valid_policy_hnd(&hnd)) {
3148 WERROR _result;
3149 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
3150 }
3151
3152 return result;
3153}
3154
3155/****************************************************************************
3156****************************************************************************/
3157
3158static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
3159 TALLOC_CTX *mem_ctx, int argc,
3160 const char **argv)
3161{
3162 WERROR result;
3163 const char *printername;
3164 const char *keyname = NULL;
3165 struct policy_handle hnd;
3166 const char **key_buffer = NULL;
3167 int i;
3168 uint32_t offered = 0;
3169 struct dcerpc_binding_handle *b = cli->binding_handle;
3170
3171 if (argc < 2 || argc > 4) {
3172 printf("Usage: %s printername [keyname] [offered]\n", argv[0]);
3173 return WERR_OK;
3174 }
3175
3176 if (argc >= 3) {
3177 keyname = argv[2];
3178 } else {
3179 keyname = "";
3180 }
3181
3182 if (argc == 4) {
3183 offered = atoi(argv[3]);
3184 }
3185
3186 /* Open printer handle */
3187
3188 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3189
3190 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3191 printername,
3192 SEC_FLAG_MAXIMUM_ALLOWED,
3193 &hnd);
3194 if (!W_ERROR_IS_OK(result)) {
3195 goto done;
3196 }
3197
3198 /* Enumerate subkeys */
3199
3200 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
3201 &hnd,
3202 keyname,
3203 &key_buffer,
3204 offered);
3205
3206 if (!W_ERROR_IS_OK(result)) {
3207 goto done;
3208 }
3209
3210 for (i=0; key_buffer && key_buffer[i]; i++) {
3211 printf("%s\n", key_buffer[i]);
3212 }
3213
3214 done:
3215
3216 if (is_valid_policy_hnd(&hnd)) {
3217 WERROR _result;
3218 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
3219 }
3220
3221 return result;
3222}
3223
3224/****************************************************************************
3225****************************************************************************/
3226
3227static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
3228 TALLOC_CTX *mem_ctx, int argc,
3229 const char **argv)
3230{
3231 const char *printername;
3232 const char *clientname;
3233 struct policy_handle hnd = { 0, };
3234 WERROR result;
3235 NTSTATUS status;
3236 struct spoolss_NotifyOption option;
3237 struct dcerpc_binding_handle *b = cli->binding_handle;
3238
3239 if (argc != 2) {
3240 printf("Usage: %s printername\n", argv[0]);
3241 result = WERR_OK;
3242 goto done;
3243 }
3244
3245 /* Open printer */
3246
3247 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3248
3249 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3250 printername,
3251 SEC_FLAG_MAXIMUM_ALLOWED,
3252 &hnd);
3253 if (!W_ERROR_IS_OK(result)) {
3254 printf("Error opening %s\n", argv[1]);
3255 goto done;
3256 }
3257
3258 /* Create spool options */
3259
3260 option.version = 2;
3261 option.count = 2;
3262
3263 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
3264 if (option.types == NULL) {
3265 result = WERR_NOMEM;
3266 goto done;
3267 }
3268
3269 option.types[0].type = PRINTER_NOTIFY_TYPE;
3270 option.types[0].count = 1;
3271 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3272 if (option.types[0].fields == NULL) {
3273 result = WERR_NOMEM;
3274 goto done;
3275 }
3276 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3277
3278 option.types[1].type = JOB_NOTIFY_TYPE;
3279 option.types[1].count = 1;
3280 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3281 if (option.types[1].fields == NULL) {
3282 result = WERR_NOMEM;
3283 goto done;
3284 }
3285 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3286
3287 clientname = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
3288 if (!clientname) {
3289 result = WERR_NOMEM;
3290 goto done;
3291 }
3292
3293 /* Send rffpcnex */
3294
3295 status = dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(b, mem_ctx,
3296 &hnd,
3297 0,
3298 0,
3299 clientname,
3300 123,
3301 &option,
3302 &result);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 result = ntstatus_to_werror(status);
3305 goto done;
3306 }
3307 if (!W_ERROR_IS_OK(result)) {
3308 printf("Error rffpcnex %s\n", argv[1]);
3309 goto done;
3310 }
3311
3312done:
3313 if (is_valid_policy_hnd(&hnd)) {
3314 WERROR _result;
3315 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &_result);
3316 }
3317
3318 return result;
3319}
3320
3321/****************************************************************************
3322****************************************************************************/
3323
3324static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3325 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3326{
3327 union spoolss_PrinterInfo info1, info2;
3328 WERROR werror;
3329 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3330
3331 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3332 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3333 hnd1,
3334 2,
3335 0,
3336 &info1);
3337 if ( !W_ERROR_IS_OK(werror) ) {
3338 printf("failed (%s)\n", win_errstr(werror));
3339 talloc_destroy(mem_ctx);
3340 return false;
3341 }
3342 printf("ok\n");
3343
3344 printf("Retrieving printer properties for %s...", cli2->desthost);
3345 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3346 hnd2,
3347 2,
3348 0,
3349 &info2);
3350 if ( !W_ERROR_IS_OK(werror) ) {
3351 printf("failed (%s)\n", win_errstr(werror));
3352 talloc_destroy(mem_ctx);
3353 return false;
3354 }
3355 printf("ok\n");
3356
3357 talloc_destroy(mem_ctx);
3358
3359 return true;
3360}
3361
3362/****************************************************************************
3363****************************************************************************/
3364
3365static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3366 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3367{
3368 union spoolss_PrinterInfo info1, info2;
3369 WERROR werror;
3370 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3371 struct security_descriptor *sd1, *sd2;
3372 bool result = true;
3373
3374
3375 printf("Retrieving printer security for %s...", cli1->desthost);
3376 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3377 hnd1,
3378 3,
3379 0,
3380 &info1);
3381 if ( !W_ERROR_IS_OK(werror) ) {
3382 printf("failed (%s)\n", win_errstr(werror));
3383 result = false;
3384 goto done;
3385 }
3386 printf("ok\n");
3387
3388 printf("Retrieving printer security for %s...", cli2->desthost);
3389 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3390 hnd2,
3391 3,
3392 0,
3393 &info2);
3394 if ( !W_ERROR_IS_OK(werror) ) {
3395 printf("failed (%s)\n", win_errstr(werror));
3396 result = false;
3397 goto done;
3398 }
3399 printf("ok\n");
3400
3401
3402 printf("++ ");
3403
3404 sd1 = info1.info3.secdesc;
3405 sd2 = info2.info3.secdesc;
3406
3407 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3408 printf("NULL secdesc!\n");
3409 result = false;
3410 goto done;
3411 }
3412
3413 if (!security_descriptor_equal( sd1, sd2 ) ) {
3414 printf("Security Descriptors *not* equal!\n");
3415 result = false;
3416 goto done;
3417 }
3418
3419 printf("Security descriptors match\n");
3420
3421done:
3422 talloc_destroy(mem_ctx);
3423 return result;
3424}
3425
3426
3427/****************************************************************************
3428****************************************************************************/
3429
3430extern struct user_auth_info *rpcclient_auth_info;
3431
3432static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3433 TALLOC_CTX *mem_ctx, int argc,
3434 const char **argv)
3435{
3436 const char *printername;
3437 char *printername_path = NULL;
3438 struct cli_state *cli_server2 = NULL;
3439 struct rpc_pipe_client *cli2 = NULL;
3440 struct policy_handle hPrinter1, hPrinter2;
3441 NTSTATUS nt_status;
3442 WERROR werror;
3443
3444 if ( argc != 3 ) {
3445 printf("Usage: %s <printer> <server>\n", argv[0]);
3446 return WERR_OK;
3447 }
3448
3449 printername = argv[1];
3450
3451 /* first get the connection to the remote server */
3452
3453 nt_status = cli_full_connection(&cli_server2, lp_netbios_name(), argv[2],
3454 NULL, 0,
3455 "IPC$", "IPC",
3456 get_cmdline_auth_info_username(rpcclient_auth_info),
3457 lp_workgroup(),
3458 get_cmdline_auth_info_password(rpcclient_auth_info),
3459 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3460 get_cmdline_auth_info_signing_state(rpcclient_auth_info));
3461
3462 if ( !NT_STATUS_IS_OK(nt_status) )
3463 return WERR_GENERAL_FAILURE;
3464
3465 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss,
3466 &cli2);
3467 if (!NT_STATUS_IS_OK(nt_status)) {
3468 printf("failed to open spoolss pipe on server %s (%s)\n",
3469 argv[2], nt_errstr(nt_status));
3470 return WERR_GENERAL_FAILURE;
3471 }
3472
3473 /* now open up both printers */
3474
3475 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3476
3477 printf("Opening %s...", printername_path);
3478
3479 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3480 printername_path,
3481 PRINTER_ALL_ACCESS,
3482 &hPrinter1);
3483 if ( !W_ERROR_IS_OK(werror) ) {
3484 printf("failed (%s)\n", win_errstr(werror));
3485 goto done;
3486 }
3487 printf("ok\n");
3488
3489 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3490
3491 printf("Opening %s...", printername_path);
3492 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3493 printername_path,
3494 PRINTER_ALL_ACCESS,
3495 &hPrinter2);
3496 if ( !W_ERROR_IS_OK(werror) ) {
3497 printf("failed (%s)\n", win_errstr(werror));
3498 goto done;
3499 }
3500 printf("ok\n");
3501
3502 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3503 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3504#if 0
3505 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3506#endif
3507
3508
3509done:
3510 /* cleanup */
3511
3512 printf("Closing printers...");
3513 {
3514 WERROR _result;
3515 dcerpc_spoolss_ClosePrinter(cli->binding_handle, mem_ctx, &hPrinter1, &_result);
3516 dcerpc_spoolss_ClosePrinter(cli2->binding_handle, mem_ctx, &hPrinter2, &_result);
3517 }
3518 printf("ok\n");
3519
3520 /* close the second remote connection */
3521
3522 cli_shutdown( cli_server2 );
3523 return WERR_OK;
3524}
3525
3526static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3527{
3528 printf("print_processor_name: %s\n", r->print_processor_name);
3529}
3530
3531static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3532 TALLOC_CTX *mem_ctx, int argc,
3533 const char **argv)
3534{
3535 WERROR werror;
3536 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3537 uint32_t num_procs, level = 1, i;
3538 union spoolss_PrintProcessorInfo *procs;
3539
3540 /* Parse the command arguments */
3541
3542 if (argc < 1 || argc > 4) {
3543 printf ("Usage: %s [environment] [level]\n", argv[0]);
3544 return WERR_OK;
3545 }
3546
3547 if (argc >= 2) {
3548 environment = argv[1];
3549 }
3550
3551 if (argc == 3) {
3552 level = atoi(argv[2]);
3553 }
3554
3555 /* Enumerate Print Processors */
3556
3557 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3558 cli->srv_name_slash,
3559 environment,
3560 level,
3561 0,
3562 &num_procs,
3563 &procs);
3564 if (!W_ERROR_IS_OK(werror))
3565 goto done;
3566
3567 /* Display output */
3568
3569 for (i = 0; i < num_procs; i++) {
3570 switch (level) {
3571 case 1:
3572 display_proc_info1(&procs[i].info1);
3573 break;
3574 }
3575 }
3576
3577 done:
3578 return werror;
3579}
3580
3581static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3582{
3583 printf("name_array: %s\n", r->name_array);
3584}
3585
3586static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3587 TALLOC_CTX *mem_ctx, int argc,
3588 const char **argv)
3589{
3590 WERROR werror;
3591 const char *print_processor_name = "winprint";
3592 uint32_t num_procs, level = 1, i;
3593 union spoolss_PrintProcDataTypesInfo *procs;
3594
3595 /* Parse the command arguments */
3596
3597 if (argc < 1 || argc > 4) {
3598 printf ("Usage: %s [environment] [level]\n", argv[0]);
3599 return WERR_OK;
3600 }
3601
3602 if (argc >= 2) {
3603 print_processor_name = argv[1];
3604 }
3605
3606 if (argc == 3) {
3607 level = atoi(argv[2]);
3608 }
3609
3610 /* Enumerate Print Processor Data Types */
3611
3612 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3613 cli->srv_name_slash,
3614 print_processor_name,
3615 level,
3616 0,
3617 &num_procs,
3618 &procs);
3619 if (!W_ERROR_IS_OK(werror))
3620 goto done;
3621
3622 /* Display output */
3623
3624 for (i = 0; i < num_procs; i++) {
3625 switch (level) {
3626 case 1:
3627 display_proc_data_types_info1(&procs[i].info1);
3628 break;
3629 }
3630 }
3631
3632 done:
3633 return werror;
3634}
3635
3636static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3637{
3638 printf("monitor_name: %s\n", r->monitor_name);
3639}
3640
3641static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3642{
3643 printf("monitor_name: %s\n", r->monitor_name);
3644 printf("environment: %s\n", r->environment);
3645 printf("dll_name: %s\n", r->dll_name);
3646}
3647
3648static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3649 TALLOC_CTX *mem_ctx, int argc,
3650 const char **argv)
3651{
3652 WERROR werror;
3653 uint32_t count, level = 1, i;
3654 union spoolss_MonitorInfo *info;
3655
3656 /* Parse the command arguments */
3657
3658 if (argc > 2) {
3659 printf("Usage: %s [level]\n", argv[0]);
3660 return WERR_OK;
3661 }
3662
3663 if (argc == 2) {
3664 level = atoi(argv[1]);
3665 }
3666
3667 /* Enumerate Print Monitors */
3668
3669 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3670 cli->srv_name_slash,
3671 level,
3672 0,
3673 &count,
3674 &info);
3675 if (!W_ERROR_IS_OK(werror)) {
3676 goto done;
3677 }
3678
3679 /* Display output */
3680
3681 for (i = 0; i < count; i++) {
3682 switch (level) {
3683 case 1:
3684 display_monitor1(&info[i].info1);
3685 break;
3686 case 2:
3687 display_monitor2(&info[i].info2);
3688 break;
3689 }
3690 }
3691
3692 done:
3693 return werror;
3694}
3695
3696static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
3697 TALLOC_CTX *mem_ctx, int argc,
3698 const char **argv)
3699{
3700 WERROR result;
3701 NTSTATUS status;
3702 struct policy_handle handle, gdi_handle;
3703 const char *printername;
3704 struct spoolss_DevmodeContainer devmode_ctr;
3705 struct dcerpc_binding_handle *b = cli->binding_handle;
3706
3707 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3708
3709 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3710 printername,
3711 SEC_FLAG_MAXIMUM_ALLOWED,
3712 &handle);
3713 if (!W_ERROR_IS_OK(result)) {
3714 return result;
3715 }
3716
3717 ZERO_STRUCT(devmode_ctr);
3718
3719 status = dcerpc_spoolss_CreatePrinterIC(b, mem_ctx,
3720 &handle,
3721 &gdi_handle,
3722 &devmode_ctr,
3723 &result);
3724 if (!NT_STATUS_IS_OK(status)) {
3725 result = ntstatus_to_werror(status);
3726 goto done;
3727 }
3728 if (!W_ERROR_IS_OK(result)) {
3729 goto done;
3730 }
3731
3732 done:
3733 if (is_valid_policy_hnd(&gdi_handle)) {
3734 WERROR _result;
3735 dcerpc_spoolss_DeletePrinterIC(b, mem_ctx, &gdi_handle, &_result);
3736 }
3737 if (is_valid_policy_hnd(&handle)) {
3738 WERROR _result;
3739 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
3740 }
3741
3742 return result;
3743}
3744
3745static WERROR cmd_spoolss_play_gdi_script_on_printer_ic(struct rpc_pipe_client *cli,
3746 TALLOC_CTX *mem_ctx, int argc,
3747 const char **argv)
3748{
3749 WERROR result;
3750 NTSTATUS status;
3751 struct policy_handle handle, gdi_handle;
3752 const char *printername;
3753 struct spoolss_DevmodeContainer devmode_ctr;
3754 struct dcerpc_binding_handle *b = cli->binding_handle;
3755 DATA_BLOB in,out;
3756 uint32_t count = 0;
3757
3758 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
3759
3760 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3761 printername,
3762 SEC_FLAG_MAXIMUM_ALLOWED,
3763 &handle);
3764 if (!W_ERROR_IS_OK(result)) {
3765 return result;
3766 }
3767
3768 ZERO_STRUCT(devmode_ctr);
3769
3770 status = dcerpc_spoolss_CreatePrinterIC(b, mem_ctx,
3771 &handle,
3772 &gdi_handle,
3773 &devmode_ctr,
3774 &result);
3775 if (!NT_STATUS_IS_OK(status)) {
3776 result = ntstatus_to_werror(status);
3777 goto done;
3778 }
3779 if (!W_ERROR_IS_OK(result)) {
3780 goto done;
3781 }
3782
3783 in = data_blob_string_const("");
3784 out = data_blob_talloc_zero(mem_ctx, 4);
3785
3786 status = dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b, mem_ctx,
3787 &gdi_handle,
3788 in.data,
3789 in.length,
3790 out.data,
3791 out.length,
3792 0, /* ul */
3793 &result);
3794 if (!NT_STATUS_IS_OK(status)) {
3795 result = ntstatus_to_werror(status);
3796 goto done;
3797 }
3798 if (!W_ERROR_IS_OK(result)) {
3799 goto done;
3800 }
3801
3802 count = IVAL(out.data, 0);
3803
3804 out = data_blob_talloc_zero(mem_ctx,
3805 count * sizeof(struct UNIVERSAL_FONT_ID) + 4);
3806
3807 status = dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b, mem_ctx,
3808 &gdi_handle,
3809 in.data,
3810 in.length,
3811 out.data,
3812 out.length,
3813 0, /* ul */
3814 &result);
3815 if (!NT_STATUS_IS_OK(status)) {
3816 result = ntstatus_to_werror(status);
3817 goto done;
3818 }
3819 if (!W_ERROR_IS_OK(result)) {
3820 goto done;
3821 }
3822
3823 {
3824 enum ndr_err_code ndr_err;
3825 struct UNIVERSAL_FONT_ID_ctr r;
3826
3827 ndr_err = ndr_pull_struct_blob(&out, mem_ctx, &r,
3828 (ndr_pull_flags_fn_t)ndr_pull_UNIVERSAL_FONT_ID_ctr);
3829 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3830 NDR_PRINT_DEBUG(UNIVERSAL_FONT_ID_ctr, &r);
3831 }
3832 }
3833
3834 done:
3835 if (is_valid_policy_hnd(&gdi_handle)) {
3836 WERROR _result;
3837 dcerpc_spoolss_DeletePrinterIC(b, mem_ctx, &gdi_handle, &_result);
3838 }
3839 if (is_valid_policy_hnd(&handle)) {
3840 WERROR _result;
3841 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &_result);
3842 }
3843
3844 return result;
3845}
3846
3847/* List of commands exported by this module */
3848struct cmd_set spoolss_commands[] = {
3849
3850 { "SPOOLSS" },
3851
3852 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss, NULL, "Add a print driver", "" },
3853 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss, NULL, "Add a printer", "" },
3854 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss, NULL, "Delete a printer driver", "" },
3855 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss, NULL, "Delete a printer driver with files", "" },
3856 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss, NULL, "Enumerate printer data", "" },
3857 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss, NULL, "Enumerate printer data for a key", "" },
3858 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss, NULL, "Enumerate printer keys", "" },
3859 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss, NULL, "Enumerate print jobs", "" },
3860 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss, NULL, "Get print job", "" },
3861 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss, NULL, "Set print job", "" },
3862 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss, NULL, "Enumerate printer ports", "" },
3863 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss, NULL, "Enumerate installed printer drivers", "" },
3864 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss, NULL, "Enumerate printers", "" },
3865 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss, NULL, "Get print driver data", "" },
3866 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss, NULL, "Get printer driver data with keyname", ""},
3867 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss, NULL, "Get print driver information", "" },
3868 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss, NULL, "Get print driver upload directory", "" },
3869 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss, NULL, "Get printer info", "" },
3870 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer, &ndr_table_spoolss, NULL, "Open printer handle", "" },
3871 { "openprinter_ex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss, NULL, "Open printer handle", "" },
3872 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss, NULL, "Set printer driver", "" },
3873 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss, NULL, "Get print processor directory", "" },
3874 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss, NULL, "Add form", "" },
3875 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss, NULL, "Set form", "" },
3876 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss, NULL, "Get form", "" },
3877 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss, NULL, "Delete form", "" },
3878 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss, NULL, "Enumerate forms", "" },
3879 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss, NULL, "Set printer comment", "" },
3880 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss, NULL, "Set printername", "" },
3881 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss, NULL, "Set REG_SZ printer data", "" },
3882 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss, NULL, "Rffpcnex test", "" },
3883 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss, NULL, "Printer comparison test", "" },
3884 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss, NULL, "Enumerate Print Processors", "" },
3885 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss, NULL, "Enumerate Print Processor Data Types", "" },
3886 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss, NULL, "Enumerate Print Monitors", "" },
3887 { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss, NULL, "Create Printer IC", "" },
3888 { "playgdiscriptonprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_play_gdi_script_on_printer_ic, &ndr_table_spoolss, NULL, "Create Printer IC", "" },
3889
3890 { NULL }
3891};
Note: See TracBrowser for help on using the repository browser.