source: trunk-3.0/source/rpcclient/cmd_spoolss.c@ 101

Last change on this file since 101 was 39, checked in by Paul Smedley, 18 years ago

Upgrade source to 3.0.25a

File size: 77.0 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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23*/
24
25#include "includes.h"
26#include "rpcclient.h"
27
28struct table_node {
29 const char *long_archi;
30 const char *short_archi;
31 int version;
32};
33
34/* The version int is used by getdrivers. Note that
35 all architecture strings that support mutliple
36 versions must be grouped together since enumdrivers
37 uses this property to prevent issuing multiple
38 enumdriver calls for the same arch */
39
40
41static const struct table_node archi_table[]= {
42
43 {"Windows 4.0", "WIN40", 0 },
44 {"Windows NT x86", "W32X86", 2 },
45 {"Windows NT x86", "W32X86", 3 },
46 {"Windows NT R4000", "W32MIPS", 2 },
47 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
48 {"Windows NT PowerPC", "W32PPC", 2 },
49 {"Windows IA64", "IA64", 3 },
50 {"Windows x64", "x64", 3 },
51 {NULL, "", -1 }
52};
53
54/**
55 * @file
56 *
57 * rpcclient module for SPOOLSS rpc pipe.
58 *
59 * This generally just parses and checks command lines, and then calls
60 * a cli_spoolss function.
61 **/
62
63/****************************************************************************
64 function to do the mapping between the long architecture name and
65 the short one.
66****************************************************************************/
67
68static const char *cmd_spoolss_get_short_archi(const char *long_archi)
69{
70 int i=-1;
71
72 DEBUG(107,("Getting architecture dependant directory\n"));
73 do {
74 i++;
75 } while ( (archi_table[i].long_archi!=NULL ) &&
76 StrCaseCmp(long_archi, archi_table[i].long_archi) );
77
78 if (archi_table[i].long_archi==NULL) {
79 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
80 return NULL;
81 }
82
83 /* this might be client code - but shouldn't this be an fstrcpy etc? */
84
85
86 DEBUGADD(108,("index: [%d]\n", i));
87 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
88 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
89
90 return archi_table[i].short_archi;
91}
92
93/****************************************************************************
94****************************************************************************/
95
96static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
97 TALLOC_CTX *mem_ctx,
98 int argc, const char **argv)
99{
100 WERROR werror;
101 fstring printername;
102 fstring servername, user;
103 POLICY_HND hnd;
104
105 if (argc != 2) {
106 printf("Usage: %s <printername>\n", argv[0]);
107 return WERR_OK;
108 }
109
110 if (!cli)
111 return WERR_GENERAL_FAILURE;
112
113 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
114 strupper_m(servername);
115 fstrcpy(user, cli->user_name);
116 fstrcpy(printername, argv[1]);
117
118 /* Open the printer handle */
119
120 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
121 "", PRINTER_ALL_ACCESS,
122 servername, user, &hnd);
123
124 if (W_ERROR_IS_OK(werror)) {
125 printf("Printer %s opened successfully\n", printername);
126 werror = rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
127
128 if (!W_ERROR_IS_OK(werror)) {
129 printf("Error closing printer handle! (%s)\n",
130 get_dos_error_msg(werror));
131 }
132 }
133
134 return werror;
135}
136
137
138/****************************************************************************
139****************************************************************************/
140
141static void display_print_info_0(PRINTER_INFO_0 *i0)
142{
143 fstring name = "";
144 fstring servername = "";
145
146 if (!i0)
147 return;
148
149 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
150
151 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
152
153 printf("\tprintername:[%s]\n", name);
154 printf("\tservername:[%s]\n", servername);
155 printf("\tcjobs:[0x%x]\n", i0->cjobs);
156 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
157
158 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
159 i0->day, i0->dayofweek);
160 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
161 i0->second, i0->milliseconds);
162
163 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
164 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
165
166 printf("\tmajorversion:[0x%x]\n", i0->major_version);
167 printf("\tbuildversion:[0x%x]\n", i0->build_version);
168
169 printf("\tunknown7:[0x%x]\n", i0->unknown7);
170 printf("\tunknown8:[0x%x]\n", i0->unknown8);
171 printf("\tunknown9:[0x%x]\n", i0->unknown9);
172 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
173 printf("\tunknown11:[0x%x]\n", i0->unknown11);
174 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
175 printf("\tunknown13:[0x%x]\n", i0->unknown13);
176 printf("\tunknown14:[0x%x]\n", i0->unknown14);
177 printf("\tunknown15:[0x%x]\n", i0->unknown15);
178 printf("\tunknown16:[0x%x]\n", i0->unknown16);
179 printf("\tchange_id:[0x%x]\n", i0->change_id);
180 printf("\tunknown18:[0x%x]\n", i0->unknown18);
181 printf("\tstatus:[0x%x]\n", i0->status);
182 printf("\tunknown20:[0x%x]\n", i0->unknown20);
183 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
184 printf("\tunknown22:[0x%x]\n", i0->unknown22);
185 printf("\tunknown23:[0x%x]\n", i0->unknown23);
186 printf("\tunknown24:[0x%x]\n", i0->unknown24);
187 printf("\tunknown25:[0x%x]\n", i0->unknown25);
188 printf("\tunknown26:[0x%x]\n", i0->unknown26);
189 printf("\tunknown27:[0x%x]\n", i0->unknown27);
190 printf("\tunknown28:[0x%x]\n", i0->unknown28);
191 printf("\tunknown29:[0x%x]\n", i0->unknown29);
192
193 printf("\n");
194}
195
196/****************************************************************************
197****************************************************************************/
198
199static void display_print_info_1(PRINTER_INFO_1 *i1)
200{
201 fstring desc = "";
202 fstring name = "";
203 fstring comm = "";
204
205 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
206 STR_TERMINATE);
207
208 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
209 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
210
211 printf("\tflags:[0x%x]\n", i1->flags);
212 printf("\tname:[%s]\n", name);
213 printf("\tdescription:[%s]\n", desc);
214 printf("\tcomment:[%s]\n", comm);
215
216 printf("\n");
217}
218
219/****************************************************************************
220****************************************************************************/
221
222static void display_print_info_2(PRINTER_INFO_2 *i2)
223{
224 fstring servername = "";
225 fstring printername = "";
226 fstring sharename = "";
227 fstring portname = "";
228 fstring drivername = "";
229 fstring comment = "";
230 fstring location = "";
231 fstring sepfile = "";
232 fstring printprocessor = "";
233 fstring datatype = "";
234 fstring parameters = "";
235
236 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
237 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
238 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
239 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
240 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
241 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
242 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
243 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
244 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
245 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
246 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
247
248 printf("\tservername:[%s]\n", servername);
249 printf("\tprintername:[%s]\n", printername);
250 printf("\tsharename:[%s]\n", sharename);
251 printf("\tportname:[%s]\n", portname);
252 printf("\tdrivername:[%s]\n", drivername);
253 printf("\tcomment:[%s]\n", comment);
254 printf("\tlocation:[%s]\n", location);
255 printf("\tsepfile:[%s]\n", sepfile);
256 printf("\tprintprocessor:[%s]\n", printprocessor);
257 printf("\tdatatype:[%s]\n", datatype);
258 printf("\tparameters:[%s]\n", parameters);
259 printf("\tattributes:[0x%x]\n", i2->attributes);
260 printf("\tpriority:[0x%x]\n", i2->priority);
261 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
262 printf("\tstarttime:[0x%x]\n", i2->starttime);
263 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
264 printf("\tstatus:[0x%x]\n", i2->status);
265 printf("\tcjobs:[0x%x]\n", i2->cjobs);
266 printf("\taverageppm:[0x%x]\n", i2->averageppm);
267
268 if (i2->secdesc)
269 display_sec_desc(i2->secdesc);
270
271 printf("\n");
272}
273
274/****************************************************************************
275****************************************************************************/
276
277static void display_print_info_3(PRINTER_INFO_3 *i3)
278{
279 display_sec_desc(i3->secdesc);
280
281 printf("\n");
282}
283
284/****************************************************************************
285****************************************************************************/
286
287static void display_print_info_7(PRINTER_INFO_7 *i7)
288{
289 fstring guid = "";
290 rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE);
291 printf("\tguid:[%s]\n", guid);
292 printf("\taction:[0x%x]\n", i7->action);
293}
294
295
296/****************************************************************************
297****************************************************************************/
298
299static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
300 TALLOC_CTX *mem_ctx,
301 int argc, const char **argv)
302{
303 WERROR result;
304 uint32 info_level = 1;
305 PRINTER_INFO_CTR ctr;
306 uint32 i = 0, num_printers;
307 fstring name;
308
309 if (argc > 3)
310 {
311 printf("Usage: %s [level] [name]\n", argv[0]);
312 return WERR_OK;
313 }
314
315 if (argc >= 2)
316 info_level = atoi(argv[1]);
317
318 if (argc == 3)
319 fstrcpy(name, argv[2]);
320 else {
321 slprintf(name, sizeof(name)-1, "\\\\%s", cli->cli->desthost);
322 strupper_m(name);
323 }
324
325 ZERO_STRUCT(ctr);
326
327 result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
328 info_level, &num_printers, &ctr);
329
330 if (W_ERROR_IS_OK(result)) {
331
332 if (!num_printers) {
333 printf ("No printers returned.\n");
334 goto done;
335 }
336
337 for (i = 0; i < num_printers; i++) {
338 switch(info_level) {
339 case 0:
340 display_print_info_0(&ctr.printers_0[i]);
341 break;
342 case 1:
343 display_print_info_1(&ctr.printers_1[i]);
344 break;
345 case 2:
346 display_print_info_2(&ctr.printers_2[i]);
347 break;
348 case 3:
349 display_print_info_3(&ctr.printers_3[i]);
350 break;
351 default:
352 printf("unknown info level %d\n", info_level);
353 goto done;
354 }
355 }
356 }
357 done:
358
359 return result;
360}
361
362/****************************************************************************
363****************************************************************************/
364
365static void display_port_info_1(PORT_INFO_1 *i1)
366{
367 fstring buffer;
368
369 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
370 printf("\tPort Name:\t[%s]\n", buffer);
371}
372
373/****************************************************************************
374****************************************************************************/
375
376static void display_port_info_2(PORT_INFO_2 *i2)
377{
378 fstring buffer;
379
380 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
381 printf("\tPort Name:\t[%s]\n", buffer);
382 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
383
384 printf("\tMonitor Name:\t[%s]\n", buffer);
385 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
386
387 printf("\tDescription:\t[%s]\n", buffer);
388 printf("\tPort Type:\t" );
389 if ( i2->port_type ) {
390 int comma = 0; /* hack */
391 printf( "[" );
392 if ( i2->port_type & PORT_TYPE_READ ) {
393 printf( "Read" );
394 comma = 1;
395 }
396 if ( i2->port_type & PORT_TYPE_WRITE ) {
397 printf( "%sWrite", comma ? ", " : "" );
398 comma = 1;
399 }
400 /* These two have slightly different interpretations
401 on 95/98/ME but I'm disregarding that for now */
402 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
403 printf( "%sRedirected", comma ? ", " : "" );
404 comma = 1;
405 }
406 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
407 printf( "%sNet-Attached", comma ? ", " : "" );
408 }
409 printf( "]\n" );
410 } else {
411 printf( "[Unset]\n" );
412 }
413 printf("\tReserved:\t[%d]\n", i2->reserved);
414 printf("\n");
415}
416
417/****************************************************************************
418****************************************************************************/
419
420static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
421 TALLOC_CTX *mem_ctx, int argc,
422 const char **argv)
423{
424 WERROR result;
425 uint32 info_level = 1;
426 PORT_INFO_CTR ctr;
427 uint32 returned;
428
429 if (argc > 2) {
430 printf("Usage: %s [level]\n", argv[0]);
431 return WERR_OK;
432 }
433
434 if (argc == 2)
435 info_level = atoi(argv[1]);
436
437 /* Enumerate ports */
438
439 ZERO_STRUCT(ctr);
440
441 result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
442
443 if (W_ERROR_IS_OK(result)) {
444 int i;
445
446 for (i = 0; i < returned; i++) {
447 switch (info_level) {
448 case 1:
449 display_port_info_1(&ctr.port.info_1[i]);
450 break;
451 case 2:
452 display_port_info_2(&ctr.port.info_2[i]);
453 break;
454 default:
455 printf("unknown info level %d\n", info_level);
456 break;
457 }
458 }
459 }
460
461 return result;
462}
463
464/****************************************************************************
465****************************************************************************/
466
467static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
468 TALLOC_CTX *mem_ctx,
469 int argc, const char **argv)
470{
471 POLICY_HND pol;
472 WERROR result;
473 uint32 info_level = 2;
474 BOOL opened_hnd = False;
475 PRINTER_INFO_CTR ctr;
476 fstring printername,
477 servername,
478 user,
479 comment;
480
481 if (argc == 1 || argc > 3) {
482 printf("Usage: %s printername comment\n", argv[0]);
483
484 return WERR_OK;
485 }
486
487 /* Open a printer handle */
488 if (argc == 3) {
489 fstrcpy(comment, argv[2]);
490 }
491
492 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
493 strupper_m(servername);
494 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
495 fstrcpy(user, cli->user_name);
496
497 /* get a printer handle */
498 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
499 PRINTER_ALL_ACCESS, servername,
500 user, &pol);
501
502 if (!W_ERROR_IS_OK(result))
503 goto done;
504
505 opened_hnd = True;
506
507 /* Get printer info */
508 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
509
510 if (!W_ERROR_IS_OK(result))
511 goto done;
512
513
514 /* Modify the comment. */
515 init_unistr(&ctr.printers_2->comment, comment);
516 ctr.printers_2->devmode = NULL;
517 ctr.printers_2->secdesc = NULL;
518
519 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
520 if (W_ERROR_IS_OK(result))
521 printf("Success in setting comment.\n");
522
523 done:
524 if (opened_hnd)
525 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
526
527 return result;
528}
529
530/****************************************************************************
531****************************************************************************/
532
533static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
534 TALLOC_CTX *mem_ctx,
535 int argc, const char **argv)
536{
537 POLICY_HND pol;
538 WERROR result;
539 uint32 info_level = 2;
540 BOOL opened_hnd = False;
541 PRINTER_INFO_CTR ctr;
542 fstring printername,
543 servername,
544 user,
545 new_printername;
546
547 if (argc == 1 || argc > 3) {
548 printf("Usage: %s printername new_printername\n", argv[0]);
549
550 return WERR_OK;
551 }
552
553 /* Open a printer handle */
554 if (argc == 3) {
555 fstrcpy(new_printername, argv[2]);
556 }
557
558 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
559 strupper_m(servername);
560 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
561 fstrcpy(user, cli->user_name);
562
563 /* get a printer handle */
564 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
565 PRINTER_ALL_ACCESS, servername,
566 user, &pol);
567
568 if (!W_ERROR_IS_OK(result))
569 goto done;
570
571 opened_hnd = True;
572
573 /* Get printer info */
574 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
575
576 if (!W_ERROR_IS_OK(result))
577 goto done;
578
579 /* Modify the printername. */
580 init_unistr(&ctr.printers_2->printername, new_printername);
581 ctr.printers_2->devmode = NULL;
582 ctr.printers_2->secdesc = NULL;
583
584 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
585 if (W_ERROR_IS_OK(result))
586 printf("Success in setting printername.\n");
587
588 done:
589 if (opened_hnd)
590 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
591
592 return result;
593}
594
595/****************************************************************************
596****************************************************************************/
597
598static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
599 TALLOC_CTX *mem_ctx,
600 int argc, const char **argv)
601{
602 POLICY_HND pol;
603 WERROR result;
604 uint32 info_level = 1;
605 BOOL opened_hnd = False;
606 PRINTER_INFO_CTR ctr;
607 fstring printername,
608 servername,
609 user;
610
611 if (argc == 1 || argc > 3) {
612 printf("Usage: %s <printername> [level]\n", argv[0]);
613 return WERR_OK;
614 }
615
616 /* Open a printer handle */
617 if (argc == 3) {
618 info_level = atoi(argv[2]);
619 }
620
621 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
622 strupper_m(servername);
623 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
624 fstrcpy(user, cli->user_name);
625
626 /* get a printer handle */
627
628 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
629 "", MAXIMUM_ALLOWED_ACCESS,
630 servername, user, &pol);
631
632 if (!W_ERROR_IS_OK(result))
633 goto done;
634
635 opened_hnd = True;
636
637 /* Get printer info */
638
639 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
640
641 if (!W_ERROR_IS_OK(result))
642 goto done;
643
644 /* Display printer info */
645
646 switch (info_level) {
647 case 0:
648 display_print_info_0(ctr.printers_0);
649 break;
650 case 1:
651 display_print_info_1(ctr.printers_1);
652 break;
653 case 2:
654 display_print_info_2(ctr.printers_2);
655 break;
656 case 3:
657 display_print_info_3(ctr.printers_3);
658 break;
659 case 7:
660 display_print_info_7(ctr.printers_7);
661 break;
662 default:
663 printf("unknown info level %d\n", info_level);
664 break;
665 }
666
667 done:
668 if (opened_hnd)
669 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
670
671 return result;
672}
673
674/****************************************************************************
675****************************************************************************/
676
677static void display_reg_value(REGISTRY_VALUE value)
678{
679 pstring text;
680
681 switch(value.type) {
682 case REG_DWORD:
683 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
684 *((uint32 *) value.data_p));
685 break;
686 case REG_SZ:
687 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
688 STR_TERMINATE);
689 printf("%s: REG_SZ: %s\n", value.valuename, text);
690 break;
691 case REG_BINARY: {
692 char *hex = hex_encode(NULL, value.data_p, value.size);
693 size_t i, len;
694 printf("%s: REG_BINARY:", value.valuename);
695 len = strlen(hex);
696 for (i=0; i<len; i++) {
697 if (hex[i] == '\0') {
698 break;
699 }
700 if (i%40 == 0) {
701 putchar('\n');
702 }
703 putchar(hex[i]);
704 }
705 TALLOC_FREE(hex);
706 putchar('\n');
707 break;
708 }
709 case REG_MULTI_SZ: {
710 uint16 *curstr = (uint16 *) value.data_p;
711 uint8 *start = value.data_p;
712 printf("%s: REG_MULTI_SZ:\n", value.valuename);
713 while (((uint8 *) curstr < start + value.size)) {
714 rpcstr_pull(text, curstr, sizeof(text), -1,
715 STR_TERMINATE);
716 printf(" %s\n", *text != 0 ? text : "NULL");
717 curstr += strlen(text) + 1;
718 }
719 }
720 break;
721 default:
722 printf("%s: unknown type %d\n", value.valuename, value.type);
723 }
724
725}
726
727/****************************************************************************
728****************************************************************************/
729
730static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
731 TALLOC_CTX *mem_ctx,
732 int argc, const char **argv)
733{
734 POLICY_HND pol;
735 WERROR result;
736 BOOL opened_hnd = False;
737 fstring printername,
738 servername,
739 user;
740 const char *valuename;
741 REGISTRY_VALUE value;
742
743 if (argc != 3) {
744 printf("Usage: %s <printername> <valuename>\n", argv[0]);
745 printf("<printername> of . queries print server\n");
746 return WERR_OK;
747 }
748 valuename = argv[2];
749
750 /* Open a printer handle */
751
752 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
753 strupper_m(servername);
754 if (strncmp(argv[1], ".", sizeof(".")) == 0)
755 fstrcpy(printername, servername);
756 else
757 slprintf(printername, sizeof(servername)-1, "%s\\%s",
758 servername, argv[1]);
759 fstrcpy(user, cli->user_name);
760
761 /* get a printer handle */
762
763 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
764 "", MAXIMUM_ALLOWED_ACCESS,
765 servername, user, &pol);
766
767 if (!W_ERROR_IS_OK(result))
768 goto done;
769
770 opened_hnd = True;
771
772 /* Get printer info */
773
774 result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
775
776 if (!W_ERROR_IS_OK(result))
777 goto done;
778
779 /* Display printer data */
780
781 fstrcpy(value.valuename, valuename);
782 display_reg_value(value);
783
784
785 done:
786 if (opened_hnd)
787 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
788
789 return result;
790}
791
792/****************************************************************************
793****************************************************************************/
794
795static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
796 TALLOC_CTX *mem_ctx,
797 int argc, const char **argv)
798{
799 POLICY_HND pol;
800 WERROR result;
801 BOOL opened_hnd = False;
802 fstring printername,
803 servername,
804 user;
805 const char *valuename, *keyname;
806 REGISTRY_VALUE value;
807
808 if (argc != 4) {
809 printf("Usage: %s <printername> <keyname> <valuename>\n",
810 argv[0]);
811 printf("<printername> of . queries print server\n");
812 return WERR_OK;
813 }
814 valuename = argv[3];
815 keyname = argv[2];
816
817 /* Open a printer handle */
818
819 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
820 strupper_m(servername);
821 if (strncmp(argv[1], ".", sizeof(".")) == 0)
822 fstrcpy(printername, servername);
823 else
824 slprintf(printername, sizeof(printername)-1, "%s\\%s",
825 servername, argv[1]);
826 fstrcpy(user, cli->user_name);
827
828 /* get a printer handle */
829
830 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
831 "", MAXIMUM_ALLOWED_ACCESS,
832 servername, user, &pol);
833
834 if (!W_ERROR_IS_OK(result))
835 goto done;
836
837 opened_hnd = True;
838
839 /* Get printer info */
840
841 result = rpccli_spoolss_getprinterdataex(cli, mem_ctx, &pol, keyname,
842 valuename, &value);
843
844 if (!W_ERROR_IS_OK(result))
845 goto done;
846
847 /* Display printer data */
848
849 fstrcpy(value.valuename, valuename);
850 display_reg_value(value);
851
852
853 done:
854 if (opened_hnd)
855 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
856
857 return result;
858}
859
860/****************************************************************************
861****************************************************************************/
862
863static void display_print_driver_1(DRIVER_INFO_1 *i1)
864{
865 fstring name;
866 if (i1 == NULL)
867 return;
868
869 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
870
871 printf ("Printer Driver Info 1:\n");
872 printf ("\tDriver Name: [%s]\n\n", name);
873
874 return;
875}
876
877/****************************************************************************
878****************************************************************************/
879
880static void display_print_driver_2(DRIVER_INFO_2 *i1)
881{
882 fstring name;
883 fstring architecture;
884 fstring driverpath;
885 fstring datafile;
886 fstring configfile;
887 if (i1 == NULL)
888 return;
889
890 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
891 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
892 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
893 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
894 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
895
896 printf ("Printer Driver Info 2:\n");
897 printf ("\tVersion: [%x]\n", i1->version);
898 printf ("\tDriver Name: [%s]\n", name);
899 printf ("\tArchitecture: [%s]\n", architecture);
900 printf ("\tDriver Path: [%s]\n", driverpath);
901 printf ("\tDatafile: [%s]\n", datafile);
902 printf ("\tConfigfile: [%s]\n\n", configfile);
903
904 return;
905}
906
907/****************************************************************************
908****************************************************************************/
909
910static void display_print_driver_3(DRIVER_INFO_3 *i1)
911{
912 fstring name = "";
913 fstring architecture = "";
914 fstring driverpath = "";
915 fstring datafile = "";
916 fstring configfile = "";
917 fstring helpfile = "";
918 fstring dependentfiles = "";
919 fstring monitorname = "";
920 fstring defaultdatatype = "";
921
922 int length=0;
923 BOOL valid = True;
924
925 if (i1 == NULL)
926 return;
927
928 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
929 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
930 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
931 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
932 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
933 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
934 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
935 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
936
937 printf ("Printer Driver Info 3:\n");
938 printf ("\tVersion: [%x]\n", i1->version);
939 printf ("\tDriver Name: [%s]\n",name);
940 printf ("\tArchitecture: [%s]\n", architecture);
941 printf ("\tDriver Path: [%s]\n", driverpath);
942 printf ("\tDatafile: [%s]\n", datafile);
943 printf ("\tConfigfile: [%s]\n", configfile);
944 printf ("\tHelpfile: [%s]\n\n", helpfile);
945
946 while (valid)
947 {
948 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
949
950 length+=strlen(dependentfiles)+1;
951
952 if (strlen(dependentfiles) > 0)
953 {
954 printf ("\tDependentfiles: [%s]\n", dependentfiles);
955 }
956 else
957 {
958 valid = False;
959 }
960 }
961
962 printf ("\n");
963
964 printf ("\tMonitorname: [%s]\n", monitorname);
965 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
966
967 return;
968}
969
970/****************************************************************************
971****************************************************************************/
972
973static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
974 TALLOC_CTX *mem_ctx,
975 int argc, const char **argv)
976{
977 POLICY_HND pol;
978 WERROR werror;
979 uint32 info_level = 3;
980 BOOL opened_hnd = False;
981 PRINTER_DRIVER_CTR ctr;
982 fstring printername,
983 servername,
984 user;
985 uint32 i;
986 BOOL success = False;
987
988 if ((argc == 1) || (argc > 3))
989 {
990 printf("Usage: %s <printername> [level]\n", argv[0]);
991 return WERR_OK;
992 }
993
994 /* get the arguments need to open the printer handle */
995 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
996 strupper_m(servername);
997 fstrcpy(user, cli->user_name);
998 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
999 if (argc == 3)
1000 info_level = atoi(argv[2]);
1001
1002 /* Open a printer handle */
1003
1004 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1005 PRINTER_ACCESS_USE,
1006 servername, user, &pol);
1007
1008 if (!W_ERROR_IS_OK(werror)) {
1009 printf("Error opening printer handle for %s!\n", printername);
1010 return werror;
1011 }
1012
1013 opened_hnd = True;
1014
1015 /* loop through and print driver info level for each architecture */
1016
1017 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1018
1019 werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
1020 archi_table[i].long_archi, archi_table[i].version,
1021 &ctr);
1022
1023 if (!W_ERROR_IS_OK(werror))
1024 continue;
1025
1026 /* need at least one success */
1027
1028 success = True;
1029
1030 printf ("\n[%s]\n", archi_table[i].long_archi);
1031
1032 switch (info_level) {
1033 case 1:
1034 display_print_driver_1 (ctr.info1);
1035 break;
1036 case 2:
1037 display_print_driver_2 (ctr.info2);
1038 break;
1039 case 3:
1040 display_print_driver_3 (ctr.info3);
1041 break;
1042 default:
1043 printf("unknown info level %d\n", info_level);
1044 break;
1045 }
1046 }
1047
1048 /* Cleanup */
1049
1050 if (opened_hnd)
1051 rpccli_spoolss_close_printer (cli, mem_ctx, &pol);
1052
1053 if ( success )
1054 werror = WERR_OK;
1055
1056 return werror;
1057}
1058
1059/****************************************************************************
1060****************************************************************************/
1061
1062static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1063 TALLOC_CTX *mem_ctx,
1064 int argc, const char **argv)
1065{
1066 WERROR werror = WERR_OK;
1067 uint32 info_level = 1;
1068 PRINTER_DRIVER_CTR ctr;
1069 uint32 i, j,
1070 returned;
1071
1072 if (argc > 2) {
1073 printf("Usage: enumdrivers [level]\n");
1074 return WERR_OK;
1075 }
1076
1077 if (argc == 2)
1078 info_level = atoi(argv[1]);
1079
1080
1081 /* loop through and print driver info level for each architecture */
1082 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1083 /* check to see if we already asked for this architecture string */
1084
1085 if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
1086 continue;
1087
1088 werror = rpccli_spoolss_enumprinterdrivers(
1089 cli, mem_ctx, info_level,
1090 archi_table[i].long_archi, &returned, &ctr);
1091
1092 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1093 printf ("Server does not support environment [%s]\n",
1094 archi_table[i].long_archi);
1095 werror = WERR_OK;
1096 continue;
1097 }
1098
1099 if (returned == 0)
1100 continue;
1101
1102 if (!W_ERROR_IS_OK(werror)) {
1103 printf ("Error getting driver for environment [%s] - %d\n",
1104 archi_table[i].long_archi, W_ERROR_V(werror));
1105 continue;
1106 }
1107
1108 printf ("\n[%s]\n", archi_table[i].long_archi);
1109 switch (info_level)
1110 {
1111
1112 case 1:
1113 for (j=0; j < returned; j++) {
1114 display_print_driver_1 (&ctr.info1[j]);
1115 }
1116 break;
1117 case 2:
1118 for (j=0; j < returned; j++) {
1119 display_print_driver_2 (&ctr.info2[j]);
1120 }
1121 break;
1122 case 3:
1123 for (j=0; j < returned; j++) {
1124 display_print_driver_3 (&ctr.info3[j]);
1125 }
1126 break;
1127 default:
1128 printf("unknown info level %d\n", info_level);
1129 return WERR_UNKNOWN_LEVEL;
1130 }
1131 }
1132
1133 return werror;
1134}
1135
1136/****************************************************************************
1137****************************************************************************/
1138
1139static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
1140{
1141 fstring name;
1142 if (i1 == NULL)
1143 return;
1144
1145 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
1146
1147 printf ("\tDirectory Name:[%s]\n", name);
1148}
1149
1150/****************************************************************************
1151****************************************************************************/
1152
1153static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1154 TALLOC_CTX *mem_ctx,
1155 int argc, const char **argv)
1156{
1157 WERROR result;
1158 fstring env;
1159 DRIVER_DIRECTORY_CTR ctr;
1160
1161 if (argc > 2) {
1162 printf("Usage: %s [environment]\n", argv[0]);
1163 return WERR_OK;
1164 }
1165
1166 /* Get the arguments need to open the printer handle */
1167
1168 if (argc == 2)
1169 fstrcpy (env, argv[1]);
1170 else
1171 fstrcpy (env, "Windows NT x86");
1172
1173 /* Get the directory. Only use Info level 1 */
1174
1175 result = rpccli_spoolss_getprinterdriverdir(cli, mem_ctx, 1, env, &ctr);
1176
1177 if (W_ERROR_IS_OK(result))
1178 display_printdriverdir_1(ctr.info1);
1179
1180 return result;
1181}
1182
1183/****************************************************************************
1184****************************************************************************/
1185
1186void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
1187{
1188
1189 int i;
1190
1191 for (i=0; archi_table[i].long_archi != NULL; i++)
1192 {
1193 if (strcmp(arch, archi_table[i].short_archi) == 0)
1194 {
1195 info->version = archi_table[i].version;
1196 init_unistr (&info->architecture, archi_table[i].long_archi);
1197 break;
1198 }
1199 }
1200
1201 if (archi_table[i].long_archi == NULL)
1202 {
1203 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1204 }
1205
1206 return;
1207}
1208
1209
1210/**************************************************************************
1211 wrapper for strtok to get the next parameter from a delimited list.
1212 Needed to handle the empty parameter string denoted by "NULL"
1213 *************************************************************************/
1214
1215static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
1216{
1217 char *ptr;
1218
1219 /* get the next token */
1220 ptr = strtok(str, delim);
1221
1222 /* a string of 'NULL' is used to represent an empty
1223 parameter because two consecutive delimiters
1224 will not return an empty string. See man strtok(3)
1225 for details */
1226 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
1227 ptr = NULL;
1228
1229 if (dest != NULL)
1230 init_unistr(dest, ptr);
1231
1232 return ptr;
1233}
1234
1235/********************************************************************************
1236 fill in the members of a DRIVER_INFO_3 struct using a character
1237 string in the form of
1238 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1239 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1240 <Default Data Type>:<Comma Separated list of Files>
1241 *******************************************************************************/
1242static BOOL init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
1243 char *args )
1244{
1245 char *str, *str2;
1246 uint32 len, i;
1247
1248 /* fill in the UNISTR fields */
1249 str = get_driver_3_param (args, ":", &info->name);
1250 str = get_driver_3_param (NULL, ":", &info->driverpath);
1251 str = get_driver_3_param (NULL, ":", &info->datafile);
1252 str = get_driver_3_param (NULL, ":", &info->configfile);
1253 str = get_driver_3_param (NULL, ":", &info->helpfile);
1254 str = get_driver_3_param (NULL, ":", &info->monitorname);
1255 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1256
1257 /* <Comma Separated List of Dependent Files> */
1258 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1259 str = str2;
1260
1261 /* begin to strip out each filename */
1262 str = strtok(str, ",");
1263 len = 0;
1264 while (str != NULL)
1265 {
1266 /* keep a cumlative count of the str lengths */
1267 len += strlen(str)+1;
1268 str = strtok(NULL, ",");
1269 }
1270
1271 /* allocate the space; add one extra slot for a terminating NULL.
1272 Each filename is NULL terminated and the end contains a double
1273 NULL */
1274 if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL)
1275 {
1276 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1277 return False;
1278 }
1279 for (i=0; i<len; i++)
1280 {
1281 SSVAL(&info->dependentfiles[i], 0, str2[i]);
1282 }
1283 info->dependentfiles[len] = '\0';
1284
1285 return True;
1286}
1287
1288
1289/****************************************************************************
1290****************************************************************************/
1291
1292static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1293 TALLOC_CTX *mem_ctx,
1294 int argc, const char **argv)
1295{
1296 WERROR result;
1297 uint32 level = 3;
1298 PRINTER_DRIVER_CTR ctr;
1299 DRIVER_INFO_3 info3;
1300 const char *arch;
1301 fstring driver_name;
1302 char *driver_args;
1303
1304 /* parse the command arguements */
1305 if (argc != 3 && argc != 4)
1306 {
1307 printf ("Usage: %s <Environment> \\\n", argv[0]);
1308 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1309 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1310 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1311 printf ("\t[version]\n");
1312
1313 return WERR_OK;
1314 }
1315
1316 /* Fill in the DRIVER_INFO_3 struct */
1317 ZERO_STRUCT(info3);
1318 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
1319 {
1320 printf ("Error Unknown architechture [%s]\n", argv[1]);
1321 return WERR_INVALID_PARAM;
1322 }
1323 else
1324 set_drv_info_3_env(&info3, arch);
1325
1326 driver_args = talloc_strdup( mem_ctx, argv[2] );
1327 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1328 {
1329 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1330 return WERR_INVALID_PARAM;
1331 }
1332
1333 /* if printer driver version specified, override the default version
1334 * used by the architecture. This allows installation of Windows
1335 * 2000 (version 3) printer drivers. */
1336 if (argc == 4)
1337 {
1338 info3.version = atoi(argv[3]);
1339 }
1340
1341
1342 ctr.info3 = &info3;
1343 result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1344
1345 if (W_ERROR_IS_OK(result)) {
1346 rpcstr_pull(driver_name, info3.name.buffer,
1347 sizeof(driver_name), -1, STR_TERMINATE);
1348 printf ("Printer Driver %s successfully installed.\n",
1349 driver_name);
1350 }
1351
1352 return result;
1353}
1354
1355
1356/****************************************************************************
1357****************************************************************************/
1358
1359static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1360 TALLOC_CTX *mem_ctx,
1361 int argc, const char **argv)
1362{
1363 WERROR result;
1364 uint32 level = 2;
1365 PRINTER_INFO_CTR ctr;
1366 PRINTER_INFO_2 info2;
1367 fstring servername;
1368
1369 /* parse the command arguements */
1370 if (argc != 5)
1371 {
1372 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1373 return WERR_OK;
1374 }
1375
1376 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
1377 strupper_m(servername);
1378
1379 /* Fill in the DRIVER_INFO_2 struct */
1380 ZERO_STRUCT(info2);
1381
1382 init_unistr( &info2.printername, argv[1]);
1383 init_unistr( &info2.sharename, argv[2]);
1384 init_unistr( &info2.drivername, argv[3]);
1385 init_unistr( &info2.portname, argv[4]);
1386 init_unistr( &info2.comment, "Created by rpcclient");
1387 init_unistr( &info2.printprocessor, "winprint");
1388 init_unistr( &info2.datatype, "RAW");
1389 info2.devmode = NULL;
1390 info2.secdesc = NULL;
1391 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1392 info2.priority = 0;
1393 info2.defaultpriority = 0;
1394 info2.starttime = 0;
1395 info2.untiltime = 0;
1396
1397 /* These three fields must not be used by AddPrinter()
1398 as defined in the MS Platform SDK documentation..
1399 --jerry
1400 info2.status = 0;
1401 info2.cjobs = 0;
1402 info2.averageppm = 0;
1403 */
1404
1405 ctr.printers_2 = &info2;
1406 result = rpccli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1407
1408 if (W_ERROR_IS_OK(result))
1409 printf ("Printer %s successfully installed.\n", argv[1]);
1410
1411 return result;
1412}
1413
1414/****************************************************************************
1415****************************************************************************/
1416
1417static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1418 TALLOC_CTX *mem_ctx,
1419 int argc, const char **argv)
1420{
1421 POLICY_HND pol;
1422 WERROR result;
1423 uint32 level = 2;
1424 BOOL opened_hnd = False;
1425 PRINTER_INFO_CTR ctr;
1426 PRINTER_INFO_2 info2;
1427 fstring servername,
1428 printername,
1429 user;
1430
1431 /* parse the command arguements */
1432 if (argc != 3)
1433 {
1434 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1435 return WERR_OK;
1436 }
1437
1438 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
1439 strupper_m(servername);
1440 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
1441 fstrcpy(user, cli->user_name);
1442
1443 /* Get a printer handle */
1444
1445 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1446 PRINTER_ALL_ACCESS,
1447 servername, user, &pol);
1448
1449 if (!W_ERROR_IS_OK(result))
1450 goto done;
1451
1452 opened_hnd = True;
1453
1454 /* Get printer info */
1455
1456 ZERO_STRUCT (info2);
1457 ctr.printers_2 = &info2;
1458
1459 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
1460
1461 if (!W_ERROR_IS_OK(result)) {
1462 printf ("Unable to retrieve printer information!\n");
1463 goto done;
1464 }
1465
1466 /* Set the printer driver */
1467
1468 init_unistr(&ctr.printers_2->drivername, argv[2]);
1469
1470 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1471
1472 if (!W_ERROR_IS_OK(result)) {
1473 printf("SetPrinter call failed!\n");
1474 goto done;;
1475 }
1476
1477 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1478
1479done:
1480 /* Cleanup */
1481
1482 if (opened_hnd)
1483 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
1484
1485 return result;
1486}
1487
1488
1489/****************************************************************************
1490****************************************************************************/
1491
1492static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1493 TALLOC_CTX *mem_ctx,
1494 int argc, const char **argv)
1495{
1496 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1497
1498 int i;
1499 int vers = -1;
1500
1501 const char *arch = NULL;
1502
1503 /* parse the command arguements */
1504 if (argc < 2 || argc > 4) {
1505 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1506 return WERR_OK;
1507 }
1508
1509 if (argc >= 3)
1510 arch = argv[2];
1511 if (argc == 4)
1512 vers = atoi (argv[3]);
1513
1514
1515 /* delete the driver for all architectures */
1516 for (i=0; archi_table[i].long_archi; i++) {
1517
1518 if (arch && !strequal( archi_table[i].long_archi, arch))
1519 continue;
1520
1521 if (vers >= 0 && archi_table[i].version != vers)
1522 continue;
1523
1524 /* make the call to remove the driver */
1525 result = rpccli_spoolss_deleteprinterdriverex(
1526 cli, mem_ctx, archi_table[i].long_archi, argv[1], archi_table[i].version);
1527
1528 if ( !W_ERROR_IS_OK(result) )
1529 {
1530 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1531 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1532 argv[1], archi_table[i].long_archi, archi_table[i].version, dos_errstr(result));
1533 }
1534 }
1535 else
1536 {
1537 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1538 archi_table[i].long_archi, archi_table[i].version);
1539 ret = WERR_OK;
1540 }
1541 }
1542
1543 return ret;
1544}
1545
1546
1547/****************************************************************************
1548****************************************************************************/
1549
1550static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1551 TALLOC_CTX *mem_ctx,
1552 int argc, const char **argv)
1553{
1554 WERROR result = WERR_OK;
1555 fstring servername;
1556 int i;
1557
1558 /* parse the command arguements */
1559 if (argc != 2) {
1560 printf ("Usage: %s <driver>\n", argv[0]);
1561 return WERR_OK;
1562 }
1563
1564 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
1565 strupper_m(servername);
1566
1567 /* delete the driver for all architectures */
1568 for (i=0; archi_table[i].long_archi; i++) {
1569 /* make the call to remove the driver */
1570 result = rpccli_spoolss_deleteprinterdriver(
1571 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
1572
1573 if ( !W_ERROR_IS_OK(result) ) {
1574 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1575 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1576 argv[1], archi_table[i].long_archi,
1577 W_ERROR_V(result));
1578 }
1579 } else {
1580 printf ("Driver %s removed for arch [%s].\n", argv[1],
1581 archi_table[i].long_archi);
1582 }
1583 }
1584
1585 return result;
1586}
1587
1588/****************************************************************************
1589****************************************************************************/
1590
1591static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1592 TALLOC_CTX *mem_ctx,
1593 int argc, const char **argv)
1594{
1595 WERROR result;
1596 char *servername = NULL, *environment = NULL;
1597 fstring procdir;
1598
1599 /* parse the command arguements */
1600 if (argc > 2) {
1601 printf ("Usage: %s [environment]\n", argv[0]);
1602 return WERR_OK;
1603 }
1604
1605 if (asprintf(&servername, "\\\\%s", cli->cli->desthost) < 0)
1606 return WERR_NOMEM;
1607 strupper_m(servername);
1608
1609 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
1610 PRINTER_DRIVER_ARCHITECTURE) < 0) {
1611 SAFE_FREE(servername);
1612 return WERR_NOMEM;
1613 }
1614
1615 result = rpccli_spoolss_getprintprocessordirectory(
1616 cli, mem_ctx, servername, environment, procdir);
1617
1618 if (W_ERROR_IS_OK(result))
1619 printf("%s\n", procdir);
1620
1621 SAFE_FREE(servername);
1622 SAFE_FREE(environment);
1623
1624 return result;
1625}
1626
1627/****************************************************************************
1628****************************************************************************/
1629
1630static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1631 int argc, const char **argv)
1632{
1633 POLICY_HND handle;
1634 WERROR werror;
1635 char *servername = NULL, *printername = NULL;
1636 FORM form;
1637 BOOL got_handle = False;
1638
1639 /* Parse the command arguements */
1640
1641 if (argc != 3) {
1642 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1643 return WERR_OK;
1644 }
1645
1646 /* Get a printer handle */
1647
1648 asprintf(&servername, "\\\\%s", cli->cli->desthost);
1649 strupper_m(servername);
1650 asprintf(&printername, "%s\\%s", servername, argv[1]);
1651
1652 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1653 PRINTER_ALL_ACCESS,
1654 servername, cli->user_name, &handle);
1655
1656 if (!W_ERROR_IS_OK(werror))
1657 goto done;
1658
1659 got_handle = True;
1660
1661 /* Dummy up some values for the form data */
1662
1663 form.flags = FORM_USER;
1664 form.size_x = form.size_y = 100;
1665 form.left = 0;
1666 form.top = 10;
1667 form.right = 20;
1668 form.bottom = 30;
1669
1670 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1671
1672 /* Add the form */
1673
1674
1675 werror = rpccli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
1676
1677 done:
1678 if (got_handle)
1679 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
1680
1681 SAFE_FREE(servername);
1682 SAFE_FREE(printername);
1683
1684 return werror;
1685}
1686
1687/****************************************************************************
1688****************************************************************************/
1689
1690static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1691 int argc, const char **argv)
1692{
1693 POLICY_HND handle;
1694 WERROR werror;
1695 char *servername = NULL, *printername = NULL;
1696 FORM form;
1697 BOOL got_handle = False;
1698
1699 /* Parse the command arguements */
1700
1701 if (argc != 3) {
1702 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1703 return WERR_OK;
1704 }
1705
1706 /* Get a printer handle */
1707
1708 asprintf(&servername, "\\\\%s", cli->cli->desthost);
1709 strupper_m(servername);
1710 asprintf(&printername, "%s\\%s", servername, argv[1]);
1711
1712 werror = rpccli_spoolss_open_printer_ex(
1713 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1714 servername, cli->user_name, &handle);
1715
1716 if (!W_ERROR_IS_OK(werror))
1717 goto done;
1718
1719 got_handle = True;
1720
1721 /* Dummy up some values for the form data */
1722
1723 form.flags = FORM_PRINTER;
1724 form.size_x = form.size_y = 100;
1725 form.left = 0;
1726 form.top = 1000;
1727 form.right = 2000;
1728 form.bottom = 3000;
1729
1730 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
1731
1732 /* Set the form */
1733
1734 werror = rpccli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
1735
1736 done:
1737 if (got_handle)
1738 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
1739
1740 SAFE_FREE(servername);
1741 SAFE_FREE(printername);
1742
1743 return werror;
1744}
1745
1746/****************************************************************************
1747****************************************************************************/
1748
1749static const char *get_form_flag(int form_flag)
1750{
1751 switch (form_flag) {
1752 case FORM_USER:
1753 return "FORM_USER";
1754 case FORM_BUILTIN:
1755 return "FORM_BUILTIN";
1756 case FORM_PRINTER:
1757 return "FORM_PRINTER";
1758 default:
1759 return "unknown";
1760 }
1761}
1762
1763/****************************************************************************
1764****************************************************************************/
1765
1766static void display_form(FORM_1 *form)
1767{
1768 fstring form_name = "";
1769
1770 if (form->name.buffer)
1771 rpcstr_pull(form_name, form->name.buffer,
1772 sizeof(form_name), -1, STR_TERMINATE);
1773
1774 printf("%s\n" \
1775 "\tflag: %s (%d)\n" \
1776 "\twidth: %d, length: %d\n" \
1777 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1778 form_name, get_form_flag(form->flag), form->flag,
1779 form->width, form->length,
1780 form->left, form->right,
1781 form->top, form->bottom);
1782}
1783
1784/****************************************************************************
1785****************************************************************************/
1786
1787static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1788 int argc, const char **argv)
1789{
1790 POLICY_HND handle;
1791 WERROR werror;
1792 char *servername = NULL, *printername = NULL;
1793 FORM_1 form;
1794 BOOL got_handle = False;
1795
1796 /* Parse the command arguements */
1797
1798 if (argc != 3) {
1799 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1800 return WERR_OK;
1801 }
1802
1803 /* Get a printer handle */
1804
1805 asprintf(&servername, "\\\\%s", cli->cli->desthost);
1806 strupper_m(servername);
1807 asprintf(&printername, "%s\\%s", servername, argv[1]);
1808
1809 werror = rpccli_spoolss_open_printer_ex(
1810 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1811 servername, cli->user_name, &handle);
1812
1813 if (!W_ERROR_IS_OK(werror))
1814 goto done;
1815
1816 got_handle = True;
1817
1818 /* Get the form */
1819
1820 werror = rpccli_spoolss_getform(cli, mem_ctx, &handle, argv[2], 1, &form);
1821
1822 if (!W_ERROR_IS_OK(werror))
1823 goto done;
1824
1825 display_form(&form);
1826
1827 done:
1828 if (got_handle)
1829 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
1830
1831 SAFE_FREE(servername);
1832 SAFE_FREE(printername);
1833
1834 return werror;
1835}
1836
1837/****************************************************************************
1838****************************************************************************/
1839
1840static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
1841 TALLOC_CTX *mem_ctx, int argc,
1842 const char **argv)
1843{
1844 POLICY_HND handle;
1845 WERROR werror;
1846 char *servername = NULL, *printername = NULL;
1847 BOOL got_handle = False;
1848
1849 /* Parse the command arguements */
1850
1851 if (argc != 3) {
1852 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1853 return WERR_OK;
1854 }
1855
1856 /* Get a printer handle */
1857
1858 asprintf(&servername, "\\\\%s", cli->cli->desthost);
1859 strupper_m(servername);
1860 asprintf(&printername, "%s\\%s", servername, argv[1]);
1861
1862 werror = rpccli_spoolss_open_printer_ex(
1863 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1864 servername, cli->user_name, &handle);
1865
1866 if (!W_ERROR_IS_OK(werror))
1867 goto done;
1868
1869 got_handle = True;
1870
1871 /* Delete the form */
1872
1873 werror = rpccli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
1874
1875 done:
1876 if (got_handle)
1877 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
1878
1879 SAFE_FREE(servername);
1880 SAFE_FREE(printername);
1881
1882 return werror;
1883}
1884
1885/****************************************************************************
1886****************************************************************************/
1887
1888static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
1889 TALLOC_CTX *mem_ctx, int argc,
1890 const char **argv)
1891{
1892 POLICY_HND handle;
1893 WERROR werror;
1894 char *servername = NULL, *printername = NULL;
1895 BOOL got_handle = False;
1896 uint32 num_forms, level = 1, i;
1897 FORM_1 *forms;
1898
1899 /* Parse the command arguements */
1900
1901 if (argc != 2) {
1902 printf ("Usage: %s <printer>\n", argv[0]);
1903 return WERR_OK;
1904 }
1905
1906 /* Get a printer handle */
1907
1908 asprintf(&servername, "\\\\%s", cli->cli->desthost);
1909 strupper_m(servername);
1910 asprintf(&printername, "%s\\%s", servername, argv[1]);
1911
1912 werror = rpccli_spoolss_open_printer_ex(
1913 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
1914 servername, cli->user_name, &handle);
1915
1916 if (!W_ERROR_IS_OK(werror))
1917 goto done;
1918
1919 got_handle = True;
1920
1921 /* Enumerate forms */
1922
1923 werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
1924
1925 if (!W_ERROR_IS_OK(werror))
1926 goto done;
1927
1928 /* Display output */
1929
1930 for (i = 0; i < num_forms; i++) {
1931
1932 display_form(&forms[i]);
1933
1934 }
1935
1936 done:
1937 if (got_handle)
1938 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
1939
1940 SAFE_FREE(servername);
1941 SAFE_FREE(printername);
1942
1943 return werror;
1944}
1945
1946/****************************************************************************
1947****************************************************************************/
1948
1949static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
1950 TALLOC_CTX *mem_ctx,
1951 int argc, const char **argv)
1952{
1953 WERROR result;
1954 fstring servername, printername, user;
1955 POLICY_HND pol;
1956 BOOL opened_hnd = False;
1957 PRINTER_INFO_CTR ctr;
1958 PRINTER_INFO_0 info;
1959 REGISTRY_VALUE value;
1960
1961 /* parse the command arguements */
1962 if (argc < 5) {
1963 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
1964 " <value> <data>\n",
1965 argv[0]);
1966 return WERR_INVALID_PARAM;
1967 }
1968
1969 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
1970 strupper_m(servername);
1971 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
1972 fstrcpy(user, cli->user_name);
1973
1974 value.type = REG_NONE;
1975
1976 if (strequal(argv[2], "string")) {
1977 value.type = REG_SZ;
1978 }
1979
1980 if (strequal(argv[2], "binary")) {
1981 value.type = REG_BINARY;
1982 }
1983
1984 if (strequal(argv[2], "dword")) {
1985 value.type = REG_DWORD;
1986 }
1987
1988 if (strequal(argv[2], "multistring")) {
1989 value.type = REG_MULTI_SZ;
1990 }
1991
1992 if (value.type == REG_NONE) {
1993 printf("Unknown data type: %s\n", argv[2]);
1994 return WERR_INVALID_PARAM;
1995 }
1996
1997 /* get a printer handle */
1998 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1999 MAXIMUM_ALLOWED_ACCESS, servername,
2000 user, &pol);
2001 if (!W_ERROR_IS_OK(result))
2002 goto done;
2003
2004 opened_hnd = True;
2005
2006 ctr.printers_0 = &info;
2007
2008 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
2009
2010 if (!W_ERROR_IS_OK(result))
2011 goto done;
2012
2013 printf("%s\n", current_timestring(True));
2014 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
2015
2016 /* Set the printer data */
2017
2018 fstrcpy(value.valuename, argv[3]);
2019
2020 switch (value.type) {
2021 case REG_SZ: {
2022 UNISTR2 data;
2023 init_unistr2(&data, argv[4], UNI_STR_TERMINATE);
2024 value.size = data.uni_str_len * 2;
2025 if (value.size) {
2026 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer,
2027 value.size);
2028 } else {
2029 value.data_p = NULL;
2030 }
2031 break;
2032 }
2033 case REG_DWORD: {
2034 uint32 data = strtoul(argv[4], NULL, 10);
2035 value.size = sizeof(data);
2036 if (sizeof(data)) {
2037 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data,
2038 sizeof(data));
2039 } else {
2040 value.data_p = NULL;
2041 }
2042 break;
2043 }
2044 case REG_BINARY: {
2045 DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]);
2046 value.data_p = data.data;
2047 value.size = data.length;
2048 break;
2049 }
2050 case REG_MULTI_SZ: {
2051 int i;
2052 size_t len = 0;
2053 char *p;
2054
2055 for (i=4; i<argc; i++) {
2056 if (strcmp(argv[i], "NULL") == 0) {
2057 argv[i] = "";
2058 }
2059 len += strlen(argv[i])+1;
2060 }
2061
2062 value.size = len*2;
2063 value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size);
2064 if (value.data_p == NULL) {
2065 result = WERR_NOMEM;
2066 goto done;
2067 }
2068
2069 p = (char *)value.data_p;
2070 len = value.size;
2071 for (i=4; i<argc; i++) {
2072 size_t l = (strlen(argv[i])+1)*2;
2073 rpcstr_push(p, argv[i], len, STR_TERMINATE);
2074 p += l;
2075 len -= l;
2076 }
2077 SMB_ASSERT(len == 0);
2078 break;
2079 }
2080 default:
2081 printf("Unknown data type: %s\n", argv[2]);
2082 result = WERR_INVALID_PARAM;
2083 goto done;
2084 }
2085
2086 result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
2087
2088 if (!W_ERROR_IS_OK(result)) {
2089 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2090 goto done;
2091 }
2092 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2093
2094 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
2095
2096 if (!W_ERROR_IS_OK(result))
2097 goto done;
2098
2099 printf("%s\n", current_timestring(True));
2100 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
2101
2102done:
2103 /* cleanup */
2104 if (opened_hnd)
2105 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
2106
2107 return result;
2108}
2109
2110/****************************************************************************
2111****************************************************************************/
2112
2113static void display_job_info_1(JOB_INFO_1 *job)
2114{
2115 fstring username = "", document = "", text_status = "";
2116
2117 rpcstr_pull(username, job->username.buffer,
2118 sizeof(username), -1, STR_TERMINATE);
2119
2120 rpcstr_pull(document, job->document.buffer,
2121 sizeof(document), -1, STR_TERMINATE);
2122
2123 rpcstr_pull(text_status, job->text_status.buffer,
2124 sizeof(text_status), -1, STR_TERMINATE);
2125
2126 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
2127 username, document, text_status, job->pagesprinted,
2128 job->totalpages);
2129}
2130
2131/****************************************************************************
2132****************************************************************************/
2133
2134static void display_job_info_2(JOB_INFO_2 *job)
2135{
2136 fstring username = "", document = "", text_status = "";
2137
2138 rpcstr_pull(username, job->username.buffer,
2139 sizeof(username), -1, STR_TERMINATE);
2140
2141 rpcstr_pull(document, job->document.buffer,
2142 sizeof(document), -1, STR_TERMINATE);
2143
2144 rpcstr_pull(text_status, job->text_status.buffer,
2145 sizeof(text_status), -1, STR_TERMINATE);
2146
2147 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
2148 username, document, text_status, job->pagesprinted,
2149 job->totalpages, job->size);
2150}
2151
2152/****************************************************************************
2153****************************************************************************/
2154
2155static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2156 TALLOC_CTX *mem_ctx, int argc,
2157 const char **argv)
2158{
2159 WERROR result;
2160 uint32 level = 1, num_jobs, i;
2161 BOOL got_hnd = False;
2162 pstring printername;
2163 fstring servername, user;
2164 POLICY_HND hnd;
2165 JOB_INFO_CTR ctr;
2166
2167 if (argc < 2 || argc > 3) {
2168 printf("Usage: %s printername [level]\n", argv[0]);
2169 return WERR_OK;
2170 }
2171
2172 if (argc == 3)
2173 level = atoi(argv[2]);
2174
2175 /* Open printer handle */
2176
2177 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
2178 strupper_m(servername);
2179 fstrcpy(user, cli->user_name);
2180 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->cli->desthost);
2181 strupper_m(printername);
2182 pstrcat(printername, argv[1]);
2183
2184 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2185 "", MAXIMUM_ALLOWED_ACCESS,
2186 servername, user, &hnd);
2187
2188 if (!W_ERROR_IS_OK(result))
2189 goto done;
2190
2191 got_hnd = True;
2192
2193 /* Enumerate ports */
2194
2195 result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
2196 &num_jobs, &ctr);
2197
2198 if (!W_ERROR_IS_OK(result))
2199 goto done;
2200
2201 for (i = 0; i < num_jobs; i++) {
2202 switch(level) {
2203 case 1:
2204 display_job_info_1(&ctr.job.job_info_1[i]);
2205 break;
2206 case 2:
2207 display_job_info_2(&ctr.job.job_info_2[i]);
2208 break;
2209 default:
2210 d_printf("unknown info level %d\n", level);
2211 break;
2212 }
2213 }
2214
2215done:
2216 if (got_hnd)
2217 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
2218
2219 return result;
2220}
2221
2222/****************************************************************************
2223****************************************************************************/
2224
2225static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
2226 TALLOC_CTX *mem_ctx, int argc,
2227 const char **argv)
2228{
2229 WERROR result;
2230 uint32 i=0, val_needed, data_needed;
2231 BOOL got_hnd = False;
2232 pstring printername;
2233 fstring servername, user;
2234 POLICY_HND hnd;
2235
2236 if (argc != 2) {
2237 printf("Usage: %s printername\n", argv[0]);
2238 return WERR_OK;
2239 }
2240
2241 /* Open printer handle */
2242
2243 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
2244 strupper_m(servername);
2245 fstrcpy(user, cli->user_name);
2246 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
2247 strupper_m(printername);
2248 pstrcat(printername, argv[1]);
2249
2250 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2251 "", MAXIMUM_ALLOWED_ACCESS,
2252 servername, user, &hnd);
2253
2254 if (!W_ERROR_IS_OK(result))
2255 goto done;
2256
2257 got_hnd = True;
2258
2259 /* Enumerate data */
2260
2261 result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2262 &val_needed, &data_needed,
2263 NULL);
2264 while (W_ERROR_IS_OK(result)) {
2265 REGISTRY_VALUE value;
2266 result = rpccli_spoolss_enumprinterdata(
2267 cli, mem_ctx, &hnd, i++, val_needed,
2268 data_needed, 0, 0, &value);
2269 if (W_ERROR_IS_OK(result))
2270 display_reg_value(value);
2271 }
2272 if (W_ERROR_V(result) == ERRnomoreitems)
2273 result = W_ERROR(ERRsuccess);
2274
2275done:
2276 if (got_hnd)
2277 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
2278
2279 return result;
2280}
2281
2282/****************************************************************************
2283****************************************************************************/
2284
2285static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2286 TALLOC_CTX *mem_ctx, int argc,
2287 const char **argv)
2288{
2289 WERROR result;
2290 uint32 i;
2291 BOOL got_hnd = False;
2292 pstring printername;
2293 fstring servername, user;
2294 const char *keyname = NULL;
2295 POLICY_HND hnd;
2296 REGVAL_CTR *ctr = NULL;
2297
2298 if (argc != 3) {
2299 printf("Usage: %s printername <keyname>\n", argv[0]);
2300 return WERR_OK;
2301 }
2302
2303 keyname = argv[2];
2304
2305 /* Open printer handle */
2306
2307 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
2308 strupper_m(servername);
2309 fstrcpy(user, cli->user_name);
2310 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
2311 strupper_m(printername);
2312 pstrcat(printername, argv[1]);
2313
2314 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2315 "", MAXIMUM_ALLOWED_ACCESS,
2316 servername, user, &hnd);
2317
2318 if (!W_ERROR_IS_OK(result))
2319 goto done;
2320
2321 got_hnd = True;
2322
2323 /* Enumerate subkeys */
2324
2325 if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
2326 return WERR_NOMEM;
2327
2328 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
2329
2330 if (!W_ERROR_IS_OK(result))
2331 goto done;
2332
2333 for (i=0; i < ctr->num_values; i++) {
2334 display_reg_value(*(ctr->values[i]));
2335 }
2336
2337 TALLOC_FREE( ctr );
2338
2339done:
2340 if (got_hnd)
2341 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
2342
2343 return result;
2344}
2345
2346/****************************************************************************
2347****************************************************************************/
2348
2349static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
2350 TALLOC_CTX *mem_ctx, int argc,
2351 const char **argv)
2352{
2353 WERROR result;
2354 BOOL got_hnd = False;
2355 pstring printername;
2356 fstring servername, user;
2357 const char *keyname = NULL;
2358 POLICY_HND hnd;
2359 uint16 *keylist = NULL, *curkey;
2360
2361 if (argc < 2 || argc > 3) {
2362 printf("Usage: %s printername [keyname]\n", argv[0]);
2363 return WERR_OK;
2364 }
2365
2366 if (argc == 3)
2367 keyname = argv[2];
2368 else
2369 keyname = "";
2370
2371 /* Open printer handle */
2372
2373 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
2374 strupper_m(servername);
2375 fstrcpy(user, cli->user_name);
2376 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
2377 strupper_m(printername);
2378 pstrcat(printername, argv[1]);
2379
2380 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
2381 "", MAXIMUM_ALLOWED_ACCESS,
2382 servername, user, &hnd);
2383
2384 if (!W_ERROR_IS_OK(result))
2385 goto done;
2386
2387 got_hnd = True;
2388
2389 /* Enumerate subkeys */
2390
2391 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
2392
2393 if (!W_ERROR_IS_OK(result))
2394 goto done;
2395
2396 curkey = keylist;
2397 while (*curkey != 0) {
2398 pstring subkey;
2399 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
2400 STR_TERMINATE);
2401 printf("%s\n", subkey);
2402 curkey += strlen(subkey) + 1;
2403 }
2404
2405done:
2406
2407 SAFE_FREE(keylist);
2408
2409 if (got_hnd)
2410 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
2411
2412 return result;
2413}
2414
2415/****************************************************************************
2416****************************************************************************/
2417
2418static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2419 TALLOC_CTX *mem_ctx, int argc,
2420 const char **argv)
2421{
2422 fstring servername, printername;
2423 POLICY_HND hnd;
2424 BOOL got_hnd = False;
2425 WERROR result;
2426 SPOOL_NOTIFY_OPTION option;
2427
2428 if (argc != 2) {
2429 printf("Usage: %s printername\n", argv[0]);
2430 result = WERR_OK;
2431 goto done;
2432 }
2433
2434 /* Open printer */
2435
2436 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->cli->desthost);
2437 strupper_m(servername);
2438
2439 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->cli->desthost,
2440 argv[1]);
2441 strupper_m(printername);
2442
2443 result = rpccli_spoolss_open_printer_ex(
2444 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
2445 servername, cli->user_name, &hnd);
2446
2447 if (!W_ERROR_IS_OK(result)) {
2448 printf("Error opening %s\n", argv[1]);
2449 goto done;
2450 }
2451
2452 got_hnd = True;
2453
2454 /* Create spool options */
2455
2456 ZERO_STRUCT(option);
2457
2458 option.version = 2;
2459 option.option_type_ptr = 1;
2460 option.count = option.ctr.count = 2;
2461
2462 option.ctr.type = TALLOC_ARRAY(mem_ctx, SPOOL_NOTIFY_OPTION_TYPE, 2);
2463 if (option.ctr.type == NULL) {
2464 result = WERR_NOMEM;
2465 goto done;
2466 }
2467
2468 ZERO_STRUCT(option.ctr.type[0]);
2469 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
2470 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
2471 option.ctr.type[0].fields_ptr = 1;
2472 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2473
2474 ZERO_STRUCT(option.ctr.type[1]);
2475 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
2476 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
2477 option.ctr.type[1].fields_ptr = 1;
2478 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2479
2480 /* Send rffpcnex */
2481
2482 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
2483 strupper_m(servername);
2484
2485 result = rpccli_spoolss_rffpcnex(
2486 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
2487
2488 if (!W_ERROR_IS_OK(result)) {
2489 printf("Error rffpcnex %s\n", argv[1]);
2490 goto done;
2491 }
2492
2493done:
2494 if (got_hnd)
2495 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
2496
2497 return result;
2498}
2499
2500/****************************************************************************
2501****************************************************************************/
2502
2503static BOOL compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2504 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2505{
2506 PRINTER_INFO_CTR ctr1, ctr2;
2507 WERROR werror;
2508 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
2509
2510 printf("Retrieving printer propertiesfor %s...", cli1->cli->desthost);
2511 werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1);
2512 if ( !W_ERROR_IS_OK(werror) ) {
2513 printf("failed (%s)\n", dos_errstr(werror));
2514 talloc_destroy(mem_ctx);
2515 return False;
2516 }
2517 printf("ok\n");
2518
2519 printf("Retrieving printer properties for %s...", cli2->cli->desthost);
2520 werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2);
2521 if ( !W_ERROR_IS_OK(werror) ) {
2522 printf("failed (%s)\n", dos_errstr(werror));
2523 talloc_destroy(mem_ctx);
2524 return False;
2525 }
2526 printf("ok\n");
2527
2528 talloc_destroy(mem_ctx);
2529
2530 return True;
2531}
2532
2533/****************************************************************************
2534****************************************************************************/
2535
2536static BOOL compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2537 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2538{
2539 PRINTER_INFO_CTR ctr1, ctr2;
2540 WERROR werror;
2541 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
2542 SEC_DESC *sd1, *sd2;
2543 BOOL result = True;
2544
2545
2546 printf("Retreiving printer security for %s...", cli1->cli->desthost);
2547 werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1);
2548 if ( !W_ERROR_IS_OK(werror) ) {
2549 printf("failed (%s)\n", dos_errstr(werror));
2550 result = False;
2551 goto done;
2552 }
2553 printf("ok\n");
2554
2555 printf("Retrieving printer security for %s...", cli2->cli->desthost);
2556 werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2);
2557 if ( !W_ERROR_IS_OK(werror) ) {
2558 printf("failed (%s)\n", dos_errstr(werror));
2559 result = False;
2560 goto done;
2561 }
2562 printf("ok\n");
2563
2564
2565 printf("++ ");
2566
2567 if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) {
2568 printf("NULL PRINTER_INFO_3!\n");
2569 result = False;
2570 goto done;
2571 }
2572
2573 sd1 = ctr1.printers_3->secdesc;
2574 sd2 = ctr2.printers_3->secdesc;
2575
2576 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
2577 printf("NULL secdesc!\n");
2578 result = False;
2579 goto done;
2580 }
2581
2582 if (!sec_desc_equal( sd1, sd2 ) ) {
2583 printf("Security Descriptors *not* equal!\n");
2584 result = False;
2585 goto done;
2586 }
2587
2588 printf("Security descriptors match\n");
2589
2590done:
2591 talloc_destroy(mem_ctx);
2592 return result;
2593}
2594
2595
2596/****************************************************************************
2597****************************************************************************/
2598
2599static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
2600 TALLOC_CTX *mem_ctx, int argc,
2601 const char **argv)
2602{
2603 fstring printername, servername1, servername2;
2604 pstring printername_path;
2605 struct cli_state *cli_server1 = cli->cli;
2606 struct cli_state *cli_server2 = NULL;
2607 struct rpc_pipe_client *cli2 = NULL;
2608 POLICY_HND hPrinter1, hPrinter2;
2609 NTSTATUS nt_status;
2610 WERROR werror;
2611
2612 if ( argc != 3 ) {
2613 printf("Usage: %s <printer> <server>\n", argv[0]);
2614 return WERR_OK;
2615 }
2616
2617 fstrcpy( printername, argv[1] );
2618
2619 fstr_sprintf( servername1, cli->cli->desthost );
2620 fstrcpy( servername2, argv[2] );
2621 strupper_m( servername1 );
2622 strupper_m( servername2 );
2623
2624
2625 /* first get the connection to the remote server */
2626
2627 nt_status = cli_full_connection(&cli_server2, global_myname(), servername2,
2628 NULL, 0,
2629 "IPC$", "IPC",
2630 cmdline_auth_info.username,
2631 lp_workgroup(),
2632 cmdline_auth_info.password,
2633 cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
2634 cmdline_auth_info.signing_state, NULL);
2635
2636 if ( !NT_STATUS_IS_OK(nt_status) )
2637 return WERR_GENERAL_FAILURE;
2638
2639 cli2 = cli_rpc_pipe_open_noauth(cli_server2, PI_SPOOLSS, &nt_status);
2640 if (!cli2) {
2641 printf("failed to open spoolss pipe on server %s (%s)\n",
2642 servername2, nt_errstr(nt_status));
2643 return WERR_GENERAL_FAILURE;
2644 }
2645
2646 /* now open up both printers */
2647
2648 pstr_sprintf( printername_path, "\\\\%s\\%s", servername1, printername );
2649 printf("Opening %s...", printername_path);
2650 werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, printername_path,
2651 "", PRINTER_ALL_ACCESS, servername1, cli_server1->user_name, &hPrinter1);
2652 if ( !W_ERROR_IS_OK(werror) ) {
2653 printf("failed (%s)\n", dos_errstr(werror));
2654 goto done;
2655 }
2656 printf("ok\n");
2657
2658 pstr_sprintf( printername_path, "\\\\%s\\%s", servername2, printername );
2659 printf("Opening %s...", printername_path);
2660 werror = rpccli_spoolss_open_printer_ex( cli2, mem_ctx, printername_path,
2661 "", PRINTER_ALL_ACCESS, servername2, cli_server2->user_name, &hPrinter2 );
2662 if ( !W_ERROR_IS_OK(werror) ) {
2663 printf("failed (%s)\n", dos_errstr(werror));
2664 goto done;
2665 }
2666 printf("ok\n");
2667
2668
2669 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
2670 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
2671#if 0
2672 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
2673#endif
2674
2675
2676done:
2677 /* cleanup */
2678
2679 printf("Closing printers...");
2680 rpccli_spoolss_close_printer( cli, mem_ctx, &hPrinter1 );
2681 rpccli_spoolss_close_printer( cli2, mem_ctx, &hPrinter2 );
2682 printf("ok\n");
2683
2684 /* close the second remote connection */
2685
2686 cli_shutdown( cli_server2 );
2687
2688 return WERR_OK;
2689}
2690
2691/* List of commands exported by this module */
2692struct cmd_set spoolss_commands[] = {
2693
2694 { "SPOOLSS" },
2695
2696 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, NULL, "Add a print driver", "" },
2697 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, NULL, "Add a printer", "" },
2698 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, NULL, "Delete a printer driver", "" },
2699 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, PI_SPOOLSS, NULL, "Delete a printer driver with files", "" },
2700 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, NULL, "Enumerate printer data", "" },
2701 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, NULL, "Enumerate printer data for a key", "" },
2702 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, NULL, "Enumerate printer keys", "" },
2703 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, NULL, "Enumerate print jobs", "" },
2704 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, NULL, "Enumerate printer ports", "" },
2705 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, NULL, "Enumerate installed printer drivers", "" },
2706 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, NULL, "Enumerate printers", "" },
2707 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, NULL, "Get print driver data", "" },
2708 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, NULL, "Get printer driver data with keyname", ""},
2709 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, NULL, "Get print driver information", "" },
2710 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, NULL, "Get print driver upload directory", "" },
2711 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, NULL, "Get printer info", "" },
2712 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, NULL, "Open printer handle", "" },
2713 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, NULL, "Set printer driver", "" },
2714 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, NULL, "Get print processor directory", "" },
2715 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, NULL, "Add form", "" },
2716 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, NULL, "Set form", "" },
2717 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, NULL, "Get form", "" },
2718 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, NULL, "Delete form", "" },
2719 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, NULL, "Enumerate forms", "" },
2720 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, NULL, "Set printer comment", "" },
2721 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, PI_SPOOLSS, NULL, "Set printername", "" },
2722 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, NULL, "Set REG_SZ printer data", "" },
2723 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, NULL, "Rffpcnex test", "" },
2724 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, PI_SPOOLSS, NULL, "Printer comparison test", "" },
2725
2726 { NULL }
2727};
Note: See TracBrowser for help on using the repository browser.