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}; 2728