00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026 #include "rpcclient.h"
00027
00028 struct table_node {
00029 const char *long_archi;
00030 const char *short_archi;
00031 int version;
00032 };
00033
00034
00035
00036
00037
00038
00039
00040
00041 static const struct table_node archi_table[]= {
00042
00043 {"Windows 4.0", "WIN40", 0 },
00044 {"Windows NT x86", "W32X86", 2 },
00045 {"Windows NT x86", "W32X86", 3 },
00046 {"Windows NT R4000", "W32MIPS", 2 },
00047 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
00048 {"Windows NT PowerPC", "W32PPC", 2 },
00049 {"Windows IA64", "IA64", 3 },
00050 {"Windows x64", "x64", 3 },
00051 {NULL, "", -1 }
00052 };
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
00069 {
00070 int i=-1;
00071
00072 DEBUG(107,("Getting architecture dependant directory\n"));
00073 do {
00074 i++;
00075 } while ( (archi_table[i].long_archi!=NULL ) &&
00076 StrCaseCmp(long_archi, archi_table[i].long_archi) );
00077
00078 if (archi_table[i].long_archi==NULL) {
00079 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
00080 return NULL;
00081 }
00082
00083
00084
00085
00086 DEBUGADD(108,("index: [%d]\n", i));
00087 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
00088 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
00089
00090 return archi_table[i].short_archi;
00091 }
00092
00093
00094
00095
00096 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
00097 TALLOC_CTX *mem_ctx,
00098 int argc, const char **argv)
00099 {
00100 WERROR werror;
00101 fstring printername;
00102 fstring servername, user;
00103 POLICY_HND hnd;
00104
00105 if (argc != 2) {
00106 printf("Usage: %s <printername>\n", argv[0]);
00107 return WERR_OK;
00108 }
00109
00110 if (!cli)
00111 return WERR_GENERAL_FAILURE;
00112
00113 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00114 strupper_m(servername);
00115 fstrcpy(user, cli->user_name);
00116 fstrcpy(printername, argv[1]);
00117
00118
00119
00120 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
00121 "", PRINTER_ALL_ACCESS,
00122 servername, user, &hnd);
00123
00124 if (W_ERROR_IS_OK(werror)) {
00125 printf("Printer %s opened successfully\n", printername);
00126 werror = rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
00127
00128 if (!W_ERROR_IS_OK(werror)) {
00129 printf("Error closing printer handle! (%s)\n",
00130 get_dos_error_msg(werror));
00131 }
00132 }
00133
00134 return werror;
00135 }
00136
00137
00138
00139
00140
00141 static void display_print_info_0(PRINTER_INFO_0 *i0)
00142 {
00143 fstring name = "";
00144 fstring servername = "";
00145
00146 if (!i0)
00147 return;
00148
00149 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
00150
00151 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
00152
00153 printf("\tprintername:[%s]\n", name);
00154 printf("\tservername:[%s]\n", servername);
00155 printf("\tcjobs:[0x%x]\n", i0->cjobs);
00156 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
00157
00158 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
00159 i0->day, i0->dayofweek);
00160 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
00161 i0->second, i0->milliseconds);
00162
00163 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
00164 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
00165
00166 printf("\tmajorversion:[0x%x]\n", i0->major_version);
00167 printf("\tbuildversion:[0x%x]\n", i0->build_version);
00168
00169 printf("\tunknown7:[0x%x]\n", i0->unknown7);
00170 printf("\tunknown8:[0x%x]\n", i0->unknown8);
00171 printf("\tunknown9:[0x%x]\n", i0->unknown9);
00172 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
00173 printf("\tunknown11:[0x%x]\n", i0->unknown11);
00174 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
00175 printf("\tunknown13:[0x%x]\n", i0->unknown13);
00176 printf("\tunknown14:[0x%x]\n", i0->unknown14);
00177 printf("\tunknown15:[0x%x]\n", i0->unknown15);
00178 printf("\tunknown16:[0x%x]\n", i0->unknown16);
00179 printf("\tchange_id:[0x%x]\n", i0->change_id);
00180 printf("\tunknown18:[0x%x]\n", i0->unknown18);
00181 printf("\tstatus:[0x%x]\n", i0->status);
00182 printf("\tunknown20:[0x%x]\n", i0->unknown20);
00183 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
00184 printf("\tunknown22:[0x%x]\n", i0->unknown22);
00185 printf("\tunknown23:[0x%x]\n", i0->unknown23);
00186 printf("\tunknown24:[0x%x]\n", i0->unknown24);
00187 printf("\tunknown25:[0x%x]\n", i0->unknown25);
00188 printf("\tunknown26:[0x%x]\n", i0->unknown26);
00189 printf("\tunknown27:[0x%x]\n", i0->unknown27);
00190 printf("\tunknown28:[0x%x]\n", i0->unknown28);
00191 printf("\tunknown29:[0x%x]\n", i0->unknown29);
00192
00193 printf("\n");
00194 }
00195
00196
00197
00198
00199 static void display_print_info_1(PRINTER_INFO_1 *i1)
00200 {
00201 fstring desc = "";
00202 fstring name = "";
00203 fstring comm = "";
00204
00205 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
00206 STR_TERMINATE);
00207
00208 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
00209 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
00210
00211 printf("\tflags:[0x%x]\n", i1->flags);
00212 printf("\tname:[%s]\n", name);
00213 printf("\tdescription:[%s]\n", desc);
00214 printf("\tcomment:[%s]\n", comm);
00215
00216 printf("\n");
00217 }
00218
00219
00220
00221
00222 static void display_print_info_2(PRINTER_INFO_2 *i2)
00223 {
00224 fstring servername = "";
00225 fstring printername = "";
00226 fstring sharename = "";
00227 fstring portname = "";
00228 fstring drivername = "";
00229 fstring comment = "";
00230 fstring location = "";
00231 fstring sepfile = "";
00232 fstring printprocessor = "";
00233 fstring datatype = "";
00234 fstring parameters = "";
00235
00236 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
00237 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
00238 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
00239 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
00240 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
00241 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
00242 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
00243 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
00244 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
00245 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
00246 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
00247
00248 printf("\tservername:[%s]\n", servername);
00249 printf("\tprintername:[%s]\n", printername);
00250 printf("\tsharename:[%s]\n", sharename);
00251 printf("\tportname:[%s]\n", portname);
00252 printf("\tdrivername:[%s]\n", drivername);
00253 printf("\tcomment:[%s]\n", comment);
00254 printf("\tlocation:[%s]\n", location);
00255 printf("\tsepfile:[%s]\n", sepfile);
00256 printf("\tprintprocessor:[%s]\n", printprocessor);
00257 printf("\tdatatype:[%s]\n", datatype);
00258 printf("\tparameters:[%s]\n", parameters);
00259 printf("\tattributes:[0x%x]\n", i2->attributes);
00260 printf("\tpriority:[0x%x]\n", i2->priority);
00261 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
00262 printf("\tstarttime:[0x%x]\n", i2->starttime);
00263 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
00264 printf("\tstatus:[0x%x]\n", i2->status);
00265 printf("\tcjobs:[0x%x]\n", i2->cjobs);
00266 printf("\taverageppm:[0x%x]\n", i2->averageppm);
00267
00268 if (i2->secdesc)
00269 display_sec_desc(i2->secdesc);
00270
00271 printf("\n");
00272 }
00273
00274
00275
00276
00277 static void display_print_info_3(PRINTER_INFO_3 *i3)
00278 {
00279 display_sec_desc(i3->secdesc);
00280
00281 printf("\n");
00282 }
00283
00284
00285
00286
00287 static void display_print_info_7(PRINTER_INFO_7 *i7)
00288 {
00289 fstring guid = "";
00290 rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE);
00291 printf("\tguid:[%s]\n", guid);
00292 printf("\taction:[0x%x]\n", i7->action);
00293 }
00294
00295
00296
00297
00298
00299 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
00300 TALLOC_CTX *mem_ctx,
00301 int argc, const char **argv)
00302 {
00303 WERROR result;
00304 uint32 info_level = 1;
00305 PRINTER_INFO_CTR ctr;
00306 uint32 i = 0, num_printers;
00307 fstring name;
00308
00309 if (argc > 3)
00310 {
00311 printf("Usage: %s [level] [name]\n", argv[0]);
00312 return WERR_OK;
00313 }
00314
00315 if (argc >= 2)
00316 info_level = atoi(argv[1]);
00317
00318 if (argc == 3)
00319 fstrcpy(name, argv[2]);
00320 else {
00321 slprintf(name, sizeof(name)-1, "\\\\%s", cli->cli->desthost);
00322 strupper_m(name);
00323 }
00324
00325 ZERO_STRUCT(ctr);
00326
00327 result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
00328 info_level, &num_printers, &ctr);
00329
00330 if (W_ERROR_IS_OK(result)) {
00331
00332 if (!num_printers) {
00333 printf ("No printers returned.\n");
00334 goto done;
00335 }
00336
00337 for (i = 0; i < num_printers; i++) {
00338 switch(info_level) {
00339 case 0:
00340 display_print_info_0(&ctr.printers_0[i]);
00341 break;
00342 case 1:
00343 display_print_info_1(&ctr.printers_1[i]);
00344 break;
00345 case 2:
00346 display_print_info_2(&ctr.printers_2[i]);
00347 break;
00348 case 3:
00349 display_print_info_3(&ctr.printers_3[i]);
00350 break;
00351 default:
00352 printf("unknown info level %d\n", info_level);
00353 goto done;
00354 }
00355 }
00356 }
00357 done:
00358
00359 return result;
00360 }
00361
00362
00363
00364
00365 static void display_port_info_1(PORT_INFO_1 *i1)
00366 {
00367 fstring buffer;
00368
00369 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
00370 printf("\tPort Name:\t[%s]\n", buffer);
00371 }
00372
00373
00374
00375
00376 static void display_port_info_2(PORT_INFO_2 *i2)
00377 {
00378 fstring buffer;
00379
00380 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
00381 printf("\tPort Name:\t[%s]\n", buffer);
00382 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
00383
00384 printf("\tMonitor Name:\t[%s]\n", buffer);
00385 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
00386
00387 printf("\tDescription:\t[%s]\n", buffer);
00388 printf("\tPort Type:\t" );
00389 if ( i2->port_type ) {
00390 int comma = 0;
00391 printf( "[" );
00392 if ( i2->port_type & PORT_TYPE_READ ) {
00393 printf( "Read" );
00394 comma = 1;
00395 }
00396 if ( i2->port_type & PORT_TYPE_WRITE ) {
00397 printf( "%sWrite", comma ? ", " : "" );
00398 comma = 1;
00399 }
00400
00401
00402 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
00403 printf( "%sRedirected", comma ? ", " : "" );
00404 comma = 1;
00405 }
00406 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
00407 printf( "%sNet-Attached", comma ? ", " : "" );
00408 }
00409 printf( "]\n" );
00410 } else {
00411 printf( "[Unset]\n" );
00412 }
00413 printf("\tReserved:\t[%d]\n", i2->reserved);
00414 printf("\n");
00415 }
00416
00417
00418
00419
00420 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
00421 TALLOC_CTX *mem_ctx, int argc,
00422 const char **argv)
00423 {
00424 WERROR result;
00425 uint32 info_level = 1;
00426 PORT_INFO_CTR ctr;
00427 uint32 returned;
00428
00429 if (argc > 2) {
00430 printf("Usage: %s [level]\n", argv[0]);
00431 return WERR_OK;
00432 }
00433
00434 if (argc == 2)
00435 info_level = atoi(argv[1]);
00436
00437
00438
00439 ZERO_STRUCT(ctr);
00440
00441 result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
00442
00443 if (W_ERROR_IS_OK(result)) {
00444 int i;
00445
00446 for (i = 0; i < returned; i++) {
00447 switch (info_level) {
00448 case 1:
00449 display_port_info_1(&ctr.port.info_1[i]);
00450 break;
00451 case 2:
00452 display_port_info_2(&ctr.port.info_2[i]);
00453 break;
00454 default:
00455 printf("unknown info level %d\n", info_level);
00456 break;
00457 }
00458 }
00459 }
00460
00461 return result;
00462 }
00463
00464
00465
00466
00467 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
00468 TALLOC_CTX *mem_ctx,
00469 int argc, const char **argv)
00470 {
00471 POLICY_HND pol;
00472 WERROR result;
00473 uint32 info_level = 2;
00474 BOOL opened_hnd = False;
00475 PRINTER_INFO_CTR ctr;
00476 fstring printername,
00477 servername,
00478 user,
00479 comment;
00480
00481 if (argc == 1 || argc > 3) {
00482 printf("Usage: %s printername comment\n", argv[0]);
00483
00484 return WERR_OK;
00485 }
00486
00487
00488 if (argc == 3) {
00489 fstrcpy(comment, argv[2]);
00490 }
00491
00492 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00493 strupper_m(servername);
00494 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
00495 fstrcpy(user, cli->user_name);
00496
00497
00498 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
00499 PRINTER_ALL_ACCESS, servername,
00500 user, &pol);
00501
00502 if (!W_ERROR_IS_OK(result))
00503 goto done;
00504
00505 opened_hnd = True;
00506
00507
00508 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
00509
00510 if (!W_ERROR_IS_OK(result))
00511 goto done;
00512
00513
00514
00515 init_unistr(&ctr.printers_2->comment, comment);
00516 ctr.printers_2->devmode = NULL;
00517 ctr.printers_2->secdesc = NULL;
00518
00519 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
00520 if (W_ERROR_IS_OK(result))
00521 printf("Success in setting comment.\n");
00522
00523 done:
00524 if (opened_hnd)
00525 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
00526
00527 return result;
00528 }
00529
00530
00531
00532
00533 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
00534 TALLOC_CTX *mem_ctx,
00535 int argc, const char **argv)
00536 {
00537 POLICY_HND pol;
00538 WERROR result;
00539 uint32 info_level = 2;
00540 BOOL opened_hnd = False;
00541 PRINTER_INFO_CTR ctr;
00542 fstring printername,
00543 servername,
00544 user,
00545 new_printername;
00546
00547 if (argc == 1 || argc > 3) {
00548 printf("Usage: %s printername new_printername\n", argv[0]);
00549
00550 return WERR_OK;
00551 }
00552
00553
00554 if (argc == 3) {
00555 fstrcpy(new_printername, argv[2]);
00556 }
00557
00558 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00559 strupper_m(servername);
00560 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
00561 fstrcpy(user, cli->user_name);
00562
00563
00564 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
00565 PRINTER_ALL_ACCESS, servername,
00566 user, &pol);
00567
00568 if (!W_ERROR_IS_OK(result))
00569 goto done;
00570
00571 opened_hnd = True;
00572
00573
00574 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
00575
00576 if (!W_ERROR_IS_OK(result))
00577 goto done;
00578
00579
00580 init_unistr(&ctr.printers_2->printername, new_printername);
00581 ctr.printers_2->devmode = NULL;
00582 ctr.printers_2->secdesc = NULL;
00583
00584 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
00585 if (W_ERROR_IS_OK(result))
00586 printf("Success in setting printername.\n");
00587
00588 done:
00589 if (opened_hnd)
00590 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
00591
00592 return result;
00593 }
00594
00595
00596
00597
00598 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
00599 TALLOC_CTX *mem_ctx,
00600 int argc, const char **argv)
00601 {
00602 POLICY_HND pol;
00603 WERROR result;
00604 uint32 info_level = 1;
00605 BOOL opened_hnd = False;
00606 PRINTER_INFO_CTR ctr;
00607 fstring printername,
00608 servername,
00609 user;
00610
00611 if (argc == 1 || argc > 3) {
00612 printf("Usage: %s <printername> [level]\n", argv[0]);
00613 return WERR_OK;
00614 }
00615
00616
00617 if (argc == 3) {
00618 info_level = atoi(argv[2]);
00619 }
00620
00621 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00622 strupper_m(servername);
00623 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
00624 fstrcpy(user, cli->user_name);
00625
00626
00627
00628 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
00629 "", MAXIMUM_ALLOWED_ACCESS,
00630 servername, user, &pol);
00631
00632 if (!W_ERROR_IS_OK(result))
00633 goto done;
00634
00635 opened_hnd = True;
00636
00637
00638
00639 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
00640
00641 if (!W_ERROR_IS_OK(result))
00642 goto done;
00643
00644
00645
00646 switch (info_level) {
00647 case 0:
00648 display_print_info_0(ctr.printers_0);
00649 break;
00650 case 1:
00651 display_print_info_1(ctr.printers_1);
00652 break;
00653 case 2:
00654 display_print_info_2(ctr.printers_2);
00655 break;
00656 case 3:
00657 display_print_info_3(ctr.printers_3);
00658 break;
00659 case 7:
00660 display_print_info_7(ctr.printers_7);
00661 break;
00662 default:
00663 printf("unknown info level %d\n", info_level);
00664 break;
00665 }
00666
00667 done:
00668 if (opened_hnd)
00669 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
00670
00671 return result;
00672 }
00673
00674
00675
00676
00677 static void display_reg_value(REGISTRY_VALUE value)
00678 {
00679 pstring text;
00680
00681 switch(value.type) {
00682 case REG_DWORD:
00683 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
00684 *((uint32 *) value.data_p));
00685 break;
00686 case REG_SZ:
00687 rpcstr_pull(text, value.data_p, sizeof(text), value.size,
00688 STR_TERMINATE);
00689 printf("%s: REG_SZ: %s\n", value.valuename, text);
00690 break;
00691 case REG_BINARY: {
00692 char *hex = hex_encode(NULL, value.data_p, value.size);
00693 size_t i, len;
00694 printf("%s: REG_BINARY:", value.valuename);
00695 len = strlen(hex);
00696 for (i=0; i<len; i++) {
00697 if (hex[i] == '\0') {
00698 break;
00699 }
00700 if (i%40 == 0) {
00701 putchar('\n');
00702 }
00703 putchar(hex[i]);
00704 }
00705 TALLOC_FREE(hex);
00706 putchar('\n');
00707 break;
00708 }
00709 case REG_MULTI_SZ: {
00710 uint16 *curstr = (uint16 *) value.data_p;
00711 uint8 *start = value.data_p;
00712 printf("%s: REG_MULTI_SZ:\n", value.valuename);
00713 while (((uint8 *) curstr < start + value.size)) {
00714 rpcstr_pull(text, curstr, sizeof(text), -1,
00715 STR_TERMINATE);
00716 printf(" %s\n", *text != 0 ? text : "NULL");
00717 curstr += strlen(text) + 1;
00718 }
00719 }
00720 break;
00721 default:
00722 printf("%s: unknown type %d\n", value.valuename, value.type);
00723 }
00724
00725 }
00726
00727
00728
00729
00730 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
00731 TALLOC_CTX *mem_ctx,
00732 int argc, const char **argv)
00733 {
00734 POLICY_HND pol;
00735 WERROR result;
00736 BOOL opened_hnd = False;
00737 fstring printername,
00738 servername,
00739 user;
00740 const char *valuename;
00741 REGISTRY_VALUE value;
00742
00743 if (argc != 3) {
00744 printf("Usage: %s <printername> <valuename>\n", argv[0]);
00745 printf("<printername> of . queries print server\n");
00746 return WERR_OK;
00747 }
00748 valuename = argv[2];
00749
00750
00751
00752 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00753 strupper_m(servername);
00754 if (strncmp(argv[1], ".", sizeof(".")) == 0)
00755 fstrcpy(printername, servername);
00756 else
00757 slprintf(printername, sizeof(servername)-1, "%s\\%s",
00758 servername, argv[1]);
00759 fstrcpy(user, cli->user_name);
00760
00761
00762
00763 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
00764 "", MAXIMUM_ALLOWED_ACCESS,
00765 servername, user, &pol);
00766
00767 if (!W_ERROR_IS_OK(result))
00768 goto done;
00769
00770 opened_hnd = True;
00771
00772
00773
00774 result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
00775
00776 if (!W_ERROR_IS_OK(result))
00777 goto done;
00778
00779
00780
00781 fstrcpy(value.valuename, valuename);
00782 display_reg_value(value);
00783
00784
00785 done:
00786 if (opened_hnd)
00787 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
00788
00789 return result;
00790 }
00791
00792
00793
00794
00795 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
00796 TALLOC_CTX *mem_ctx,
00797 int argc, const char **argv)
00798 {
00799 POLICY_HND pol;
00800 WERROR result;
00801 BOOL opened_hnd = False;
00802 fstring printername,
00803 servername,
00804 user;
00805 const char *valuename, *keyname;
00806 REGISTRY_VALUE value;
00807
00808 if (argc != 4) {
00809 printf("Usage: %s <printername> <keyname> <valuename>\n",
00810 argv[0]);
00811 printf("<printername> of . queries print server\n");
00812 return WERR_OK;
00813 }
00814 valuename = argv[3];
00815 keyname = argv[2];
00816
00817
00818
00819 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00820 strupper_m(servername);
00821 if (strncmp(argv[1], ".", sizeof(".")) == 0)
00822 fstrcpy(printername, servername);
00823 else
00824 slprintf(printername, sizeof(printername)-1, "%s\\%s",
00825 servername, argv[1]);
00826 fstrcpy(user, cli->user_name);
00827
00828
00829
00830 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
00831 "", MAXIMUM_ALLOWED_ACCESS,
00832 servername, user, &pol);
00833
00834 if (!W_ERROR_IS_OK(result))
00835 goto done;
00836
00837 opened_hnd = True;
00838
00839
00840
00841 result = rpccli_spoolss_getprinterdataex(cli, mem_ctx, &pol, keyname,
00842 valuename, &value);
00843
00844 if (!W_ERROR_IS_OK(result))
00845 goto done;
00846
00847
00848
00849 fstrcpy(value.valuename, valuename);
00850 display_reg_value(value);
00851
00852
00853 done:
00854 if (opened_hnd)
00855 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
00856
00857 return result;
00858 }
00859
00860
00861
00862
00863 static void display_print_driver_1(DRIVER_INFO_1 *i1)
00864 {
00865 fstring name;
00866 if (i1 == NULL)
00867 return;
00868
00869 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
00870
00871 printf ("Printer Driver Info 1:\n");
00872 printf ("\tDriver Name: [%s]\n\n", name);
00873
00874 return;
00875 }
00876
00877
00878
00879
00880 static void display_print_driver_2(DRIVER_INFO_2 *i1)
00881 {
00882 fstring name;
00883 fstring architecture;
00884 fstring driverpath;
00885 fstring datafile;
00886 fstring configfile;
00887 if (i1 == NULL)
00888 return;
00889
00890 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
00891 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
00892 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
00893 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
00894 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
00895
00896 printf ("Printer Driver Info 2:\n");
00897 printf ("\tVersion: [%x]\n", i1->version);
00898 printf ("\tDriver Name: [%s]\n", name);
00899 printf ("\tArchitecture: [%s]\n", architecture);
00900 printf ("\tDriver Path: [%s]\n", driverpath);
00901 printf ("\tDatafile: [%s]\n", datafile);
00902 printf ("\tConfigfile: [%s]\n\n", configfile);
00903
00904 return;
00905 }
00906
00907
00908
00909
00910 static void display_print_driver_3(DRIVER_INFO_3 *i1)
00911 {
00912 fstring name = "";
00913 fstring architecture = "";
00914 fstring driverpath = "";
00915 fstring datafile = "";
00916 fstring configfile = "";
00917 fstring helpfile = "";
00918 fstring dependentfiles = "";
00919 fstring monitorname = "";
00920 fstring defaultdatatype = "";
00921
00922 int length=0;
00923 BOOL valid = True;
00924
00925 if (i1 == NULL)
00926 return;
00927
00928 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
00929 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
00930 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
00931 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
00932 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
00933 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
00934 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
00935 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
00936
00937 printf ("Printer Driver Info 3:\n");
00938 printf ("\tVersion: [%x]\n", i1->version);
00939 printf ("\tDriver Name: [%s]\n",name);
00940 printf ("\tArchitecture: [%s]\n", architecture);
00941 printf ("\tDriver Path: [%s]\n", driverpath);
00942 printf ("\tDatafile: [%s]\n", datafile);
00943 printf ("\tConfigfile: [%s]\n", configfile);
00944 printf ("\tHelpfile: [%s]\n\n", helpfile);
00945
00946 while (valid)
00947 {
00948 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
00949
00950 length+=strlen(dependentfiles)+1;
00951
00952 if (strlen(dependentfiles) > 0)
00953 {
00954 printf ("\tDependentfiles: [%s]\n", dependentfiles);
00955 }
00956 else
00957 {
00958 valid = False;
00959 }
00960 }
00961
00962 printf ("\n");
00963
00964 printf ("\tMonitorname: [%s]\n", monitorname);
00965 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
00966
00967 return;
00968 }
00969
00970
00971
00972
00973 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
00974 TALLOC_CTX *mem_ctx,
00975 int argc, const char **argv)
00976 {
00977 POLICY_HND pol;
00978 WERROR werror;
00979 uint32 info_level = 3;
00980 BOOL opened_hnd = False;
00981 PRINTER_DRIVER_CTR ctr;
00982 fstring printername,
00983 servername,
00984 user;
00985 uint32 i;
00986 BOOL success = False;
00987
00988 if ((argc == 1) || (argc > 3))
00989 {
00990 printf("Usage: %s <printername> [level]\n", argv[0]);
00991 return WERR_OK;
00992 }
00993
00994
00995 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
00996 strupper_m(servername);
00997 fstrcpy(user, cli->user_name);
00998 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
00999 if (argc == 3)
01000 info_level = atoi(argv[2]);
01001
01002
01003
01004 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
01005 PRINTER_ACCESS_USE,
01006 servername, user, &pol);
01007
01008 if (!W_ERROR_IS_OK(werror)) {
01009 printf("Error opening printer handle for %s!\n", printername);
01010 return werror;
01011 }
01012
01013 opened_hnd = True;
01014
01015
01016
01017 for (i=0; archi_table[i].long_archi!=NULL; i++) {
01018
01019 werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
01020 archi_table[i].long_archi, archi_table[i].version,
01021 &ctr);
01022
01023 if (!W_ERROR_IS_OK(werror))
01024 continue;
01025
01026
01027
01028 success = True;
01029
01030 printf ("\n[%s]\n", archi_table[i].long_archi);
01031
01032 switch (info_level) {
01033 case 1:
01034 display_print_driver_1 (ctr.info1);
01035 break;
01036 case 2:
01037 display_print_driver_2 (ctr.info2);
01038 break;
01039 case 3:
01040 display_print_driver_3 (ctr.info3);
01041 break;
01042 default:
01043 printf("unknown info level %d\n", info_level);
01044 break;
01045 }
01046 }
01047
01048
01049
01050 if (opened_hnd)
01051 rpccli_spoolss_close_printer (cli, mem_ctx, &pol);
01052
01053 if ( success )
01054 werror = WERR_OK;
01055
01056 return werror;
01057 }
01058
01059
01060
01061
01062 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
01063 TALLOC_CTX *mem_ctx,
01064 int argc, const char **argv)
01065 {
01066 WERROR werror = WERR_OK;
01067 uint32 info_level = 1;
01068 PRINTER_DRIVER_CTR ctr;
01069 uint32 i, j,
01070 returned;
01071
01072 if (argc > 2) {
01073 printf("Usage: enumdrivers [level]\n");
01074 return WERR_OK;
01075 }
01076
01077 if (argc == 2)
01078 info_level = atoi(argv[1]);
01079
01080
01081
01082 for (i=0; archi_table[i].long_archi!=NULL; i++) {
01083
01084
01085 if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
01086 continue;
01087
01088 werror = rpccli_spoolss_enumprinterdrivers(
01089 cli, mem_ctx, info_level,
01090 archi_table[i].long_archi, &returned, &ctr);
01091
01092 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
01093 printf ("Server does not support environment [%s]\n",
01094 archi_table[i].long_archi);
01095 werror = WERR_OK;
01096 continue;
01097 }
01098
01099 if (returned == 0)
01100 continue;
01101
01102 if (!W_ERROR_IS_OK(werror)) {
01103 printf ("Error getting driver for environment [%s] - %d\n",
01104 archi_table[i].long_archi, W_ERROR_V(werror));
01105 continue;
01106 }
01107
01108 printf ("\n[%s]\n", archi_table[i].long_archi);
01109 switch (info_level)
01110 {
01111
01112 case 1:
01113 for (j=0; j < returned; j++) {
01114 display_print_driver_1 (&ctr.info1[j]);
01115 }
01116 break;
01117 case 2:
01118 for (j=0; j < returned; j++) {
01119 display_print_driver_2 (&ctr.info2[j]);
01120 }
01121 break;
01122 case 3:
01123 for (j=0; j < returned; j++) {
01124 display_print_driver_3 (&ctr.info3[j]);
01125 }
01126 break;
01127 default:
01128 printf("unknown info level %d\n", info_level);
01129 return WERR_UNKNOWN_LEVEL;
01130 }
01131 }
01132
01133 return werror;
01134 }
01135
01136
01137
01138
01139 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
01140 {
01141 fstring name;
01142 if (i1 == NULL)
01143 return;
01144
01145 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
01146
01147 printf ("\tDirectory Name:[%s]\n", name);
01148 }
01149
01150
01151
01152
01153 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
01154 TALLOC_CTX *mem_ctx,
01155 int argc, const char **argv)
01156 {
01157 WERROR result;
01158 fstring env;
01159 DRIVER_DIRECTORY_CTR ctr;
01160
01161 if (argc > 2) {
01162 printf("Usage: %s [environment]\n", argv[0]);
01163 return WERR_OK;
01164 }
01165
01166
01167
01168 if (argc == 2)
01169 fstrcpy (env, argv[1]);
01170 else
01171 fstrcpy (env, "Windows NT x86");
01172
01173
01174
01175 result = rpccli_spoolss_getprinterdriverdir(cli, mem_ctx, 1, env, &ctr);
01176
01177 if (W_ERROR_IS_OK(result))
01178 display_printdriverdir_1(ctr.info1);
01179
01180 return result;
01181 }
01182
01183
01184
01185
01186 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
01187 {
01188
01189 int i;
01190
01191 for (i=0; archi_table[i].long_archi != NULL; i++)
01192 {
01193 if (strcmp(arch, archi_table[i].short_archi) == 0)
01194 {
01195 info->version = archi_table[i].version;
01196 init_unistr (&info->architecture, archi_table[i].long_archi);
01197 break;
01198 }
01199 }
01200
01201 if (archi_table[i].long_archi == NULL)
01202 {
01203 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
01204 }
01205
01206 return;
01207 }
01208
01209
01210
01211
01212
01213
01214
01215 static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
01216 {
01217 char *ptr;
01218
01219
01220 ptr = strtok(str, delim);
01221
01222
01223
01224
01225
01226 if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
01227 ptr = NULL;
01228
01229 if (dest != NULL)
01230 init_unistr(dest, ptr);
01231
01232 return ptr;
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242 static BOOL init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
01243 char *args )
01244 {
01245 char *str, *str2;
01246 uint32 len, i;
01247
01248
01249 str = get_driver_3_param (args, ":", &info->name);
01250 str = get_driver_3_param (NULL, ":", &info->driverpath);
01251 str = get_driver_3_param (NULL, ":", &info->datafile);
01252 str = get_driver_3_param (NULL, ":", &info->configfile);
01253 str = get_driver_3_param (NULL, ":", &info->helpfile);
01254 str = get_driver_3_param (NULL, ":", &info->monitorname);
01255 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
01256
01257
01258 str2 = get_driver_3_param (NULL, ":", NULL);
01259 str = str2;
01260
01261
01262 str = strtok(str, ",");
01263 len = 0;
01264 while (str != NULL)
01265 {
01266
01267 len += strlen(str)+1;
01268 str = strtok(NULL, ",");
01269 }
01270
01271
01272
01273
01274 if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL)
01275 {
01276 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
01277 return False;
01278 }
01279 for (i=0; i<len; i++)
01280 {
01281 SSVAL(&info->dependentfiles[i], 0, str2[i]);
01282 }
01283 info->dependentfiles[len] = '\0';
01284
01285 return True;
01286 }
01287
01288
01289
01290
01291
01292 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
01293 TALLOC_CTX *mem_ctx,
01294 int argc, const char **argv)
01295 {
01296 WERROR result;
01297 uint32 level = 3;
01298 PRINTER_DRIVER_CTR ctr;
01299 DRIVER_INFO_3 info3;
01300 const char *arch;
01301 fstring driver_name;
01302 char *driver_args;
01303
01304
01305 if (argc != 3 && argc != 4)
01306 {
01307 printf ("Usage: %s <Environment> \\\n", argv[0]);
01308 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
01309 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
01310 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
01311 printf ("\t[version]\n");
01312
01313 return WERR_OK;
01314 }
01315
01316
01317 ZERO_STRUCT(info3);
01318 if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
01319 {
01320 printf ("Error Unknown architechture [%s]\n", argv[1]);
01321 return WERR_INVALID_PARAM;
01322 }
01323 else
01324 set_drv_info_3_env(&info3, arch);
01325
01326 driver_args = talloc_strdup( mem_ctx, argv[2] );
01327 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
01328 {
01329 printf ("Error Invalid parameter list - %s.\n", argv[2]);
01330 return WERR_INVALID_PARAM;
01331 }
01332
01333
01334
01335
01336 if (argc == 4)
01337 {
01338 info3.version = atoi(argv[3]);
01339 }
01340
01341
01342 ctr.info3 = &info3;
01343 result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
01344
01345 if (W_ERROR_IS_OK(result)) {
01346 rpcstr_pull(driver_name, info3.name.buffer,
01347 sizeof(driver_name), -1, STR_TERMINATE);
01348 printf ("Printer Driver %s successfully installed.\n",
01349 driver_name);
01350 }
01351
01352 return result;
01353 }
01354
01355
01356
01357
01358
01359 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
01360 TALLOC_CTX *mem_ctx,
01361 int argc, const char **argv)
01362 {
01363 WERROR result;
01364 uint32 level = 2;
01365 PRINTER_INFO_CTR ctr;
01366 PRINTER_INFO_2 info2;
01367 fstring servername;
01368
01369
01370 if (argc != 5)
01371 {
01372 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
01373 return WERR_OK;
01374 }
01375
01376 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
01377 strupper_m(servername);
01378
01379
01380 ZERO_STRUCT(info2);
01381
01382 init_unistr( &info2.printername, argv[1]);
01383 init_unistr( &info2.sharename, argv[2]);
01384 init_unistr( &info2.drivername, argv[3]);
01385 init_unistr( &info2.portname, argv[4]);
01386 init_unistr( &info2.comment, "Created by rpcclient");
01387 init_unistr( &info2.printprocessor, "winprint");
01388 init_unistr( &info2.datatype, "RAW");
01389 info2.devmode = NULL;
01390 info2.secdesc = NULL;
01391 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
01392 info2.priority = 0;
01393 info2.defaultpriority = 0;
01394 info2.starttime = 0;
01395 info2.untiltime = 0;
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405 ctr.printers_2 = &info2;
01406 result = rpccli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
01407
01408 if (W_ERROR_IS_OK(result))
01409 printf ("Printer %s successfully installed.\n", argv[1]);
01410
01411 return result;
01412 }
01413
01414
01415
01416
01417 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
01418 TALLOC_CTX *mem_ctx,
01419 int argc, const char **argv)
01420 {
01421 POLICY_HND pol;
01422 WERROR result;
01423 uint32 level = 2;
01424 BOOL opened_hnd = False;
01425 PRINTER_INFO_CTR ctr;
01426 PRINTER_INFO_2 info2;
01427 fstring servername,
01428 printername,
01429 user;
01430
01431
01432 if (argc != 3)
01433 {
01434 printf ("Usage: %s <printer> <driver>\n", argv[0]);
01435 return WERR_OK;
01436 }
01437
01438 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
01439 strupper_m(servername);
01440 slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
01441 fstrcpy(user, cli->user_name);
01442
01443
01444
01445 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
01446 PRINTER_ALL_ACCESS,
01447 servername, user, &pol);
01448
01449 if (!W_ERROR_IS_OK(result))
01450 goto done;
01451
01452 opened_hnd = True;
01453
01454
01455
01456 ZERO_STRUCT (info2);
01457 ctr.printers_2 = &info2;
01458
01459 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
01460
01461 if (!W_ERROR_IS_OK(result)) {
01462 printf ("Unable to retrieve printer information!\n");
01463 goto done;
01464 }
01465
01466
01467
01468 init_unistr(&ctr.printers_2->drivername, argv[2]);
01469
01470 result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
01471
01472 if (!W_ERROR_IS_OK(result)) {
01473 printf("SetPrinter call failed!\n");
01474 goto done;;
01475 }
01476
01477 printf("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
01478
01479 done:
01480
01481
01482 if (opened_hnd)
01483 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
01484
01485 return result;
01486 }
01487
01488
01489
01490
01491
01492 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
01493 TALLOC_CTX *mem_ctx,
01494 int argc, const char **argv)
01495 {
01496 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
01497
01498 int i;
01499 int vers = -1;
01500
01501 const char *arch = NULL;
01502
01503
01504 if (argc < 2 || argc > 4) {
01505 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
01506 return WERR_OK;
01507 }
01508
01509 if (argc >= 3)
01510 arch = argv[2];
01511 if (argc == 4)
01512 vers = atoi (argv[3]);
01513
01514
01515
01516 for (i=0; archi_table[i].long_archi; i++) {
01517
01518 if (arch && !strequal( archi_table[i].long_archi, arch))
01519 continue;
01520
01521 if (vers >= 0 && archi_table[i].version != vers)
01522 continue;
01523
01524
01525 result = rpccli_spoolss_deleteprinterdriverex(
01526 cli, mem_ctx, archi_table[i].long_archi, argv[1], archi_table[i].version);
01527
01528 if ( !W_ERROR_IS_OK(result) )
01529 {
01530 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
01531 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
01532 argv[1], archi_table[i].long_archi, archi_table[i].version, dos_errstr(result));
01533 }
01534 }
01535 else
01536 {
01537 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
01538 archi_table[i].long_archi, archi_table[i].version);
01539 ret = WERR_OK;
01540 }
01541 }
01542
01543 return ret;
01544 }
01545
01546
01547
01548
01549
01550 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
01551 TALLOC_CTX *mem_ctx,
01552 int argc, const char **argv)
01553 {
01554 WERROR result = WERR_OK;
01555 fstring servername;
01556 int i;
01557
01558
01559 if (argc != 2) {
01560 printf ("Usage: %s <driver>\n", argv[0]);
01561 return WERR_OK;
01562 }
01563
01564 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
01565 strupper_m(servername);
01566
01567
01568 for (i=0; archi_table[i].long_archi; i++) {
01569
01570 result = rpccli_spoolss_deleteprinterdriver(
01571 cli, mem_ctx, archi_table[i].long_archi, argv[1]);
01572
01573 if ( !W_ERROR_IS_OK(result) ) {
01574 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
01575 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
01576 argv[1], archi_table[i].long_archi,
01577 W_ERROR_V(result));
01578 }
01579 } else {
01580 printf ("Driver %s removed for arch [%s].\n", argv[1],
01581 archi_table[i].long_archi);
01582 }
01583 }
01584
01585 return result;
01586 }
01587
01588
01589
01590
01591 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
01592 TALLOC_CTX *mem_ctx,
01593 int argc, const char **argv)
01594 {
01595 WERROR result;
01596 char *servername = NULL, *environment = NULL;
01597 fstring procdir;
01598
01599
01600 if (argc > 2) {
01601 printf ("Usage: %s [environment]\n", argv[0]);
01602 return WERR_OK;
01603 }
01604
01605 if (asprintf(&servername, "\\\\%s", cli->cli->desthost) < 0)
01606 return WERR_NOMEM;
01607 strupper_m(servername);
01608
01609 if (asprintf(&environment, "%s", (argc == 2) ? argv[1] :
01610 PRINTER_DRIVER_ARCHITECTURE) < 0) {
01611 SAFE_FREE(servername);
01612 return WERR_NOMEM;
01613 }
01614
01615 result = rpccli_spoolss_getprintprocessordirectory(
01616 cli, mem_ctx, servername, environment, procdir);
01617
01618 if (W_ERROR_IS_OK(result))
01619 printf("%s\n", procdir);
01620
01621 SAFE_FREE(servername);
01622 SAFE_FREE(environment);
01623
01624 return result;
01625 }
01626
01627
01628
01629
01630 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
01631 int argc, const char **argv)
01632 {
01633 POLICY_HND handle;
01634 WERROR werror;
01635 char *servername = NULL, *printername = NULL;
01636 FORM form;
01637 BOOL got_handle = False;
01638
01639
01640
01641 if (argc != 3) {
01642 printf ("Usage: %s <printer> <formname>\n", argv[0]);
01643 return WERR_OK;
01644 }
01645
01646
01647
01648 asprintf(&servername, "\\\\%s", cli->cli->desthost);
01649 strupper_m(servername);
01650 asprintf(&printername, "%s\\%s", servername, argv[1]);
01651
01652 werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
01653 PRINTER_ALL_ACCESS,
01654 servername, cli->user_name, &handle);
01655
01656 if (!W_ERROR_IS_OK(werror))
01657 goto done;
01658
01659 got_handle = True;
01660
01661
01662
01663 form.flags = FORM_USER;
01664 form.size_x = form.size_y = 100;
01665 form.left = 0;
01666 form.top = 10;
01667 form.right = 20;
01668 form.bottom = 30;
01669
01670 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
01671
01672
01673
01674
01675 werror = rpccli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
01676
01677 done:
01678 if (got_handle)
01679 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
01680
01681 SAFE_FREE(servername);
01682 SAFE_FREE(printername);
01683
01684 return werror;
01685 }
01686
01687
01688
01689
01690 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
01691 int argc, const char **argv)
01692 {
01693 POLICY_HND handle;
01694 WERROR werror;
01695 char *servername = NULL, *printername = NULL;
01696 FORM form;
01697 BOOL got_handle = False;
01698
01699
01700
01701 if (argc != 3) {
01702 printf ("Usage: %s <printer> <formname>\n", argv[0]);
01703 return WERR_OK;
01704 }
01705
01706
01707
01708 asprintf(&servername, "\\\\%s", cli->cli->desthost);
01709 strupper_m(servername);
01710 asprintf(&printername, "%s\\%s", servername, argv[1]);
01711
01712 werror = rpccli_spoolss_open_printer_ex(
01713 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
01714 servername, cli->user_name, &handle);
01715
01716 if (!W_ERROR_IS_OK(werror))
01717 goto done;
01718
01719 got_handle = True;
01720
01721
01722
01723 form.flags = FORM_PRINTER;
01724 form.size_x = form.size_y = 100;
01725 form.left = 0;
01726 form.top = 1000;
01727 form.right = 2000;
01728 form.bottom = 3000;
01729
01730 init_unistr2(&form.name, argv[2], UNI_STR_TERMINATE);
01731
01732
01733
01734 werror = rpccli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
01735
01736 done:
01737 if (got_handle)
01738 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
01739
01740 SAFE_FREE(servername);
01741 SAFE_FREE(printername);
01742
01743 return werror;
01744 }
01745
01746
01747
01748
01749 static const char *get_form_flag(int form_flag)
01750 {
01751 switch (form_flag) {
01752 case FORM_USER:
01753 return "FORM_USER";
01754 case FORM_BUILTIN:
01755 return "FORM_BUILTIN";
01756 case FORM_PRINTER:
01757 return "FORM_PRINTER";
01758 default:
01759 return "unknown";
01760 }
01761 }
01762
01763
01764
01765
01766 static void display_form(FORM_1 *form)
01767 {
01768 fstring form_name = "";
01769
01770 if (form->name.buffer)
01771 rpcstr_pull(form_name, form->name.buffer,
01772 sizeof(form_name), -1, STR_TERMINATE);
01773
01774 printf("%s\n" \
01775 "\tflag: %s (%d)\n" \
01776 "\twidth: %d, length: %d\n" \
01777 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
01778 form_name, get_form_flag(form->flag), form->flag,
01779 form->width, form->length,
01780 form->left, form->right,
01781 form->top, form->bottom);
01782 }
01783
01784
01785
01786
01787 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
01788 int argc, const char **argv)
01789 {
01790 POLICY_HND handle;
01791 WERROR werror;
01792 char *servername = NULL, *printername = NULL;
01793 FORM_1 form;
01794 BOOL got_handle = False;
01795
01796
01797
01798 if (argc != 3) {
01799 printf ("Usage: %s <printer> <formname>\n", argv[0]);
01800 return WERR_OK;
01801 }
01802
01803
01804
01805 asprintf(&servername, "\\\\%s", cli->cli->desthost);
01806 strupper_m(servername);
01807 asprintf(&printername, "%s\\%s", servername, argv[1]);
01808
01809 werror = rpccli_spoolss_open_printer_ex(
01810 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
01811 servername, cli->user_name, &handle);
01812
01813 if (!W_ERROR_IS_OK(werror))
01814 goto done;
01815
01816 got_handle = True;
01817
01818
01819
01820 werror = rpccli_spoolss_getform(cli, mem_ctx, &handle, argv[2], 1, &form);
01821
01822 if (!W_ERROR_IS_OK(werror))
01823 goto done;
01824
01825 display_form(&form);
01826
01827 done:
01828 if (got_handle)
01829 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
01830
01831 SAFE_FREE(servername);
01832 SAFE_FREE(printername);
01833
01834 return werror;
01835 }
01836
01837
01838
01839
01840 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
01841 TALLOC_CTX *mem_ctx, int argc,
01842 const char **argv)
01843 {
01844 POLICY_HND handle;
01845 WERROR werror;
01846 char *servername = NULL, *printername = NULL;
01847 BOOL got_handle = False;
01848
01849
01850
01851 if (argc != 3) {
01852 printf ("Usage: %s <printer> <formname>\n", argv[0]);
01853 return WERR_OK;
01854 }
01855
01856
01857
01858 asprintf(&servername, "\\\\%s", cli->cli->desthost);
01859 strupper_m(servername);
01860 asprintf(&printername, "%s\\%s", servername, argv[1]);
01861
01862 werror = rpccli_spoolss_open_printer_ex(
01863 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
01864 servername, cli->user_name, &handle);
01865
01866 if (!W_ERROR_IS_OK(werror))
01867 goto done;
01868
01869 got_handle = True;
01870
01871
01872
01873 werror = rpccli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
01874
01875 done:
01876 if (got_handle)
01877 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
01878
01879 SAFE_FREE(servername);
01880 SAFE_FREE(printername);
01881
01882 return werror;
01883 }
01884
01885
01886
01887
01888 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
01889 TALLOC_CTX *mem_ctx, int argc,
01890 const char **argv)
01891 {
01892 POLICY_HND handle;
01893 WERROR werror;
01894 char *servername = NULL, *printername = NULL;
01895 BOOL got_handle = False;
01896 uint32 num_forms, level = 1, i;
01897 FORM_1 *forms;
01898
01899
01900
01901 if (argc != 2) {
01902 printf ("Usage: %s <printer>\n", argv[0]);
01903 return WERR_OK;
01904 }
01905
01906
01907
01908 asprintf(&servername, "\\\\%s", cli->cli->desthost);
01909 strupper_m(servername);
01910 asprintf(&printername, "%s\\%s", servername, argv[1]);
01911
01912 werror = rpccli_spoolss_open_printer_ex(
01913 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
01914 servername, cli->user_name, &handle);
01915
01916 if (!W_ERROR_IS_OK(werror))
01917 goto done;
01918
01919 got_handle = True;
01920
01921
01922
01923 werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
01924
01925 if (!W_ERROR_IS_OK(werror))
01926 goto done;
01927
01928
01929
01930 for (i = 0; i < num_forms; i++) {
01931
01932 display_form(&forms[i]);
01933
01934 }
01935
01936 done:
01937 if (got_handle)
01938 rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
01939
01940 SAFE_FREE(servername);
01941 SAFE_FREE(printername);
01942
01943 return werror;
01944 }
01945
01946
01947
01948
01949 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
01950 TALLOC_CTX *mem_ctx,
01951 int argc, const char **argv)
01952 {
01953 WERROR result;
01954 fstring servername, printername, user;
01955 POLICY_HND pol;
01956 BOOL opened_hnd = False;
01957 PRINTER_INFO_CTR ctr;
01958 PRINTER_INFO_0 info;
01959 REGISTRY_VALUE value;
01960
01961
01962 if (argc < 5) {
01963 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
01964 " <value> <data>\n",
01965 argv[0]);
01966 return WERR_INVALID_PARAM;
01967 }
01968
01969 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
01970 strupper_m(servername);
01971 slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
01972 fstrcpy(user, cli->user_name);
01973
01974 value.type = REG_NONE;
01975
01976 if (strequal(argv[2], "string")) {
01977 value.type = REG_SZ;
01978 }
01979
01980 if (strequal(argv[2], "binary")) {
01981 value.type = REG_BINARY;
01982 }
01983
01984 if (strequal(argv[2], "dword")) {
01985 value.type = REG_DWORD;
01986 }
01987
01988 if (strequal(argv[2], "multistring")) {
01989 value.type = REG_MULTI_SZ;
01990 }
01991
01992 if (value.type == REG_NONE) {
01993 printf("Unknown data type: %s\n", argv[2]);
01994 return WERR_INVALID_PARAM;
01995 }
01996
01997
01998 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
01999 MAXIMUM_ALLOWED_ACCESS, servername,
02000 user, &pol);
02001 if (!W_ERROR_IS_OK(result))
02002 goto done;
02003
02004 opened_hnd = True;
02005
02006 ctr.printers_0 = &info;
02007
02008 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
02009
02010 if (!W_ERROR_IS_OK(result))
02011 goto done;
02012
02013 printf("%s\n", current_timestring(True));
02014 printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
02015
02016
02017
02018 fstrcpy(value.valuename, argv[3]);
02019
02020 switch (value.type) {
02021 case REG_SZ: {
02022 UNISTR2 data;
02023 init_unistr2(&data, argv[4], UNI_STR_TERMINATE);
02024 value.size = data.uni_str_len * 2;
02025 if (value.size) {
02026 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer,
02027 value.size);
02028 } else {
02029 value.data_p = NULL;
02030 }
02031 break;
02032 }
02033 case REG_DWORD: {
02034 uint32 data = strtoul(argv[4], NULL, 10);
02035 value.size = sizeof(data);
02036 if (sizeof(data)) {
02037 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data,
02038 sizeof(data));
02039 } else {
02040 value.data_p = NULL;
02041 }
02042 break;
02043 }
02044 case REG_BINARY: {
02045 DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]);
02046 value.data_p = data.data;
02047 value.size = data.length;
02048 break;
02049 }
02050 case REG_MULTI_SZ: {
02051 int i;
02052 size_t len = 0;
02053 char *p;
02054
02055 for (i=4; i<argc; i++) {
02056 if (strcmp(argv[i], "NULL") == 0) {
02057 argv[i] = "";
02058 }
02059 len += strlen(argv[i])+1;
02060 }
02061
02062 value.size = len*2;
02063 value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size);
02064 if (value.data_p == NULL) {
02065 result = WERR_NOMEM;
02066 goto done;
02067 }
02068
02069 p = (char *)value.data_p;
02070 len = value.size;
02071 for (i=4; i<argc; i++) {
02072 size_t l = (strlen(argv[i])+1)*2;
02073 rpcstr_push(p, argv[i], len, STR_TERMINATE);
02074 p += l;
02075 len -= l;
02076 }
02077 SMB_ASSERT(len == 0);
02078 break;
02079 }
02080 default:
02081 printf("Unknown data type: %s\n", argv[2]);
02082 result = WERR_INVALID_PARAM;
02083 goto done;
02084 }
02085
02086 result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
02087
02088 if (!W_ERROR_IS_OK(result)) {
02089 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
02090 goto done;
02091 }
02092 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
02093
02094 result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
02095
02096 if (!W_ERROR_IS_OK(result))
02097 goto done;
02098
02099 printf("%s\n", current_timestring(True));
02100 printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
02101
02102 done:
02103
02104 if (opened_hnd)
02105 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
02106
02107 return result;
02108 }
02109
02110
02111
02112
02113 static void display_job_info_1(JOB_INFO_1 *job)
02114 {
02115 fstring username = "", document = "", text_status = "";
02116
02117 rpcstr_pull(username, job->username.buffer,
02118 sizeof(username), -1, STR_TERMINATE);
02119
02120 rpcstr_pull(document, job->document.buffer,
02121 sizeof(document), -1, STR_TERMINATE);
02122
02123 rpcstr_pull(text_status, job->text_status.buffer,
02124 sizeof(text_status), -1, STR_TERMINATE);
02125
02126 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
02127 username, document, text_status, job->pagesprinted,
02128 job->totalpages);
02129 }
02130
02131
02132
02133
02134 static void display_job_info_2(JOB_INFO_2 *job)
02135 {
02136 fstring username = "", document = "", text_status = "";
02137
02138 rpcstr_pull(username, job->username.buffer,
02139 sizeof(username), -1, STR_TERMINATE);
02140
02141 rpcstr_pull(document, job->document.buffer,
02142 sizeof(document), -1, STR_TERMINATE);
02143
02144 rpcstr_pull(text_status, job->text_status.buffer,
02145 sizeof(text_status), -1, STR_TERMINATE);
02146
02147 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
02148 username, document, text_status, job->pagesprinted,
02149 job->totalpages, job->size);
02150 }
02151
02152
02153
02154
02155 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
02156 TALLOC_CTX *mem_ctx, int argc,
02157 const char **argv)
02158 {
02159 WERROR result;
02160 uint32 level = 1, num_jobs, i;
02161 BOOL got_hnd = False;
02162 pstring printername;
02163 fstring servername, user;
02164 POLICY_HND hnd;
02165 JOB_INFO_CTR ctr;
02166
02167 if (argc < 2 || argc > 3) {
02168 printf("Usage: %s printername [level]\n", argv[0]);
02169 return WERR_OK;
02170 }
02171
02172 if (argc == 3)
02173 level = atoi(argv[2]);
02174
02175
02176
02177 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
02178 strupper_m(servername);
02179 fstrcpy(user, cli->user_name);
02180 slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->cli->desthost);
02181 strupper_m(printername);
02182 pstrcat(printername, argv[1]);
02183
02184 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
02185 "", MAXIMUM_ALLOWED_ACCESS,
02186 servername, user, &hnd);
02187
02188 if (!W_ERROR_IS_OK(result))
02189 goto done;
02190
02191 got_hnd = True;
02192
02193
02194
02195 result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
02196 &num_jobs, &ctr);
02197
02198 if (!W_ERROR_IS_OK(result))
02199 goto done;
02200
02201 for (i = 0; i < num_jobs; i++) {
02202 switch(level) {
02203 case 1:
02204 display_job_info_1(&ctr.job.job_info_1[i]);
02205 break;
02206 case 2:
02207 display_job_info_2(&ctr.job.job_info_2[i]);
02208 break;
02209 default:
02210 d_printf("unknown info level %d\n", level);
02211 break;
02212 }
02213 }
02214
02215 done:
02216 if (got_hnd)
02217 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
02218
02219 return result;
02220 }
02221
02222
02223
02224
02225 static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
02226 TALLOC_CTX *mem_ctx, int argc,
02227 const char **argv)
02228 {
02229 WERROR result;
02230 uint32 i=0, val_needed, data_needed;
02231 BOOL got_hnd = False;
02232 pstring printername;
02233 fstring servername, user;
02234 POLICY_HND hnd;
02235
02236 if (argc != 2) {
02237 printf("Usage: %s printername\n", argv[0]);
02238 return WERR_OK;
02239 }
02240
02241
02242
02243 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
02244 strupper_m(servername);
02245 fstrcpy(user, cli->user_name);
02246 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
02247 strupper_m(printername);
02248 pstrcat(printername, argv[1]);
02249
02250 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
02251 "", MAXIMUM_ALLOWED_ACCESS,
02252 servername, user, &hnd);
02253
02254 if (!W_ERROR_IS_OK(result))
02255 goto done;
02256
02257 got_hnd = True;
02258
02259
02260
02261 result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
02262 &val_needed, &data_needed,
02263 NULL);
02264 while (W_ERROR_IS_OK(result)) {
02265 REGISTRY_VALUE value;
02266 result = rpccli_spoolss_enumprinterdata(
02267 cli, mem_ctx, &hnd, i++, val_needed,
02268 data_needed, 0, 0, &value);
02269 if (W_ERROR_IS_OK(result))
02270 display_reg_value(value);
02271 }
02272 if (W_ERROR_V(result) == ERRnomoreitems)
02273 result = W_ERROR(ERRsuccess);
02274
02275 done:
02276 if (got_hnd)
02277 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
02278
02279 return result;
02280 }
02281
02282
02283
02284
02285 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
02286 TALLOC_CTX *mem_ctx, int argc,
02287 const char **argv)
02288 {
02289 WERROR result;
02290 uint32 i;
02291 BOOL got_hnd = False;
02292 pstring printername;
02293 fstring servername, user;
02294 const char *keyname = NULL;
02295 POLICY_HND hnd;
02296 REGVAL_CTR *ctr = NULL;
02297
02298 if (argc != 3) {
02299 printf("Usage: %s printername <keyname>\n", argv[0]);
02300 return WERR_OK;
02301 }
02302
02303 keyname = argv[2];
02304
02305
02306
02307 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
02308 strupper_m(servername);
02309 fstrcpy(user, cli->user_name);
02310 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
02311 strupper_m(printername);
02312 pstrcat(printername, argv[1]);
02313
02314 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
02315 "", MAXIMUM_ALLOWED_ACCESS,
02316 servername, user, &hnd);
02317
02318 if (!W_ERROR_IS_OK(result))
02319 goto done;
02320
02321 got_hnd = True;
02322
02323
02324
02325 if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
02326 return WERR_NOMEM;
02327
02328 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
02329
02330 if (!W_ERROR_IS_OK(result))
02331 goto done;
02332
02333 for (i=0; i < ctr->num_values; i++) {
02334 display_reg_value(*(ctr->values[i]));
02335 }
02336
02337 TALLOC_FREE( ctr );
02338
02339 done:
02340 if (got_hnd)
02341 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
02342
02343 return result;
02344 }
02345
02346
02347
02348
02349 static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
02350 TALLOC_CTX *mem_ctx, int argc,
02351 const char **argv)
02352 {
02353 WERROR result;
02354 BOOL got_hnd = False;
02355 pstring printername;
02356 fstring servername, user;
02357 const char *keyname = NULL;
02358 POLICY_HND hnd;
02359 uint16 *keylist = NULL, *curkey;
02360
02361 if (argc < 2 || argc > 3) {
02362 printf("Usage: %s printername [keyname]\n", argv[0]);
02363 return WERR_OK;
02364 }
02365
02366 if (argc == 3)
02367 keyname = argv[2];
02368 else
02369 keyname = "";
02370
02371
02372
02373 slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
02374 strupper_m(servername);
02375 fstrcpy(user, cli->user_name);
02376 slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
02377 strupper_m(printername);
02378 pstrcat(printername, argv[1]);
02379
02380 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
02381 "", MAXIMUM_ALLOWED_ACCESS,
02382 servername, user, &hnd);
02383
02384 if (!W_ERROR_IS_OK(result))
02385 goto done;
02386
02387 got_hnd = True;
02388
02389
02390
02391 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
02392
02393 if (!W_ERROR_IS_OK(result))
02394 goto done;
02395
02396 curkey = keylist;
02397 while (*curkey != 0) {
02398 pstring subkey;
02399 rpcstr_pull(subkey, curkey, sizeof(subkey), -1,
02400 STR_TERMINATE);
02401 printf("%s\n", subkey);
02402 curkey += strlen(subkey) + 1;
02403 }
02404
02405 done:
02406
02407 SAFE_FREE(keylist);
02408
02409 if (got_hnd)
02410 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
02411
02412 return result;
02413 }
02414
02415
02416
02417
02418 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
02419 TALLOC_CTX *mem_ctx, int argc,
02420 const char **argv)
02421 {
02422 fstring servername, printername;
02423 POLICY_HND hnd;
02424 BOOL got_hnd = False;
02425 WERROR result;
02426 SPOOL_NOTIFY_OPTION option;
02427
02428 if (argc != 2) {
02429 printf("Usage: %s printername\n", argv[0]);
02430 result = WERR_OK;
02431 goto done;
02432 }
02433
02434
02435
02436 slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->cli->desthost);
02437 strupper_m(servername);
02438
02439 slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->cli->desthost,
02440 argv[1]);
02441 strupper_m(printername);
02442
02443 result = rpccli_spoolss_open_printer_ex(
02444 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
02445 servername, cli->user_name, &hnd);
02446
02447 if (!W_ERROR_IS_OK(result)) {
02448 printf("Error opening %s\n", argv[1]);
02449 goto done;
02450 }
02451
02452 got_hnd = True;
02453
02454
02455
02456 ZERO_STRUCT(option);
02457
02458 option.version = 2;
02459 option.option_type_ptr = 1;
02460 option.count = option.ctr.count = 2;
02461
02462 option.ctr.type = TALLOC_ARRAY(mem_ctx, SPOOL_NOTIFY_OPTION_TYPE, 2);
02463 if (option.ctr.type == NULL) {
02464 result = WERR_NOMEM;
02465 goto done;
02466 }
02467
02468 ZERO_STRUCT(option.ctr.type[0]);
02469 option.ctr.type[0].type = PRINTER_NOTIFY_TYPE;
02470 option.ctr.type[0].count = option.ctr.type[0].count2 = 1;
02471 option.ctr.type[0].fields_ptr = 1;
02472 option.ctr.type[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
02473
02474 ZERO_STRUCT(option.ctr.type[1]);
02475 option.ctr.type[1].type = JOB_NOTIFY_TYPE;
02476 option.ctr.type[1].count = option.ctr.type[1].count2 = 1;
02477 option.ctr.type[1].fields_ptr = 1;
02478 option.ctr.type[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
02479
02480
02481
02482 slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
02483 strupper_m(servername);
02484
02485 result = rpccli_spoolss_rffpcnex(
02486 cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
02487
02488 if (!W_ERROR_IS_OK(result)) {
02489 printf("Error rffpcnex %s\n", argv[1]);
02490 goto done;
02491 }
02492
02493 done:
02494 if (got_hnd)
02495 rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
02496
02497 return result;
02498 }
02499
02500
02501
02502
02503 static BOOL compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
02504 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
02505 {
02506 PRINTER_INFO_CTR ctr1, ctr2;
02507 WERROR werror;
02508 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
02509
02510 printf("Retrieving printer propertiesfor %s...", cli1->cli->desthost);
02511 werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1);
02512 if ( !W_ERROR_IS_OK(werror) ) {
02513 printf("failed (%s)\n", dos_errstr(werror));
02514 talloc_destroy(mem_ctx);
02515 return False;
02516 }
02517 printf("ok\n");
02518
02519 printf("Retrieving printer properties for %s...", cli2->cli->desthost);
02520 werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2);
02521 if ( !W_ERROR_IS_OK(werror) ) {
02522 printf("failed (%s)\n", dos_errstr(werror));
02523 talloc_destroy(mem_ctx);
02524 return False;
02525 }
02526 printf("ok\n");
02527
02528 talloc_destroy(mem_ctx);
02529
02530 return True;
02531 }
02532
02533
02534
02535
02536 static BOOL compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
02537 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
02538 {
02539 PRINTER_INFO_CTR ctr1, ctr2;
02540 WERROR werror;
02541 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
02542 SEC_DESC *sd1, *sd2;
02543 BOOL result = True;
02544
02545
02546 printf("Retreiving printer security for %s...", cli1->cli->desthost);
02547 werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1);
02548 if ( !W_ERROR_IS_OK(werror) ) {
02549 printf("failed (%s)\n", dos_errstr(werror));
02550 result = False;
02551 goto done;
02552 }
02553 printf("ok\n");
02554
02555 printf("Retrieving printer security for %s...", cli2->cli->desthost);
02556 werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2);
02557 if ( !W_ERROR_IS_OK(werror) ) {
02558 printf("failed (%s)\n", dos_errstr(werror));
02559 result = False;
02560 goto done;
02561 }
02562 printf("ok\n");
02563
02564
02565 printf("++ ");
02566
02567 if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) {
02568 printf("NULL PRINTER_INFO_3!\n");
02569 result = False;
02570 goto done;
02571 }
02572
02573 sd1 = ctr1.printers_3->secdesc;
02574 sd2 = ctr2.printers_3->secdesc;
02575
02576 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
02577 printf("NULL secdesc!\n");
02578 result = False;
02579 goto done;
02580 }
02581
02582 if (!sec_desc_equal( sd1, sd2 ) ) {
02583 printf("Security Descriptors *not* equal!\n");
02584 result = False;
02585 goto done;
02586 }
02587
02588 printf("Security descriptors match\n");
02589
02590 done:
02591 talloc_destroy(mem_ctx);
02592 return result;
02593 }
02594
02595
02596
02597
02598
02599 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
02600 TALLOC_CTX *mem_ctx, int argc,
02601 const char **argv)
02602 {
02603 fstring printername, servername1, servername2;
02604 pstring printername_path;
02605 struct cli_state *cli_server1 = cli->cli;
02606 struct cli_state *cli_server2 = NULL;
02607 struct rpc_pipe_client *cli2 = NULL;
02608 POLICY_HND hPrinter1, hPrinter2;
02609 NTSTATUS nt_status;
02610 WERROR werror;
02611
02612 if ( argc != 3 ) {
02613 printf("Usage: %s <printer> <server>\n", argv[0]);
02614 return WERR_OK;
02615 }
02616
02617 fstrcpy( printername, argv[1] );
02618
02619 fstrcpy( servername1, cli->cli->desthost );
02620 fstrcpy( servername2, argv[2] );
02621 strupper_m( servername1 );
02622 strupper_m( servername2 );
02623
02624
02625
02626
02627 nt_status = cli_full_connection(&cli_server2, global_myname(), servername2,
02628 NULL, 0,
02629 "IPC$", "IPC",
02630 cmdline_auth_info.username,
02631 lp_workgroup(),
02632 cmdline_auth_info.password,
02633 cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
02634 cmdline_auth_info.signing_state, NULL);
02635
02636 if ( !NT_STATUS_IS_OK(nt_status) )
02637 return WERR_GENERAL_FAILURE;
02638
02639 cli2 = cli_rpc_pipe_open_noauth(cli_server2, PI_SPOOLSS, &nt_status);
02640 if (!cli2) {
02641 printf("failed to open spoolss pipe on server %s (%s)\n",
02642 servername2, nt_errstr(nt_status));
02643 return WERR_GENERAL_FAILURE;
02644 }
02645
02646
02647
02648 pstr_sprintf( printername_path, "\\\\%s\\%s", servername1, printername );
02649 printf("Opening %s...", printername_path);
02650 werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, printername_path,
02651 "", PRINTER_ALL_ACCESS, servername1, cli_server1->user_name, &hPrinter1);
02652 if ( !W_ERROR_IS_OK(werror) ) {
02653 printf("failed (%s)\n", dos_errstr(werror));
02654 goto done;
02655 }
02656 printf("ok\n");
02657
02658 pstr_sprintf( printername_path, "\\\\%s\\%s", servername2, printername );
02659 printf("Opening %s...", printername_path);
02660 werror = rpccli_spoolss_open_printer_ex( cli2, mem_ctx, printername_path,
02661 "", PRINTER_ALL_ACCESS, servername2, cli_server2->user_name, &hPrinter2 );
02662 if ( !W_ERROR_IS_OK(werror) ) {
02663 printf("failed (%s)\n", dos_errstr(werror));
02664 goto done;
02665 }
02666 printf("ok\n");
02667
02668
02669 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
02670 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
02671 #if 0
02672 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
02673 #endif
02674
02675
02676 done:
02677
02678
02679 printf("Closing printers...");
02680 rpccli_spoolss_close_printer( cli, mem_ctx, &hPrinter1 );
02681 rpccli_spoolss_close_printer( cli2, mem_ctx, &hPrinter2 );
02682 printf("ok\n");
02683
02684
02685
02686 cli_shutdown( cli_server2 );
02687
02688 return WERR_OK;
02689 }
02690
02691
02692 struct cmd_set spoolss_commands[] = {
02693
02694 { "SPOOLSS" },
02695
02696 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, NULL, "Add a print driver", "" },
02697 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, NULL, "Add a printer", "" },
02698 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, NULL, "Delete a printer driver", "" },
02699 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, PI_SPOOLSS, NULL, "Delete a printer driver with files", "" },
02700 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, NULL, "Enumerate printer data", "" },
02701 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, NULL, "Enumerate printer data for a key", "" },
02702 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, NULL, "Enumerate printer keys", "" },
02703 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, NULL, "Enumerate print jobs", "" },
02704 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, NULL, "Enumerate printer ports", "" },
02705 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, NULL, "Enumerate installed printer drivers", "" },
02706 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, NULL, "Enumerate printers", "" },
02707 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, NULL, "Get print driver data", "" },
02708 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, NULL, "Get printer driver data with keyname", ""},
02709 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, NULL, "Get print driver information", "" },
02710 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, NULL, "Get print driver upload directory", "" },
02711 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, NULL, "Get printer info", "" },
02712 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, NULL, "Open printer handle", "" },
02713 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, NULL, "Set printer driver", "" },
02714 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, NULL, "Get print processor directory", "" },
02715 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, NULL, "Add form", "" },
02716 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, NULL, "Set form", "" },
02717 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, NULL, "Get form", "" },
02718 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, NULL, "Delete form", "" },
02719 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, NULL, "Enumerate forms", "" },
02720 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, NULL, "Set printer comment", "" },
02721 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, PI_SPOOLSS, NULL, "Set printername", "" },
02722 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, NULL, "Set REG_SZ printer data", "" },
02723 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, NULL, "Rffpcnex test", "" },
02724 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, PI_SPOOLSS, NULL, "Printer comparison test", "" },
02725
02726 { NULL }
02727 };