Changeset 740 for vendor/current/source3/printing
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source3/printing
- Files:
-
- 17 added
- 1 deleted
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/printing/load.c
r597 r740 19 19 20 20 #include "includes.h" 21 21 #include "printing/pcap.h" 22 #include "printing/load.h" 22 23 23 24 /*************************************************************************** … … 56 57 load automatic printer services from pre-populated pcap cache 57 58 ***************************************************************************/ 58 void load_printers(void) 59 void load_printers(struct tevent_context *ev, 60 struct messaging_context *msg_ctx) 59 61 { 62 SMB_ASSERT(pcap_cache_loaded()); 63 60 64 add_auto_printers(); 61 65 -
vendor/current/source3/printing/notify.c
r414 r740 22 22 #include "includes.h" 23 23 #include "printing.h" 24 #include "../librpc/gen_ndr/spoolss.h" 25 #include "nt_printing.h" 26 #include "printing/notify.h" 27 #include "messages.h" 28 #include "util_tdb.h" 24 29 25 30 static TALLOC_CTX *send_ctx; … … 228 233 void *private_data) 229 234 { 235 struct messaging_context *msg_ctx = talloc_get_type_abort( 236 private_data, struct messaging_context); 230 237 /* Remove this timed event handler. */ 231 238 TALLOC_FREE(notify_event); 232 239 233 240 change_to_root_user(); 234 print_notify_send_messages( smbd_messaging_context(), 0);241 print_notify_send_messages(msg_ctx, 0); 235 242 } 236 243 … … 263 270 *******************************************************************/ 264 271 265 static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg) 272 static void send_spoolss_notify2_msg(struct tevent_context *ev, 273 struct messaging_context *msg_ctx, 274 SPOOLSS_NOTIFY_MSG *msg) 266 275 { 267 276 struct notify_queue *pnqueue, *tmp_ptr; … … 326 335 num_messages++; 327 336 328 if ((notify_event == NULL) && ( smbd_event_context()!= NULL)) {337 if ((notify_event == NULL) && (ev != NULL)) { 329 338 /* Add an event for 1 second's time to send this queue. */ 330 notify_event = tevent_add_timer(smbd_event_context(), NULL, 331 timeval_current_ofs(1,0), 332 print_notify_event_send_messages, NULL); 333 } 334 335 } 336 337 static void send_notify_field_values(const char *sharename, uint32 type, 339 notify_event = tevent_add_timer( 340 ev, NULL, timeval_current_ofs(1,0), 341 print_notify_event_send_messages, msg_ctx); 342 } 343 344 } 345 346 static void send_notify_field_values(struct tevent_context *ev, 347 struct messaging_context *msg_ctx, 348 const char *sharename, uint32 type, 338 349 uint32 field, uint32 id, uint32 value1, 339 350 uint32 value2, uint32 flags) … … 361 372 msg->flags = flags; 362 373 363 send_spoolss_notify2_msg(msg); 364 } 365 366 static void send_notify_field_buffer(const char *sharename, uint32 type, 374 send_spoolss_notify2_msg(ev, msg_ctx, msg); 375 } 376 377 static void send_notify_field_buffer(struct tevent_context *ev, 378 struct messaging_context *msg_ctx, 379 const char *sharename, uint32 type, 367 380 uint32 field, uint32 id, uint32 len, 368 381 const char *buffer) … … 389 402 msg->notify.data = CONST_DISCARD(char *,buffer); 390 403 391 send_spoolss_notify2_msg( msg);404 send_spoolss_notify2_msg(ev, msg_ctx, msg); 392 405 } 393 406 394 407 /* Send a message that the printer status has changed */ 395 408 396 void notify_printer_status_byname(const char *sharename, uint32 status) 409 void notify_printer_status_byname(struct tevent_context *ev, 410 struct messaging_context *msg_ctx, 411 const char *sharename, uint32 status) 397 412 { 398 413 /* Printer status stored in value1 */ … … 400 415 int snum = print_queue_snum(sharename); 401 416 402 send_notify_field_values( sharename, PRINTER_NOTIFY_TYPE,417 send_notify_field_values(ev, msg_ctx, sharename, PRINTER_NOTIFY_TYPE, 403 418 PRINTER_NOTIFY_FIELD_STATUS, snum, 404 419 status, 0, 0); 405 420 } 406 421 407 void notify_printer_status(int snum, uint32 status) 408 { 409 const char *sharename = SERVICE(snum); 422 void notify_printer_status(struct tevent_context *ev, 423 struct messaging_context *msg_ctx, 424 int snum, uint32 status) 425 { 426 const char *sharename = lp_servicename(snum); 410 427 411 428 if (sharename) 412 notify_printer_status_byname(sharename, status); 413 } 414 415 void notify_job_status_byname(const char *sharename, uint32 jobid, uint32 status, 429 notify_printer_status_byname(ev, msg_ctx, sharename, status); 430 } 431 432 void notify_job_status_byname(struct tevent_context *ev, 433 struct messaging_context *msg_ctx, 434 const char *sharename, uint32 jobid, 435 uint32 status, 416 436 uint32 flags) 417 437 { 418 438 /* Job id stored in id field, status in value1 */ 419 439 420 send_notify_field_values(sharename, JOB_NOTIFY_TYPE, 440 send_notify_field_values(ev, msg_ctx, 441 sharename, JOB_NOTIFY_TYPE, 421 442 JOB_NOTIFY_FIELD_STATUS, jobid, 422 443 status, 0, flags); 423 444 } 424 445 425 void notify_job_status(const char *sharename, uint32 jobid, uint32 status) 426 { 427 notify_job_status_byname(sharename, jobid, status, 0); 428 } 429 430 void notify_job_total_bytes(const char *sharename, uint32 jobid, 446 void notify_job_status(struct tevent_context *ev, 447 struct messaging_context *msg_ctx, 448 const char *sharename, uint32 jobid, uint32 status) 449 { 450 notify_job_status_byname(ev, msg_ctx, sharename, jobid, status, 0); 451 } 452 453 void notify_job_total_bytes(struct tevent_context *ev, 454 struct messaging_context *msg_ctx, 455 const char *sharename, uint32 jobid, 431 456 uint32 size) 432 457 { 433 458 /* Job id stored in id field, status in value1 */ 434 459 435 send_notify_field_values(sharename, JOB_NOTIFY_TYPE, 460 send_notify_field_values(ev, msg_ctx, 461 sharename, JOB_NOTIFY_TYPE, 436 462 JOB_NOTIFY_FIELD_TOTAL_BYTES, jobid, 437 463 size, 0, 0); 438 464 } 439 465 440 void notify_job_total_pages(const char *sharename, uint32 jobid, 466 void notify_job_total_pages(struct tevent_context *ev, 467 struct messaging_context *msg_ctx, 468 const char *sharename, uint32 jobid, 441 469 uint32 pages) 442 470 { 443 471 /* Job id stored in id field, status in value1 */ 444 472 445 send_notify_field_values(sharename, JOB_NOTIFY_TYPE, 473 send_notify_field_values(ev, msg_ctx, 474 sharename, JOB_NOTIFY_TYPE, 446 475 JOB_NOTIFY_FIELD_TOTAL_PAGES, jobid, 447 476 pages, 0, 0); 448 477 } 449 478 450 void notify_job_username(const char *sharename, uint32 jobid, char *name) 451 { 452 send_notify_field_buffer( 479 void notify_job_username(struct tevent_context *ev, 480 struct messaging_context *msg_ctx, 481 const char *sharename, uint32 jobid, char *name) 482 { 483 send_notify_field_buffer( 484 ev, msg_ctx, 453 485 sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, 454 486 jobid, strlen(name) + 1, name); 455 487 } 456 488 457 void notify_job_name(const char *sharename, uint32 jobid, char *name) 458 { 459 send_notify_field_buffer( 489 void notify_job_name(struct tevent_context *ev, 490 struct messaging_context *msg_ctx, 491 const char *sharename, uint32 jobid, char *name) 492 { 493 send_notify_field_buffer( 494 ev, msg_ctx, 460 495 sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, 461 496 jobid, strlen(name) + 1, name); 462 497 } 463 498 464 void notify_job_submitted(const char *sharename, uint32 jobid, 499 void notify_job_submitted(struct tevent_context *ev, 500 struct messaging_context *msg_ctx, 501 const char *sharename, uint32 jobid, 465 502 time_t submitted) 466 503 { 467 504 send_notify_field_buffer( 505 ev, msg_ctx, 468 506 sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, 469 507 jobid, sizeof(submitted), (char *)&submitted); 470 508 } 471 509 472 void notify_printer_driver(int snum, char *driver_name) 473 { 474 const char *sharename = SERVICE(snum); 475 476 send_notify_field_buffer( 510 void notify_printer_driver(struct tevent_context *ev, 511 struct messaging_context *msg_ctx, 512 int snum, const char *driver_name) 513 { 514 const char *sharename = lp_servicename(snum); 515 516 send_notify_field_buffer( 517 ev, msg_ctx, 477 518 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, 478 519 snum, strlen(driver_name) + 1, driver_name); 479 520 } 480 521 481 void notify_printer_comment(int snum, char *comment) 482 { 483 const char *sharename = SERVICE(snum); 484 485 send_notify_field_buffer( 522 void notify_printer_comment(struct tevent_context *ev, 523 struct messaging_context *msg_ctx, 524 int snum, const char *comment) 525 { 526 const char *sharename = lp_servicename(snum); 527 528 send_notify_field_buffer( 529 ev, msg_ctx, 486 530 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, 487 531 snum, strlen(comment) + 1, comment); 488 532 } 489 533 490 void notify_printer_sharename(int snum, char *share_name) 491 { 492 const char *sharename = SERVICE(snum); 493 494 send_notify_field_buffer( 534 void notify_printer_sharename(struct tevent_context *ev, 535 struct messaging_context *msg_ctx, 536 int snum, const char *share_name) 537 { 538 const char *sharename = lp_servicename(snum); 539 540 send_notify_field_buffer( 541 ev, msg_ctx, 495 542 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, 496 543 snum, strlen(share_name) + 1, share_name); 497 544 } 498 545 499 void notify_printer_printername(int snum, char *printername) 500 { 501 const char *sharename = SERVICE(snum); 502 503 send_notify_field_buffer( 546 void notify_printer_printername(struct tevent_context *ev, 547 struct messaging_context *msg_ctx, 548 int snum, const char *printername) 549 { 550 const char *sharename = lp_servicename(snum); 551 552 send_notify_field_buffer( 553 ev, msg_ctx, 504 554 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, 505 555 snum, strlen(printername) + 1, printername); 506 556 } 507 557 508 void notify_printer_port(int snum, char *port_name) 509 { 510 const char *sharename = SERVICE(snum); 511 512 send_notify_field_buffer( 558 void notify_printer_port(struct tevent_context *ev, 559 struct messaging_context *msg_ctx, 560 int snum, const char *port_name) 561 { 562 const char *sharename = lp_servicename(snum); 563 564 send_notify_field_buffer( 565 ev, msg_ctx, 513 566 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, 514 567 snum, strlen(port_name) + 1, port_name); 515 568 } 516 569 517 void notify_printer_location(int snum, char *location) 518 { 519 const char *sharename = SERVICE(snum); 520 521 send_notify_field_buffer( 570 void notify_printer_location(struct tevent_context *ev, 571 struct messaging_context *msg_ctx, 572 int snum, const char *location) 573 { 574 const char *sharename = lp_servicename(snum); 575 576 send_notify_field_buffer( 577 ev, msg_ctx, 522 578 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, 523 579 snum, strlen(location) + 1, location); 524 580 } 525 581 526 void notify_printer_byname( const char *printername, uint32 change, const char *value ) 582 void notify_printer_sepfile(struct tevent_context *ev, 583 struct messaging_context *msg_ctx, 584 int snum, const char *sepfile) 585 { 586 const char *sharename = lp_servicename(snum); 587 588 send_notify_field_buffer( 589 ev, msg_ctx, 590 sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, 591 snum, strlen(sepfile) + 1, sepfile); 592 } 593 594 595 void notify_printer_byname(struct tevent_context *ev, 596 struct messaging_context *msg_ctx, 597 const char *printername, uint32 change, 598 const char *value) 527 599 { 528 600 int snum = print_queue_snum(printername); … … 532 604 return; 533 605 534 send_notify_field_buffer( printername, type, change, snum, strlen(value)+1, value ); 606 send_notify_field_buffer( 607 ev, msg_ctx, 608 printername, type, change, snum, strlen(value)+1, value ); 535 609 } 536 610 -
vendor/current/source3/printing/nt_printing.c
r597 r740 21 21 22 22 #include "includes.h" 23 24 static TDB_CONTEXT *tdb_forms; /* used for forms files */ 25 static TDB_CONTEXT *tdb_drivers; /* used for driver files */ 26 static TDB_CONTEXT *tdb_printers; /* used for printers files */ 27 28 #define FORMS_PREFIX "FORMS/" 29 #define DRIVERS_PREFIX "DRIVERS/" 30 #define DRIVER_INIT_PREFIX "DRIVER_INIT/" 31 #define PRINTERS_PREFIX "PRINTERS/" 32 #define SECDESC_PREFIX "SECDESC/" 33 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter" 34 35 #define NTDRIVERS_DATABASE_VERSION_1 1 36 #define NTDRIVERS_DATABASE_VERSION_2 2 37 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */ 38 #define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */ 39 #define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */ 23 #include "printing/nt_printing_tdb.h" 24 #include "../librpc/gen_ndr/ndr_spoolss.h" 25 #include "rpc_server/spoolss/srv_spoolss_util.h" 26 #include "nt_printing.h" 27 #include "secrets.h" 28 #include "../librpc/gen_ndr/netlogon.h" 29 #include "../libcli/security/security.h" 30 #include "passdb/machine_sid.h" 31 #include "smbd/smbd.h" 32 #include "auth.h" 33 #include "messages.h" 34 #include "rpc_server/spoolss/srv_spoolss_nt.h" 35 #include "rpc_client/cli_winreg_spoolss.h" 40 36 41 37 /* Map generic permissions to printer object specific permissions */ … … 48 44 }; 49 45 50 const struct standard_mapping printer_std_mapping = {51 PRINTER_READ,52 PRINTER_WRITE,53 PRINTER_EXECUTE,54 PRINTER_ALL_ACCESS55 };56 57 46 /* Map generic permissions to print server object specific permissions */ 58 47 … … 64 53 }; 65 54 66 const struct generic_mapping printserver_std_mapping = {67 SERVER_READ,68 SERVER_WRITE,69 SERVER_EXECUTE,70 SERVER_ALL_ACCESS71 };72 73 55 /* Map generic permissions to job object specific permissions */ 74 56 … … 78 60 JOB_EXECUTE, 79 61 JOB_ALL_ACCESS 80 };81 82 /* We need one default form to support our default printer. Msoft adds the83 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an84 array index). Letter is always first, so (for the current code) additions85 always put things in the correct order. */86 static const nt_forms_struct default_forms[] = {87 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},88 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},89 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},90 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},91 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},92 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},93 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},94 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},95 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},96 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},97 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},98 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},99 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},100 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},101 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},102 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},103 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},104 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},105 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},106 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},107 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},108 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},109 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},110 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},111 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},112 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},113 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},114 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},115 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},116 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},117 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},118 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},119 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},120 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},121 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},122 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},123 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},124 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},125 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},126 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},127 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},128 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},129 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},130 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},131 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},132 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},133 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},134 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},135 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},136 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},137 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},138 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},139 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},140 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},141 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},142 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},143 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},144 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},145 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},146 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},147 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},148 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},149 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},150 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},151 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},152 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},153 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},154 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},155 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},156 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},157 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},158 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},159 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},160 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},161 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},162 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},163 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},164 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},165 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},166 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},167 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},168 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},169 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},170 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},171 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},172 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},173 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},174 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},175 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},176 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},177 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},178 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},179 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},180 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},181 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},182 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},183 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},184 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},185 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},186 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},187 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},188 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},189 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},190 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},191 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},192 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},193 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},194 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},195 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},196 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},197 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},198 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},199 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},200 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},201 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},202 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},203 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},204 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}205 62 }; 206 63 … … 217 74 }; 218 75 219 220 /****************************************************************************221 generate a new TDB_DATA key for storing a printer222 ****************************************************************************/223 224 static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )225 {226 fstring share;227 char *keystr = NULL;228 TDB_DATA key;229 230 fstrcpy(share, sharename);231 strlower_m(share);232 233 keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);234 key = string_term_tdb_data(keystr ? keystr : "");235 236 return key;237 }238 239 /****************************************************************************240 generate a new TDB_DATA key for storing a printer security descriptor241 ****************************************************************************/242 243 static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,244 const char* sharename )245 {246 fstring share;247 char *keystr = NULL;248 TDB_DATA key;249 250 fstrcpy(share, sharename );251 strlower_m(share);252 253 keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);254 key = string_term_tdb_data(keystr ? keystr : "");255 256 return key;257 }258 259 /****************************************************************************260 ****************************************************************************/261 262 static bool upgrade_to_version_3(void)263 {264 TDB_DATA kbuf, newkey, dbuf;265 266 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));267 268 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;269 newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {270 271 dbuf = tdb_fetch(tdb_drivers, kbuf);272 273 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {274 DEBUG(0,("upgrade_to_version_3:moving form\n"));275 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {276 SAFE_FREE(dbuf.dptr);277 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));278 return False;279 }280 if (tdb_delete(tdb_drivers, kbuf) != 0) {281 SAFE_FREE(dbuf.dptr);282 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));283 return False;284 }285 }286 287 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {288 DEBUG(0,("upgrade_to_version_3:moving printer\n"));289 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {290 SAFE_FREE(dbuf.dptr);291 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));292 return False;293 }294 if (tdb_delete(tdb_drivers, kbuf) != 0) {295 SAFE_FREE(dbuf.dptr);296 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));297 return False;298 }299 }300 301 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {302 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));303 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {304 SAFE_FREE(dbuf.dptr);305 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));306 return False;307 }308 if (tdb_delete(tdb_drivers, kbuf) != 0) {309 SAFE_FREE(dbuf.dptr);310 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));311 return False;312 }313 }314 315 SAFE_FREE(dbuf.dptr);316 }317 318 return True;319 }320 321 /*******************************************************************322 Fix an issue with security descriptors. Printer sec_desc must323 use more than the generic bits that were previously used324 in <= 3.0.14a. They must also have a owner and group SID assigned.325 Otherwise, any printers than have been migrated to a Windows326 host using printmig.exe will not be accessible.327 *******************************************************************/328 329 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,330 TDB_DATA data, void *state )331 {332 NTSTATUS status;333 SEC_DESC_BUF *sd_orig = NULL;334 SEC_DESC_BUF *sd_new, *sd_store;335 SEC_DESC *sec, *new_sec;336 TALLOC_CTX *ctx = state;337 int result, i;338 uint32 sd_size;339 size_t size_new_sec;340 341 if (!data.dptr || data.dsize == 0) {342 return 0;343 }344 345 if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {346 return 0;347 }348 349 /* upgrade the security descriptor */350 351 status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);352 if (!NT_STATUS_IS_OK(status)) {353 /* delete bad entries */354 DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n",355 (const char *)key.dptr ));356 tdb_delete( tdb_printers, key );357 return 0;358 }359 360 if (!sd_orig) {361 return 0;362 }363 sec = sd_orig->sd;364 365 /* is this even valid? */366 367 if ( !sec->dacl ) {368 return 0;369 }370 371 /* update access masks */372 373 for ( i=0; i<sec->dacl->num_aces; i++ ) {374 switch ( sec->dacl->aces[i].access_mask ) {375 case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):376 sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;377 break;378 379 case GENERIC_ALL_ACCESS:380 sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;381 break;382 383 case READ_CONTROL_ACCESS:384 sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;385 386 default: /* no change */387 break;388 }389 }390 391 /* create a new SEC_DESC with the appropriate owner and group SIDs */392 393 new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,394 &global_sid_Builtin_Administrators,395 &global_sid_Builtin_Administrators,396 NULL, NULL, &size_new_sec );397 if (!new_sec) {398 return 0;399 }400 sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );401 if (!sd_new) {402 return 0;403 }404 405 if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {406 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));407 return 0;408 }409 410 /* store it back */411 412 sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)413 + sizeof(SEC_DESC_BUF);414 415 status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);416 if (!NT_STATUS_IS_OK(status)) {417 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));418 return 0;419 }420 421 result = tdb_store( tdb_printers, key, data, TDB_REPLACE );422 423 /* 0 to continue and non-zero to stop traversal */424 425 return (result == -1);426 }427 428 /*******************************************************************429 *******************************************************************/430 431 static bool upgrade_to_version_4(void)432 {433 TALLOC_CTX *ctx;434 int result;435 436 DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));437 438 if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )439 return False;440 441 result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );442 443 talloc_destroy( ctx );444 445 return ( result != -1 );446 }447 448 /*******************************************************************449 Fix an issue with security descriptors. Printer sec_desc must450 use more than the generic bits that were previously used451 in <= 3.0.14a. They must also have a owner and group SID assigned.452 Otherwise, any printers than have been migrated to a Windows453 host using printmig.exe will not be accessible.454 *******************************************************************/455 456 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,457 TDB_DATA data, void *state )458 {459 TALLOC_CTX *ctx = talloc_tos();460 TDB_DATA new_key;461 462 if (!data.dptr || data.dsize == 0)463 return 0;464 465 /* upgrade printer records and security descriptors */466 467 if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {468 new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );469 }470 else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {471 new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );472 }473 else {474 /* ignore this record */475 return 0;476 }477 478 /* delete the original record and store under the normalized key */479 480 if ( tdb_delete( the_tdb, key ) != 0 ) {481 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",482 key.dptr));483 return 1;484 }485 486 if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {487 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",488 key.dptr));489 return 1;490 }491 492 return 0;493 }494 495 /*******************************************************************496 *******************************************************************/497 498 static bool upgrade_to_version_5(void)499 {500 TALLOC_CTX *ctx;501 int result;502 503 DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));504 505 if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )506 return False;507 508 result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );509 510 talloc_destroy( ctx );511 512 return ( result != -1 );513 }514 515 76 /**************************************************************************** 516 77 Open the NT printing tdbs. Done once before fork(). … … 519 80 bool nt_printing_init(struct messaging_context *msg_ctx) 520 81 { 521 const char *vstring = "INFO/version";522 82 WERROR win_rc; 523 int32 vers_id; 524 525 if ( tdb_drivers && tdb_printers && tdb_forms ) 526 return True; 527 528 if (tdb_drivers) 529 tdb_close(tdb_drivers); 530 tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 531 if (!tdb_drivers) { 532 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n", 533 state_path("ntdrivers.tdb"), strerror(errno) )); 534 return False; 535 } 536 537 if (tdb_printers) 538 tdb_close(tdb_printers); 539 tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 540 if (!tdb_printers) { 541 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n", 542 state_path("ntprinters.tdb"), strerror(errno) )); 543 return False; 544 } 545 546 if (tdb_forms) 547 tdb_close(tdb_forms); 548 tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 549 if (!tdb_forms) { 550 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n", 551 state_path("ntforms.tdb"), strerror(errno) )); 552 return False; 553 } 554 555 /* handle a Samba upgrade */ 556 557 vers_id = tdb_fetch_int32(tdb_drivers, vstring); 558 if (vers_id == -1) { 559 DEBUG(10, ("Fresh database\n")); 560 tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 ); 561 vers_id = NTDRIVERS_DATABASE_VERSION_5; 562 } 563 564 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) { 565 566 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) { 567 if (!upgrade_to_version_3()) 568 return False; 569 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3); 570 vers_id = NTDRIVERS_DATABASE_VERSION_3; 571 } 572 573 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) { 574 /* Written on a bigendian machine with old fetch_int code. Save as le. */ 575 /* The only upgrade between V2 and V3 is to save the version in little-endian. */ 576 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3); 577 vers_id = NTDRIVERS_DATABASE_VERSION_3; 578 } 579 580 if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) { 581 if ( !upgrade_to_version_4() ) 582 return False; 583 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4); 584 vers_id = NTDRIVERS_DATABASE_VERSION_4; 585 } 586 587 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) { 588 if ( !upgrade_to_version_5() ) 589 return False; 590 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5); 591 vers_id = NTDRIVERS_DATABASE_VERSION_5; 592 } 593 594 595 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) { 596 DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id)); 597 return False; 598 } 599 } 600 601 update_c_setprinter(True); 83 84 if (!nt_printing_tdb_upgrade()) { 85 return false; 86 } 602 87 603 88 /* … … 605 90 * drivers are installed 606 91 */ 607 608 92 messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE, 609 93 do_drv_upgrade_printer); 610 94 611 /*612 * register callback to handle updating printer data613 * when a driver is initialized614 */615 616 messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,617 reset_all_printerdata);618 619 95 /* of course, none of the message callbacks matter if you don't 620 96 tell messages.c that you interested in receiving PRINT_GENERAL 621 msgs. This is done in claim_connection() */ 622 97 msgs. This is done in serverid_register() */ 623 98 624 99 if ( lp_security() == SEC_ADS ) { 625 win_rc = check_published_printers( );100 win_rc = check_published_printers(msg_ctx); 626 101 if (!W_ERROR_IS_OK(win_rc)) 627 102 DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc))); 628 103 } 629 104 630 return True;105 return true; 631 106 } 632 107 … … 661 136 } 662 137 663 /*******************************************************************664 tdb traversal function for counting printers.665 ********************************************************************/666 667 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,668 TDB_DATA data, void *context)669 {670 int *printer_count = (int*)context;671 672 if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {673 (*printer_count)++;674 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));675 }676 677 return 0;678 }679 680 /*******************************************************************681 Update the spooler global c_setprinter. This variable is initialized682 when the parent smbd starts with the number of existing printers. It683 is monotonically increased by the current number of printers *after*684 each add or delete printer RPC. Only Microsoft knows why... JRR020119685 ********************************************************************/686 687 uint32 update_c_setprinter(bool initialize)688 {689 int32 c_setprinter;690 int32 printer_count = 0;691 692 tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);693 694 /* Traverse the tdb, counting the printers */695 tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);696 697 /* If initializing, set c_setprinter to current printers count698 * otherwise, bump it by the current printer count699 */700 if (!initialize)701 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;702 else703 c_setprinter = printer_count;704 705 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));706 tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);707 708 tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);709 710 return (uint32)c_setprinter;711 }712 713 /*******************************************************************714 Get the spooler global c_setprinter, accounting for initialization.715 ********************************************************************/716 717 uint32 get_c_setprinter(void)718 {719 int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);720 721 if (c_setprinter == (int32)-1)722 c_setprinter = update_c_setprinter(True);723 724 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));725 726 return (uint32)c_setprinter;727 }728 729 /****************************************************************************730 Get builtin form struct list.731 ****************************************************************************/732 733 int get_builtin_ntforms(nt_forms_struct **list)734 {735 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));736 if (!*list) {737 return 0;738 }739 return ARRAY_SIZE(default_forms);740 }741 742 /****************************************************************************743 get a builtin form struct744 ****************************************************************************/745 746 bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)747 {748 int i;749 DEBUGADD(6,("Looking for builtin form %s \n", form_name));750 for (i=0; i<ARRAY_SIZE(default_forms); i++) {751 if (strequal(form_name,default_forms[i].name)) {752 DEBUGADD(6,("Found builtin form %s \n", form_name));753 memcpy(form,&default_forms[i],sizeof(*form));754 return true;755 }756 }757 758 return false;759 }760 761 /****************************************************************************762 get a form struct list.763 ****************************************************************************/764 765 int get_ntforms(nt_forms_struct **list)766 {767 TDB_DATA kbuf, newkey, dbuf;768 nt_forms_struct form;769 int ret;770 int i;771 int n = 0;772 773 *list = NULL;774 775 for (kbuf = tdb_firstkey(tdb_forms);776 kbuf.dptr;777 newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)778 {779 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)780 continue;781 782 dbuf = tdb_fetch(tdb_forms, kbuf);783 if (!dbuf.dptr)784 continue;785 786 fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));787 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",788 &i, &form.flag, &form.width, &form.length, &form.left,789 &form.top, &form.right, &form.bottom);790 SAFE_FREE(dbuf.dptr);791 if (ret != dbuf.dsize)792 continue;793 794 *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);795 if (!*list) {796 DEBUG(0,("get_ntforms: Realloc fail.\n"));797 return 0;798 }799 (*list)[n] = form;800 n++;801 }802 803 804 return n;805 }806 807 /****************************************************************************808 write a form struct list809 ****************************************************************************/810 811 int write_ntforms(nt_forms_struct **list, int number)812 {813 TALLOC_CTX *ctx = talloc_tos();814 char *buf = NULL;815 char *key = NULL;816 int len;817 TDB_DATA dbuf;818 int i;819 820 for (i=0;i<number;i++) {821 /* save index, so list is rebuilt in correct order */822 len = tdb_pack(NULL, 0, "dddddddd",823 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,824 (*list)[i].left, (*list)[i].top, (*list)[i].right,825 (*list)[i].bottom);826 if (!len) {827 continue;828 }829 buf = TALLOC_ARRAY(ctx, char, len);830 if (!buf) {831 return 0;832 }833 len = tdb_pack((uint8 *)buf, len, "dddddddd",834 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,835 (*list)[i].left, (*list)[i].top, (*list)[i].right,836 (*list)[i].bottom);837 key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);838 if (!key) {839 return 0;840 }841 dbuf.dsize = len;842 dbuf.dptr = (uint8 *)buf;843 if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {844 TALLOC_FREE(key);845 TALLOC_FREE(buf);846 break;847 }848 TALLOC_FREE(key);849 TALLOC_FREE(buf);850 }851 852 return i;853 }854 855 /****************************************************************************856 add a form struct at the end of the list857 ****************************************************************************/858 bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)859 {860 int n=0;861 bool update;862 863 /*864 * NT tries to add forms even when865 * they are already in the base866 * only update the values if already present867 */868 869 update=False;870 871 for (n=0; n<*count; n++) {872 if ( strequal((*list)[n].name, form->form_name) ) {873 update=True;874 break;875 }876 }877 878 if (update==False) {879 if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {880 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));881 return False;882 }883 fstrcpy((*list)[n].name, form->form_name);884 (*count)++;885 }886 887 (*list)[n].flag = form->flags;888 (*list)[n].width = form->size.width;889 (*list)[n].length = form->size.height;890 (*list)[n].left = form->area.left;891 (*list)[n].top = form->area.top;892 (*list)[n].right = form->area.right;893 (*list)[n].bottom = form->area.bottom;894 895 DEBUG(6,("add_a_form: Successfully %s form [%s]\n",896 update ? "updated" : "added", form->form_name));897 898 return True;899 }900 901 /****************************************************************************902 Delete a named form struct.903 ****************************************************************************/904 905 bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)906 {907 char *key = NULL;908 int n=0;909 910 *ret = WERR_OK;911 912 for (n=0; n<*count; n++) {913 if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {914 DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));915 break;916 }917 }918 919 if (n == *count) {920 DEBUG(10,("delete_a_form, [%s] not found\n", del_name));921 *ret = WERR_INVALID_PARAM;922 return False;923 }924 925 if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {926 *ret = WERR_NOMEM;927 return false;928 }929 if (tdb_delete_bystring(tdb_forms, key) != 0) {930 SAFE_FREE(key);931 *ret = WERR_NOMEM;932 return False;933 }934 SAFE_FREE(key);935 return true;936 }937 938 /****************************************************************************939 Update a form struct.940 ****************************************************************************/941 942 void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)943 {944 int n=0;945 946 DEBUG(106, ("[%s]\n", form->form_name));947 for (n=0; n<count; n++) {948 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));949 if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))950 break;951 }952 953 if (n==count) return;954 955 (*list)[n].flag = form->flags;956 (*list)[n].width = form->size.width;957 (*list)[n].length = form->size.height;958 (*list)[n].left = form->area.left;959 (*list)[n].top = form->area.top;960 (*list)[n].right = form->area.right;961 (*list)[n].bottom = form->area.bottom;962 }963 964 /****************************************************************************965 Get the nt drivers list.966 Traverse the database and look-up the matching names.967 ****************************************************************************/968 int get_ntdrivers(fstring **list, const char *architecture, uint32 version)969 {970 int total=0;971 const char *short_archi;972 char *key = NULL;973 TDB_DATA kbuf, newkey;974 975 short_archi = get_short_archi(architecture);976 if (!short_archi) {977 return 0;978 }979 980 if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX,981 short_archi, version) < 0) {982 return 0;983 }984 985 for (kbuf = tdb_firstkey(tdb_drivers);986 kbuf.dptr;987 newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {988 989 if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)990 continue;991 992 if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {993 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));994 SAFE_FREE(key);995 return -1;996 }997 998 fstrcpy((*list)[total], (const char *)kbuf.dptr+strlen(key));999 total++;1000 }1001 1002 SAFE_FREE(key);1003 return(total);1004 }1005 1006 138 /**************************************************************************** 1007 139 Function to do the mapping between the long architecture name and … … 1013 145 int i=-1; 1014 146 1015 DEBUG(107,("Getting architecture depend ant directory\n"));147 DEBUG(107,("Getting architecture dependent directory\n")); 1016 148 do { 1017 149 i++; … … 1316 448 INTERNAL_OPEN_ONLY, /* oplock_request */ 1317 449 0, /* allocation_size */ 450 0, /* private_flags */ 1318 451 NULL, /* sd */ 1319 452 NULL, /* ea_list */ … … 1368 501 INTERNAL_OPEN_ONLY, /* oplock_request */ 1369 502 0, /* allocation_size */ 503 0, /* private_flags */ 1370 504 NULL, /* sd */ 1371 505 NULL, /* ea_list */ … … 1441 575 Determine the correct cVersion associated with an architecture and driver 1442 576 ****************************************************************************/ 1443 static uint32 get_correct_cversion(struct pipes_struct *p,577 static uint32 get_correct_cversion(struct auth_serversupplied_info *session_info, 1444 578 const char *architecture, 1445 579 const char *driverpath_in, 1446 580 WERROR *perr) 1447 581 { 1448 int cversion;582 int cversion = -1; 1449 583 NTSTATUS nt_status; 1450 584 struct smb_filename *smb_fname = NULL; … … 1452 586 files_struct *fsp = NULL; 1453 587 connection_struct *conn = NULL; 1454 NTSTATUS status;1455 588 char *oldcwd; 1456 fstring printdollar;589 char *printdollar = NULL; 1457 590 int printdollar_snum; 1458 591 … … 1473 606 } 1474 607 1475 fstrcpy(printdollar, "print$"); 1476 1477 printdollar_snum = find_service(printdollar); 608 printdollar_snum = find_service(talloc_tos(), "print$", &printdollar); 609 if (!printdollar) { 610 *perr = WERR_NOMEM; 611 return -1; 612 } 1478 613 if (printdollar_snum == -1) { 1479 614 *perr = WERR_NO_SUCH_SHARE; … … 1483 618 nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum, 1484 619 lp_pathname(printdollar_snum), 1485 p->server_info, &oldcwd);620 session_info, &oldcwd); 1486 621 if (!NT_STATUS_IS_OK(nt_status)) { 1487 622 DEBUG(0,("get_correct_cversion: create_conn_struct " … … 1489 624 *perr = ntstatus_to_werror(nt_status); 1490 625 return -1; 626 } 627 628 nt_status = set_conn_force_user_group(conn, printdollar_snum); 629 if (!NT_STATUS_IS_OK(nt_status)) { 630 DEBUG(0, ("failed set force user / group\n")); 631 *perr = ntstatus_to_werror(nt_status); 632 goto error_free_conn; 633 } 634 635 if (!become_user_by_session(conn, session_info)) { 636 DEBUG(0, ("failed to become user\n")); 637 *perr = WERR_ACCESS_DENIED; 638 goto error_free_conn; 1491 639 } 1492 640 … … 1510 658 nt_status = vfs_file_exist(conn, smb_fname); 1511 659 if (!NT_STATUS_IS_OK(nt_status)) { 660 DEBUG(3,("get_correct_cversion: vfs_file_exist failed\n")); 1512 661 *perr = WERR_BADFILE; 1513 662 goto error_exit; 1514 663 } 1515 664 1516 status = SMB_VFS_CREATE_FILE(665 nt_status = SMB_VFS_CREATE_FILE( 1517 666 conn, /* conn */ 1518 667 NULL, /* req */ … … 1525 674 FILE_ATTRIBUTE_NORMAL, /* file_attributes */ 1526 675 INTERNAL_OPEN_ONLY, /* oplock_request */ 676 0, /* private_flags */ 1527 677 0, /* allocation_size */ 1528 678 NULL, /* sd */ … … 1531 681 NULL); /* pinfo */ 1532 682 1533 if (!NT_STATUS_IS_OK( status)) {683 if (!NT_STATUS_IS_OK(nt_status)) { 1534 684 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = " 1535 685 "%d\n", smb_fname_str_dbg(smb_fname), errno)); … … 1542 692 1543 693 ret = get_file_version(fsp, smb_fname->base_name, &major, &minor); 1544 if (ret == -1) goto error_exit; 1545 1546 if (!ret) { 694 if (ret == -1) { 695 *perr = WERR_INVALID_PARAM; 696 goto error_exit; 697 } else if (!ret) { 1547 698 DEBUG(6,("get_correct_cversion: Version info not " 1548 699 "found [%s]\n", 1549 700 smb_fname_str_dbg(smb_fname))); 701 *perr = WERR_INVALID_PARAM; 1550 702 goto error_exit; 1551 703 } … … 1579 731 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n", 1580 732 smb_fname_str_dbg(smb_fname), cversion)); 1581 1582 goto done; 733 *perr = WERR_OK; 1583 734 1584 735 error_exit: 1585 cversion = -1;1586 done:736 unbecome_user(); 737 error_free_conn: 1587 738 TALLOC_FREE(smb_fname); 1588 739 if (fsp != NULL) { … … 1591 742 if (conn != NULL) { 1592 743 vfs_ChDir(conn, oldcwd); 744 SMB_VFS_DISCONNECT(conn); 1593 745 conn_free(conn); 1594 746 } 1595 if (cversion != -1) { 1596 *perr = WERR_OK; 1597 } 747 if (!NT_STATUS_IS_OK(*perr)) { 748 cversion = -1; 749 } 750 1598 751 return cversion; 1599 752 } … … 1610 763 1611 764 static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx, 1612 struct pipes_struct *rpc_pipe,765 struct auth_serversupplied_info *session_info, 1613 766 const char *architecture, 1614 767 const char **driver_path, … … 1617 770 const char **help_file, 1618 771 struct spoolss_StringArray *dependent_files, 1619 uint32_t*version)772 enum spoolss_DriverOSVersion *version) 1620 773 { 1621 774 const char *short_architecture; … … 1670 823 */ 1671 824 1672 *version = get_correct_cversion( rpc_pipe, short_architecture,825 *version = get_correct_cversion(session_info, short_architecture, 1673 826 *driver_path, &err); 1674 827 if (*version == -1) { … … 1682 835 ****************************************************************************/ 1683 836 1684 WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe, 837 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx, 838 struct auth_serversupplied_info *session_info, 1685 839 struct spoolss_AddDriverInfoCtr *r) 1686 840 { 1687 841 switch (r->level) { 1688 842 case 3: 1689 return clean_up_driver_struct_level( r, rpc_pipe,843 return clean_up_driver_struct_level(mem_ctx, session_info, 1690 844 r->info.info3->architecture, 1691 845 &r->info.info3->driver_path, … … 1696 850 &r->info.info3->version); 1697 851 case 6: 1698 return clean_up_driver_struct_level( r, rpc_pipe,852 return clean_up_driver_struct_level(mem_ctx, session_info, 1699 853 r->info.info6->architecture, 1700 854 &r->info.info6->driver_path, … … 1731 885 1732 886 /**************************************************************************** 1733 This function sucks and should be replaced. JRA.1734 ****************************************************************************/1735 1736 static void convert_level_8_to_level3(TALLOC_CTX *mem_ctx,1737 struct spoolss_AddDriverInfo3 *dst,1738 const struct spoolss_DriverInfo8 *src)1739 {1740 dst->version = src->version;1741 dst->driver_name = src->driver_name;1742 dst->architecture = src->architecture;1743 dst->driver_path = src->driver_path;1744 dst->data_file = src->data_file;1745 dst->config_file = src->config_file;1746 dst->help_file = src->help_file;1747 dst->monitor_name = src->monitor_name;1748 dst->default_datatype = src->default_datatype;1749 if (src->dependent_files) {1750 dst->dependent_files = talloc_zero(mem_ctx, struct spoolss_StringArray);1751 if (!dst->dependent_files) return;1752 dst->dependent_files->string = src->dependent_files;1753 } else {1754 dst->dependent_files = NULL;1755 }1756 }1757 1758 /****************************************************************************1759 887 ****************************************************************************/ 1760 888 … … 1827 955 } 1828 956 1829 WERROR move_driver_to_download_area(struct pipes_struct *p, 1830 struct spoolss_AddDriverInfoCtr *r, 1831 WERROR *perr) 957 WERROR move_driver_to_download_area(struct auth_serversupplied_info *session_info, 958 struct spoolss_AddDriverInfoCtr *r) 1832 959 { 1833 960 struct spoolss_AddDriverInfo3 *driver; … … 1842 969 int ver = 0; 1843 970 char *oldcwd; 1844 fstring printdollar;971 char *printdollar = NULL; 1845 972 int printdollar_snum; 1846 1847 *perr = WERR_OK; 973 WERROR err = WERR_OK; 1848 974 1849 975 switch (r->level) { … … 1865 991 } 1866 992 1867 fstrcpy(printdollar, "print$"); 1868 1869 printdollar_snum = find_service(printdollar); 993 printdollar_snum = find_service(ctx, "print$", &printdollar); 994 if (!printdollar) { 995 return WERR_NOMEM; 996 } 1870 997 if (printdollar_snum == -1) { 1871 *perr = WERR_NO_SUCH_SHARE;1872 998 return WERR_NO_SUCH_SHARE; 1873 999 } … … 1875 1001 nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum, 1876 1002 lp_pathname(printdollar_snum), 1877 p->server_info, &oldcwd);1003 session_info, &oldcwd); 1878 1004 if (!NT_STATUS_IS_OK(nt_status)) { 1879 1005 DEBUG(0,("move_driver_to_download_area: create_conn_struct " 1880 1006 "returned %s\n", nt_errstr(nt_status))); 1881 *perr = ntstatus_to_werror(nt_status); 1882 return *perr; 1007 err = ntstatus_to_werror(nt_status); 1008 return err; 1009 } 1010 1011 nt_status = set_conn_force_user_group(conn, printdollar_snum); 1012 if (!NT_STATUS_IS_OK(nt_status)) { 1013 DEBUG(0, ("failed set force user / group\n")); 1014 err = ntstatus_to_werror(nt_status); 1015 goto err_free_conn; 1016 } 1017 1018 if (!become_user_by_session(conn, session_info)) { 1019 DEBUG(0, ("failed to become user\n")); 1020 err = WERR_ACCESS_DENIED; 1021 goto err_free_conn; 1883 1022 } 1884 1023 … … 1888 1027 driver->version); 1889 1028 if (!new_dir) { 1890 *perr = WERR_NOMEM;1029 err = WERR_NOMEM; 1891 1030 goto err_exit; 1892 1031 } 1893 1032 nt_status = driver_unix_convert(conn, new_dir, &smb_dname); 1894 1033 if (!NT_STATUS_IS_OK(nt_status)) { 1895 *perr = WERR_NOMEM;1034 err = WERR_NOMEM; 1896 1035 goto err_exit; 1897 1036 } … … 1899 1038 DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name)); 1900 1039 1901 create_directory(conn, NULL, smb_dname); 1040 nt_status = create_directory(conn, NULL, smb_dname); 1041 if (!NT_STATUS_IS_OK(nt_status) 1042 && !NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_COLLISION)) { 1043 DEBUG(0, ("failed to create driver destination directory: %s\n", 1044 nt_errstr(nt_status))); 1045 err = ntstatus_to_werror(nt_status); 1046 goto err_exit; 1047 } 1902 1048 1903 1049 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file … … 1922 1068 if (driver->driver_path && strlen(driver->driver_path)) { 1923 1069 1924 *perr = move_driver_file_to_download_area(ctx, 1925 conn, 1926 driver->driver_path, 1927 short_architecture, 1928 driver->version, 1929 ver); 1930 if (!W_ERROR_IS_OK(*perr)) { 1931 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1932 ver = -1; 1933 } 1070 err = move_driver_file_to_download_area(ctx, 1071 conn, 1072 driver->driver_path, 1073 short_architecture, 1074 driver->version, 1075 ver); 1076 if (!W_ERROR_IS_OK(err)) { 1934 1077 goto err_exit; 1935 1078 } … … 1939 1082 if (!strequal(driver->data_file, driver->driver_path)) { 1940 1083 1941 *perr = move_driver_file_to_download_area(ctx, 1942 conn, 1943 driver->data_file, 1944 short_architecture, 1945 driver->version, 1946 ver); 1947 if (!W_ERROR_IS_OK(*perr)) { 1948 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1949 ver = -1; 1950 } 1084 err = move_driver_file_to_download_area(ctx, 1085 conn, 1086 driver->data_file, 1087 short_architecture, 1088 driver->version, 1089 ver); 1090 if (!W_ERROR_IS_OK(err)) { 1951 1091 goto err_exit; 1952 1092 } … … 1958 1098 !strequal(driver->config_file, driver->data_file)) { 1959 1099 1960 *perr = move_driver_file_to_download_area(ctx, 1961 conn, 1962 driver->config_file, 1963 short_architecture, 1964 driver->version, 1965 ver); 1966 if (!W_ERROR_IS_OK(*perr)) { 1967 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1968 ver = -1; 1969 } 1100 err = move_driver_file_to_download_area(ctx, 1101 conn, 1102 driver->config_file, 1103 short_architecture, 1104 driver->version, 1105 ver); 1106 if (!W_ERROR_IS_OK(err)) { 1970 1107 goto err_exit; 1971 1108 } … … 1978 1115 !strequal(driver->help_file, driver->config_file)) { 1979 1116 1980 *perr = move_driver_file_to_download_area(ctx, 1981 conn, 1982 driver->help_file, 1983 short_architecture, 1984 driver->version, 1985 ver); 1986 if (!W_ERROR_IS_OK(*perr)) { 1987 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1988 ver = -1; 1989 } 1117 err = move_driver_file_to_download_area(ctx, 1118 conn, 1119 driver->help_file, 1120 short_architecture, 1121 driver->version, 1122 ver); 1123 if (!W_ERROR_IS_OK(err)) { 1990 1124 goto err_exit; 1991 1125 } … … 2006 1140 } 2007 1141 2008 *perr = move_driver_file_to_download_area(ctx, 2009 conn, 2010 driver->dependent_files->string[i], 2011 short_architecture, 2012 driver->version, 2013 ver); 2014 if (!W_ERROR_IS_OK(*perr)) { 2015 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 2016 ver = -1; 2017 } 1142 err = move_driver_file_to_download_area(ctx, 1143 conn, 1144 driver->dependent_files->string[i], 1145 short_architecture, 1146 driver->version, 1147 ver); 1148 if (!W_ERROR_IS_OK(err)) { 2018 1149 goto err_exit; 2019 1150 } … … 2023 1154 } 2024 1155 2025 err_exit: 1156 err = WERR_OK; 1157 err_exit: 1158 unbecome_user(); 1159 err_free_conn: 2026 1160 TALLOC_FREE(smb_dname); 2027 1161 2028 1162 if (conn != NULL) { 2029 1163 vfs_ChDir(conn, oldcwd); 1164 SMB_VFS_DISCONNECT(conn); 2030 1165 conn_free(conn); 2031 1166 } 2032 1167 2033 if (W_ERROR_EQUAL(*perr, WERR_OK)) { 2034 return WERR_OK; 2035 } 2036 if (ver == -1) { 2037 return WERR_UNKNOWN_PRINTER_DRIVER; 2038 } 2039 return (*perr); 2040 } 2041 2042 /**************************************************************************** 2043 ****************************************************************************/ 2044 2045 static uint32 add_a_printer_driver_3(struct spoolss_AddDriverInfo3 *driver) 2046 { 2047 TALLOC_CTX *ctx = talloc_tos(); 2048 int len, buflen; 2049 const char *architecture; 2050 char *directory = NULL; 2051 char *key = NULL; 2052 uint8 *buf; 2053 int i, ret; 2054 TDB_DATA dbuf; 2055 2056 architecture = get_short_archi(driver->architecture); 2057 if (!architecture) { 2058 return (uint32)-1; 2059 } 2060 2061 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx 2062 * \\server is added in the rpc server layer. 2063 * It does make sense to NOT store the server's name in the printer TDB. 2064 */ 2065 2066 directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\", 2067 architecture, driver->version); 2068 if (!directory) { 2069 return (uint32)-1; 2070 } 2071 2072 #define gen_full_driver_unc_path(ctx, directory, file) \ 2073 do { \ 2074 if (file && strlen(file)) { \ 2075 file = talloc_asprintf(ctx, "%s%s", directory, file); \ 2076 } else { \ 2077 file = talloc_strdup(ctx, ""); \ 2078 } \ 2079 if (!file) { \ 2080 return (uint32_t)-1; \ 2081 } \ 2082 } while (0); 2083 2084 /* .inf files do not always list a file for each of the four standard files. 2085 * Don't prepend a path to a null filename, or client claims: 2086 * "The server on which the printer resides does not have a suitable 2087 * <printer driver name> printer driver installed. Click OK if you 2088 * wish to install the driver on your local machine." 2089 */ 2090 2091 gen_full_driver_unc_path(ctx, directory, driver->driver_path); 2092 gen_full_driver_unc_path(ctx, directory, driver->data_file); 2093 gen_full_driver_unc_path(ctx, directory, driver->config_file); 2094 gen_full_driver_unc_path(ctx, directory, driver->help_file); 2095 2096 if (driver->dependent_files && driver->dependent_files->string) { 2097 for (i=0; driver->dependent_files->string[i]; i++) { 2098 gen_full_driver_unc_path(ctx, directory, 2099 driver->dependent_files->string[i]); 2100 } 2101 } 2102 2103 key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX, 2104 architecture, driver->version, driver->driver_name); 2105 if (!key) { 2106 return (uint32)-1; 2107 } 2108 2109 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key )); 2110 2111 buf = NULL; 2112 len = buflen = 0; 2113 2114 again: 2115 len = 0; 2116 len += tdb_pack(buf+len, buflen-len, "dffffffff", 2117 driver->version, 2118 driver->driver_name, 2119 driver->architecture, 2120 driver->driver_path, 2121 driver->data_file, 2122 driver->config_file, 2123 driver->help_file, 2124 driver->monitor_name ? driver->monitor_name : "", 2125 driver->default_datatype ? driver->default_datatype : ""); 2126 2127 if (driver->dependent_files && driver->dependent_files->string) { 2128 for (i=0; driver->dependent_files->string[i]; i++) { 2129 len += tdb_pack(buf+len, buflen-len, "f", 2130 driver->dependent_files->string[i]); 2131 } 2132 } 2133 2134 if (len != buflen) { 2135 buf = (uint8 *)SMB_REALLOC(buf, len); 2136 if (!buf) { 2137 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!")); 2138 ret = -1; 2139 goto done; 2140 } 2141 buflen = len; 2142 goto again; 2143 } 2144 2145 dbuf.dptr = buf; 2146 dbuf.dsize = len; 2147 2148 ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE); 2149 2150 done: 2151 if (ret) 2152 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key )); 2153 2154 SAFE_FREE(buf); 2155 return ret; 2156 } 2157 2158 /**************************************************************************** 2159 ****************************************************************************/ 2160 2161 static uint32_t add_a_printer_driver_8(struct spoolss_DriverInfo8 *driver) 2162 { 2163 TALLOC_CTX *mem_ctx = talloc_new(talloc_tos()); 2164 struct spoolss_AddDriverInfo3 info3; 2165 uint32_t ret; 2166 2167 convert_level_8_to_level3(mem_ctx, &info3, driver); 2168 2169 ret = add_a_printer_driver_3(&info3); 2170 talloc_free(mem_ctx); 2171 2172 return ret; 2173 } 2174 2175 /**************************************************************************** 2176 ****************************************************************************/ 2177 2178 static WERROR get_a_printer_driver_3_default(TALLOC_CTX *mem_ctx, 2179 struct spoolss_DriverInfo3 *info, 2180 const char *driver, const char *arch) 2181 { 2182 info->driver_name = talloc_strdup(mem_ctx, driver); 2183 if (!info->driver_name) { 2184 return WERR_NOMEM; 2185 } 2186 2187 info->default_datatype = talloc_strdup(mem_ctx, "RAW"); 2188 if (!info->default_datatype) { 2189 return WERR_NOMEM; 2190 } 2191 2192 info->driver_path = talloc_strdup(mem_ctx, ""); 2193 info->data_file = talloc_strdup(mem_ctx, ""); 2194 info->config_file = talloc_strdup(mem_ctx, ""); 2195 info->help_file = talloc_strdup(mem_ctx, ""); 2196 if (!info->driver_path || !info->data_file || !info->config_file || !info->help_file) { 2197 return WERR_NOMEM; 2198 } 2199 2200 return WERR_OK; 2201 } 2202 2203 /**************************************************************************** 2204 ****************************************************************************/ 2205 2206 static WERROR get_a_printer_driver_3(TALLOC_CTX *mem_ctx, 2207 struct spoolss_DriverInfo3 *driver, 2208 const char *drivername, const char *arch, 2209 uint32_t version) 2210 { 2211 TDB_DATA dbuf; 2212 const char *architecture; 2213 int len = 0; 2214 int i; 2215 char *key = NULL; 2216 fstring name, driverpath, environment, datafile, configfile, helpfile, monitorname, defaultdatatype; 2217 2218 architecture = get_short_archi(arch); 2219 if ( !architecture ) { 2220 return WERR_UNKNOWN_PRINTER_DRIVER; 2221 } 2222 2223 /* Windows 4.0 (i.e. win9x) should always use a version of 0 */ 2224 2225 if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 ) 2226 version = 0; 2227 2228 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername)); 2229 2230 if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX, 2231 architecture, version, drivername) < 0) { 2232 return WERR_NOMEM; 2233 } 2234 2235 dbuf = tdb_fetch_bystring(tdb_drivers, key); 2236 if (!dbuf.dptr) { 2237 SAFE_FREE(key); 2238 return WERR_UNKNOWN_PRINTER_DRIVER; 2239 } 2240 2241 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 2242 &driver->version, 2243 name, 2244 environment, 2245 driverpath, 2246 datafile, 2247 configfile, 2248 helpfile, 2249 monitorname, 2250 defaultdatatype); 2251 2252 driver->driver_name = talloc_strdup(mem_ctx, name); 2253 driver->architecture = talloc_strdup(mem_ctx, environment); 2254 driver->driver_path = talloc_strdup(mem_ctx, driverpath); 2255 driver->data_file = talloc_strdup(mem_ctx, datafile); 2256 driver->config_file = talloc_strdup(mem_ctx, configfile); 2257 driver->help_file = talloc_strdup(mem_ctx, helpfile); 2258 driver->monitor_name = talloc_strdup(mem_ctx, monitorname); 2259 driver->default_datatype = talloc_strdup(mem_ctx, defaultdatatype); 2260 2261 i=0; 2262 2263 while (len < dbuf.dsize) { 2264 2265 fstring file; 2266 2267 driver->dependent_files = talloc_realloc(mem_ctx, driver->dependent_files, const char *, i+2); 2268 if (!driver->dependent_files ) { 2269 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n")); 2270 break; 2271 } 2272 2273 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 2274 &file); 2275 2276 driver->dependent_files[i] = talloc_strdup(mem_ctx, file); 2277 2278 i++; 2279 } 2280 2281 if (driver->dependent_files) 2282 driver->dependent_files[i] = NULL; 2283 2284 SAFE_FREE(dbuf.dptr); 2285 SAFE_FREE(key); 2286 2287 if (len != dbuf.dsize) { 2288 return get_a_printer_driver_3_default(mem_ctx, driver, drivername, arch); 2289 } 2290 2291 return WERR_OK; 2292 } 2293 2294 /**************************************************************************** 2295 ****************************************************************************/ 2296 int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen) 2297 { 2298 int len = 0; 2299 2300 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode); 2301 2302 if (!nt_devmode) 2303 return len; 2304 2305 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp", 2306 nt_devmode->devicename, 2307 nt_devmode->formname, 2308 2309 nt_devmode->specversion, 2310 nt_devmode->driverversion, 2311 nt_devmode->size, 2312 nt_devmode->driverextra, 2313 nt_devmode->orientation, 2314 nt_devmode->papersize, 2315 nt_devmode->paperlength, 2316 nt_devmode->paperwidth, 2317 nt_devmode->scale, 2318 nt_devmode->copies, 2319 nt_devmode->defaultsource, 2320 nt_devmode->printquality, 2321 nt_devmode->color, 2322 nt_devmode->duplex, 2323 nt_devmode->yresolution, 2324 nt_devmode->ttoption, 2325 nt_devmode->collate, 2326 nt_devmode->logpixels, 2327 2328 nt_devmode->fields, 2329 nt_devmode->bitsperpel, 2330 nt_devmode->pelswidth, 2331 nt_devmode->pelsheight, 2332 nt_devmode->displayflags, 2333 nt_devmode->displayfrequency, 2334 nt_devmode->icmmethod, 2335 nt_devmode->icmintent, 2336 nt_devmode->mediatype, 2337 nt_devmode->dithertype, 2338 nt_devmode->reserved1, 2339 nt_devmode->reserved2, 2340 nt_devmode->panningwidth, 2341 nt_devmode->panningheight, 2342 nt_devmode->nt_dev_private); 2343 2344 if (nt_devmode->nt_dev_private) { 2345 len += tdb_pack(buf+len, buflen-len, "B", 2346 nt_devmode->driverextra, 2347 nt_devmode->nt_dev_private); 2348 } 2349 2350 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname)); 2351 2352 return len; 2353 } 2354 2355 /**************************************************************************** 2356 Pack all values in all printer keys 2357 ***************************************************************************/ 2358 2359 static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen) 2360 { 2361 int len = 0; 2362 int i, j; 2363 struct regval_blob *val; 2364 struct regval_ctr *val_ctr; 2365 char *path = NULL; 2366 int num_values; 2367 2368 if ( !data ) 2369 return 0; 2370 2371 /* loop over all keys */ 2372 2373 for ( i=0; i<data->num_keys; i++ ) { 2374 val_ctr = data->keys[i].values; 2375 num_values = regval_ctr_numvals( val_ctr ); 2376 2377 /* pack the keyname followed by a empty value */ 2378 2379 len += tdb_pack(buf+len, buflen-len, "pPdB", 2380 &data->keys[i].name, 2381 data->keys[i].name, 2382 REG_NONE, 2383 0, 2384 NULL); 2385 2386 /* now loop over all values */ 2387 2388 for ( j=0; j<num_values; j++ ) { 2389 /* pathname should be stored as <key>\<value> */ 2390 2391 val = regval_ctr_specific_value( val_ctr, j ); 2392 if (asprintf(&path, "%s\\%s", 2393 data->keys[i].name, 2394 regval_name(val)) < 0) { 2395 return -1; 2396 } 2397 2398 len += tdb_pack(buf+len, buflen-len, "pPdB", 2399 val, 2400 path, 2401 regval_type(val), 2402 regval_size(val), 2403 regval_data_p(val) ); 2404 2405 DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val))); 2406 SAFE_FREE(path); 2407 } 2408 2409 } 2410 2411 /* terminator */ 2412 2413 len += tdb_pack(buf+len, buflen-len, "p", NULL); 2414 2415 return len; 2416 } 2417 2418 2419 /**************************************************************************** 2420 Delete a printer - this just deletes the printer info file, any open 2421 handles are not affected. 2422 ****************************************************************************/ 2423 2424 uint32 del_a_printer(const char *sharename) 2425 { 2426 TDB_DATA kbuf; 2427 char *printdb_path = NULL; 2428 TALLOC_CTX *ctx = talloc_tos(); 2429 2430 kbuf = make_printer_tdbkey(ctx, sharename); 2431 tdb_delete(tdb_printers, kbuf); 2432 2433 kbuf= make_printers_secdesc_tdbkey(ctx, sharename); 2434 tdb_delete(tdb_printers, kbuf); 2435 2436 close_all_print_db(); 2437 2438 if (geteuid() == sec_initial_uid()) { 2439 if (asprintf(&printdb_path, "%s%s.tdb", 2440 cache_path("printing/"), 2441 sharename) < 0) { 2442 return (uint32)-1; 2443 } 2444 unlink(printdb_path); 2445 SAFE_FREE(printdb_path); 2446 } 2447 2448 return 0; 2449 } 2450 2451 /**************************************************************************** 2452 ****************************************************************************/ 2453 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) 2454 { 2455 uint8 *buf; 2456 int buflen, len; 2457 int retlen; 2458 WERROR ret; 2459 TDB_DATA kbuf, dbuf; 2460 2461 /* 2462 * in addprinter: no servername and the printer is the name 2463 * in setprinter: servername is \\server 2464 * and printer is \\server\\printer 2465 * 2466 * Samba manages only local printers. 2467 * we currently don't support things like i 2468 * path=\\other_server\printer 2469 * 2470 * We only store the printername, not \\server\printername 2471 */ 2472 2473 if ( info->servername[0] != '\0' ) { 2474 trim_string(info->printername, info->servername, NULL); 2475 trim_char(info->printername, '\\', '\0'); 2476 info->servername[0]='\0'; 2477 } 2478 2479 /* 2480 * JFM: one day I'll forget. 2481 * below that's info->portname because that's the SAMBA sharename 2482 * and I made NT 'thinks' it's the portname 2483 * the info->sharename is the thing you can name when you add a printer 2484 * that's the short-name when you create shared printer for 95/98 2485 * So I've made a limitation in SAMBA: you can only have 1 printer model 2486 * behind a SAMBA share. 2487 */ 2488 2489 buf = NULL; 2490 buflen = 0; 2491 2492 again: 2493 len = 0; 2494 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff", 2495 info->attributes, 2496 info->priority, 2497 info->default_priority, 2498 info->starttime, 2499 info->untiltime, 2500 info->status, 2501 info->cjobs, 2502 info->averageppm, 2503 info->changeid, 2504 info->c_setprinter, 2505 info->setuptime, 2506 info->servername, 2507 info->printername, 2508 info->sharename, 2509 info->portname, 2510 info->drivername, 2511 info->comment, 2512 info->location, 2513 info->sepfile, 2514 info->printprocessor, 2515 info->datatype, 2516 info->parameters); 2517 2518 len += pack_devicemode(info->devmode, buf+len, buflen-len); 2519 retlen = pack_values( info->data, buf+len, buflen-len ); 2520 if (retlen == -1) { 2521 ret = WERR_NOMEM; 2522 goto done; 2523 } 2524 len += retlen; 2525 2526 if (buflen != len) { 2527 buf = (uint8 *)SMB_REALLOC(buf, len); 2528 if (!buf) { 2529 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n")); 2530 ret = WERR_NOMEM; 2531 goto done; 2532 } 2533 buflen = len; 2534 goto again; 2535 } 2536 2537 kbuf = make_printer_tdbkey(talloc_tos(), info->sharename ); 2538 2539 dbuf.dptr = buf; 2540 dbuf.dsize = len; 2541 2542 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM); 2543 2544 done: 2545 if (!W_ERROR_IS_OK(ret)) 2546 DEBUG(8, ("error updating printer to tdb on disk\n")); 2547 2548 SAFE_FREE(buf); 2549 2550 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 2551 info->sharename, info->drivername, info->portname, len)); 2552 2553 return ret; 2554 } 2555 2556 2557 /**************************************************************************** 2558 Malloc and return an NT devicemode. 2559 ****************************************************************************/ 2560 2561 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename) 2562 { 2563 2564 char adevice[MAXDEVICENAME]; 2565 NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE); 2566 2567 if (nt_devmode == NULL) { 2568 DEBUG(0,("construct_nt_devicemode: malloc fail.\n")); 2569 return NULL; 2570 } 2571 2572 ZERO_STRUCTP(nt_devmode); 2573 2574 slprintf(adevice, sizeof(adevice), "%s", default_devicename); 2575 fstrcpy(nt_devmode->devicename, adevice); 2576 2577 fstrcpy(nt_devmode->formname, "Letter"); 2578 2579 nt_devmode->specversion = DMSPEC_NT4_AND_ABOVE; 2580 nt_devmode->driverversion = 0x0400; 2581 nt_devmode->size = 0x00DC; 2582 nt_devmode->driverextra = 0x0000; 2583 nt_devmode->fields = DEVMODE_FORMNAME | 2584 DEVMODE_TTOPTION | 2585 DEVMODE_PRINTQUALITY | 2586 DEVMODE_DEFAULTSOURCE | 2587 DEVMODE_COPIES | 2588 DEVMODE_SCALE | 2589 DEVMODE_PAPERSIZE | 2590 DEVMODE_ORIENTATION; 2591 nt_devmode->orientation = DMORIENT_PORTRAIT; 2592 nt_devmode->papersize = DMPAPER_LETTER; 2593 nt_devmode->paperlength = 0; 2594 nt_devmode->paperwidth = 0; 2595 nt_devmode->scale = 0x64; 2596 nt_devmode->copies = 1; 2597 nt_devmode->defaultsource = DMBIN_FORMSOURCE; 2598 nt_devmode->printquality = DMRES_HIGH; /* 0x0258 */ 2599 nt_devmode->color = DMRES_MONOCHROME; 2600 nt_devmode->duplex = DMDUP_SIMPLEX; 2601 nt_devmode->yresolution = 0; 2602 nt_devmode->ttoption = DMTT_SUBDEV; 2603 nt_devmode->collate = DMCOLLATE_FALSE; 2604 nt_devmode->icmmethod = 0; 2605 nt_devmode->icmintent = 0; 2606 nt_devmode->mediatype = 0; 2607 nt_devmode->dithertype = 0; 2608 2609 /* non utilisés par un driver d'imprimante */ 2610 nt_devmode->logpixels = 0; 2611 nt_devmode->bitsperpel = 0; 2612 nt_devmode->pelswidth = 0; 2613 nt_devmode->pelsheight = 0; 2614 nt_devmode->displayflags = 0; 2615 nt_devmode->displayfrequency = 0; 2616 nt_devmode->reserved1 = 0; 2617 nt_devmode->reserved2 = 0; 2618 nt_devmode->panningwidth = 0; 2619 nt_devmode->panningheight = 0; 2620 2621 nt_devmode->nt_dev_private = NULL; 2622 return nt_devmode; 2623 } 2624 2625 /**************************************************************************** 2626 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE. 2627 ****************************************************************************/ 2628 2629 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr) 2630 { 2631 NT_DEVICEMODE *nt_devmode = *devmode_ptr; 2632 2633 if(nt_devmode == NULL) 2634 return; 2635 2636 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n")); 2637 2638 SAFE_FREE(nt_devmode->nt_dev_private); 2639 SAFE_FREE(*devmode_ptr); 2640 } 2641 2642 /**************************************************************************** 2643 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2. 2644 ****************************************************************************/ 2645 2646 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr) 2647 { 2648 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr; 2649 2650 if ( !info ) 2651 return; 2652 2653 free_nt_devicemode(&info->devmode); 2654 2655 TALLOC_FREE( *info_ptr ); 2656 } 2657 2658 2659 /**************************************************************************** 2660 ****************************************************************************/ 2661 int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen) 2662 { 2663 int len = 0; 2664 int extra_len = 0; 2665 NT_DEVICEMODE devmode; 2666 2667 ZERO_STRUCT(devmode); 2668 2669 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode); 2670 2671 if (!*nt_devmode) return len; 2672 2673 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp", 2674 devmode.devicename, 2675 devmode.formname, 2676 2677 &devmode.specversion, 2678 &devmode.driverversion, 2679 &devmode.size, 2680 &devmode.driverextra, 2681 &devmode.orientation, 2682 &devmode.papersize, 2683 &devmode.paperlength, 2684 &devmode.paperwidth, 2685 &devmode.scale, 2686 &devmode.copies, 2687 &devmode.defaultsource, 2688 &devmode.printquality, 2689 &devmode.color, 2690 &devmode.duplex, 2691 &devmode.yresolution, 2692 &devmode.ttoption, 2693 &devmode.collate, 2694 &devmode.logpixels, 2695 2696 &devmode.fields, 2697 &devmode.bitsperpel, 2698 &devmode.pelswidth, 2699 &devmode.pelsheight, 2700 &devmode.displayflags, 2701 &devmode.displayfrequency, 2702 &devmode.icmmethod, 2703 &devmode.icmintent, 2704 &devmode.mediatype, 2705 &devmode.dithertype, 2706 &devmode.reserved1, 2707 &devmode.reserved2, 2708 &devmode.panningwidth, 2709 &devmode.panningheight, 2710 &devmode.nt_dev_private); 2711 2712 if (devmode.nt_dev_private) { 2713 /* the len in tdb_unpack is an int value and 2714 * devmode.driverextra is only a short 2715 */ 2716 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private); 2717 devmode.driverextra=(uint16)extra_len; 2718 2719 /* check to catch an invalid TDB entry so we don't segfault */ 2720 if (devmode.driverextra == 0) { 2721 devmode.nt_dev_private = NULL; 2722 } 2723 } 2724 2725 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode)); 2726 if (!*nt_devmode) { 2727 SAFE_FREE(devmode.nt_dev_private); 2728 return -1; 2729 } 2730 2731 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname)); 2732 if (devmode.nt_dev_private) 2733 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra)); 2734 2735 return len; 2736 } 2737 2738 /**************************************************************************** 2739 Allocate and initialize a new slot. 2740 ***************************************************************************/ 2741 2742 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) 2743 { 2744 NT_PRINTER_KEY *d; 2745 int key_index; 2746 2747 if ( !name || !data ) 2748 return -1; 2749 2750 /* allocate another slot in the NT_PRINTER_KEY array */ 2751 2752 if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) { 2753 DEBUG(0,("add_new_printer_key: Realloc() failed!\n")); 2754 return -1; 2755 } 2756 2757 data->keys = d; 2758 2759 key_index = data->num_keys; 2760 2761 /* initialze new key */ 2762 2763 data->keys[key_index].name = talloc_strdup( data, name ); 2764 2765 if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, struct regval_ctr )) ) 2766 return -1; 2767 2768 data->num_keys++; 2769 2770 DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name )); 2771 2772 return key_index; 2773 } 2774 2775 /**************************************************************************** 2776 search for a registry key name in the existing printer data 2777 ***************************************************************************/ 2778 2779 int delete_printer_key( NT_PRINTER_DATA *data, const char *name ) 2780 { 2781 int i; 2782 2783 for ( i=0; i<data->num_keys; i++ ) { 2784 if ( strequal( data->keys[i].name, name ) ) { 2785 2786 /* cleanup memory */ 2787 2788 TALLOC_FREE( data->keys[i].name ); 2789 TALLOC_FREE( data->keys[i].values ); 2790 2791 /* if not the end of the array, move remaining elements down one slot */ 2792 2793 data->num_keys--; 2794 if ( data->num_keys && (i < data->num_keys) ) 2795 memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) ); 2796 2797 break; 2798 } 2799 } 2800 2801 2802 return data->num_keys; 2803 } 2804 2805 /**************************************************************************** 2806 search for a registry key name in the existing printer data 2807 ***************************************************************************/ 2808 2809 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name ) 2810 { 2811 int key_index = -1; 2812 int i; 2813 2814 if ( !data || !name ) 2815 return -1; 2816 2817 DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name)); 2818 2819 /* loop over all existing keys */ 2820 2821 for ( i=0; i<data->num_keys; i++ ) { 2822 if ( strequal(data->keys[i].name, name) ) { 2823 DEBUG(12,("lookup_printerkey: Found [%s]!\n", name)); 2824 key_index = i; 2825 break; 2826 2827 } 2828 } 2829 2830 return key_index; 2831 } 2832 2833 /**************************************************************************** 2834 ***************************************************************************/ 2835 2836 int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys ) 2837 { 2838 int i, j; 2839 int key_len; 2840 int num_subkeys = 0; 2841 char *p; 2842 fstring *subkeys_ptr = NULL; 2843 fstring subkeyname; 2844 2845 *subkeys = NULL; 2846 2847 if ( !data ) 2848 return 0; 2849 2850 if ( !key ) 2851 return -1; 2852 2853 /* special case of asking for the top level printer data registry key names */ 2854 2855 if ( strlen(key) == 0 ) { 2856 for ( i=0; i<data->num_keys; i++ ) { 2857 2858 /* found a match, so allocate space and copy the name */ 2859 2860 if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) { 2861 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 2862 num_subkeys+1)); 2863 return -1; 2864 } 2865 2866 fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name ); 2867 num_subkeys++; 2868 } 2869 2870 goto done; 2871 } 2872 2873 /* asking for the subkeys of some key */ 2874 /* subkey paths are stored in the key name using '\' as the delimiter */ 2875 2876 for ( i=0; i<data->num_keys; i++ ) { 2877 if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) { 2878 2879 /* if we found the exact key, then break */ 2880 key_len = strlen( key ); 2881 if ( strlen(data->keys[i].name) == key_len ) 2882 break; 2883 2884 /* get subkey path */ 2885 2886 p = data->keys[i].name + key_len; 2887 if ( *p == '\\' ) 2888 p++; 2889 fstrcpy( subkeyname, p ); 2890 if ( (p = strchr( subkeyname, '\\' )) ) 2891 *p = '\0'; 2892 2893 /* don't add a key more than once */ 2894 2895 for ( j=0; j<num_subkeys; j++ ) { 2896 if ( strequal( subkeys_ptr[j], subkeyname ) ) 2897 break; 2898 } 2899 2900 if ( j != num_subkeys ) 2901 continue; 2902 2903 /* found a match, so allocate space and copy the name */ 2904 2905 if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) { 2906 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 2907 num_subkeys+1)); 2908 return 0; 2909 } 2910 2911 fstrcpy( subkeys_ptr[num_subkeys], subkeyname ); 2912 num_subkeys++; 2913 } 2914 2915 } 2916 2917 /* return error if the key was not found */ 2918 2919 if ( i == data->num_keys ) { 2920 SAFE_FREE(subkeys_ptr); 2921 return -1; 2922 } 2923 2924 done: 2925 /* tag off the end */ 2926 2927 if (num_subkeys) 2928 fstrcpy(subkeys_ptr[num_subkeys], "" ); 2929 2930 *subkeys = subkeys_ptr; 2931 2932 return num_subkeys; 2933 } 2934 2935 #ifdef HAVE_ADS 2936 static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name, 2937 const char *sz) 2938 { 2939 regval_ctr_delvalue(ctr, val_name); 2940 regval_ctr_addvalue_sz(ctr, val_name, sz); 2941 } 2942 2943 static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name, 2944 uint32 dword) 2945 { 2946 regval_ctr_delvalue(ctr, val_name); 2947 regval_ctr_addvalue(ctr, val_name, REG_DWORD, 2948 (char *) &dword, sizeof(dword)); 2949 } 2950 2951 static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name, 2952 bool b) 2953 { 2954 uint8 bin_bool = (b ? 1 : 0); 2955 regval_ctr_delvalue(ctr, val_name); 2956 regval_ctr_addvalue(ctr, val_name, REG_BINARY, 2957 (char *) &bin_bool, sizeof(bin_bool)); 2958 } 2959 2960 static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name, 2961 const char *multi_sz) 2962 { 2963 const char *a[2]; 2964 2965 a[0] = multi_sz; 2966 a[1] = NULL; 2967 2968 regval_ctr_delvalue(ctr, val_name); 2969 regval_ctr_addvalue_multi_sz(ctr, val_name, a); 2970 } 2971 2972 /**************************************************************************** 2973 * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing. 2974 * 2975 * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified 2976 * @return bool indicating success or failure 2977 ***************************************************************************/ 2978 2979 static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) 2980 { 2981 struct regval_ctr *ctr = NULL; 2982 fstring longname; 2983 const char *dnssuffix; 2984 char *allocated_string = NULL; 2985 const char *ascii_str; 2986 int i; 2987 2988 if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) 2989 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY); 2990 ctr = info2->data->keys[i].values; 2991 2992 map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename); 2993 map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname()); 2994 2995 /* we make the assumption that the netbios name is the same 2996 as the DNS name sinc ethe former will be what we used to 2997 join the domain */ 2998 2999 dnssuffix = get_mydnsdomname(talloc_tos()); 3000 if (dnssuffix && *dnssuffix) { 3001 fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix ); 3002 } else { 3003 fstrcpy( longname, global_myname() ); 3004 } 3005 3006 map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname); 3007 3008 if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) { 3009 return false; 3010 } 3011 map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string); 3012 SAFE_FREE(allocated_string); 3013 3014 map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4); 3015 map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername); 3016 map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location); 3017 map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment); 3018 map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname); 3019 map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile); 3020 map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime); 3021 map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime); 3022 map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority); 3023 3024 map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS, 3025 (info2->attributes & 3026 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)); 3027 3028 switch (info2->attributes & 0x3) { 3029 case 0: 3030 ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING; 3031 break; 3032 case 1: 3033 ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED; 3034 break; 3035 case 2: 3036 ascii_str = SPOOL_REGVAL_PRINTDIRECT; 3037 break; 3038 default: 3039 ascii_str = "unknown"; 3040 } 3041 map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str); 3042 3043 return True; 3044 } 3045 3046 /***************************************************************** 3047 ****************************************************************/ 3048 3049 static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, 3050 struct GUID guid) 3051 { 3052 int i; 3053 struct regval_ctr *ctr=NULL; 3054 3055 /* find the DsSpooler key */ 3056 if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) 3057 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY); 3058 ctr = info2->data->keys[i].values; 3059 3060 regval_ctr_delvalue(ctr, "objectGUID"); 3061 3062 /* We used to store this as a REG_BINARY but that causes 3063 Vista to whine */ 3064 3065 regval_ctr_addvalue_sz(ctr, "objectGUID", 3066 GUID_string(talloc_tos(), &guid)); 3067 } 3068 3069 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, 3070 NT_PRINTER_INFO_LEVEL *printer) 3071 { 3072 ADS_STATUS ads_rc; 3073 LDAPMessage *res; 3074 char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped; 3075 char *srv_dn_utf8, **srv_cn_utf8; 3076 TALLOC_CTX *ctx; 3077 ADS_MODLIST mods; 3078 const char *attrs[] = {"objectGUID", NULL}; 3079 struct GUID guid; 3080 WERROR win_rc = WERR_OK; 3081 size_t converted_size; 3082 3083 /* build the ads mods */ 3084 ctx = talloc_init("nt_printer_publish_ads"); 3085 if (ctx == NULL) { 3086 return WERR_NOMEM; 3087 } 3088 3089 DEBUG(5, ("publishing printer %s\n", printer->info_2->printername)); 3090 3091 /* figure out where to publish */ 3092 ads_find_machine_acct(ads, &res, global_myname()); 3093 3094 /* We use ldap_get_dn here as we need the answer 3095 * in utf8 to call ldap_explode_dn(). JRA. */ 3096 3097 srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res); 3098 if (!srv_dn_utf8) { 3099 TALLOC_FREE(ctx); 3100 return WERR_SERVER_UNAVAILABLE; 3101 } 3102 ads_msgfree(ads, res); 3103 srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1); 3104 if (!srv_cn_utf8) { 3105 TALLOC_FREE(ctx); 3106 ldap_memfree(srv_dn_utf8); 3107 return WERR_SERVER_UNAVAILABLE; 3108 } 3109 /* Now convert to CH_UNIX. */ 3110 if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) { 3111 TALLOC_FREE(ctx); 3112 ldap_memfree(srv_dn_utf8); 3113 ldap_memfree(srv_cn_utf8); 3114 return WERR_SERVER_UNAVAILABLE; 3115 } 3116 if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) { 3117 TALLOC_FREE(ctx); 3118 ldap_memfree(srv_dn_utf8); 3119 ldap_memfree(srv_cn_utf8); 3120 TALLOC_FREE(srv_dn); 3121 return WERR_SERVER_UNAVAILABLE; 3122 } 3123 3124 ldap_memfree(srv_dn_utf8); 3125 ldap_memfree(srv_cn_utf8); 3126 3127 srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0); 3128 if (!srv_cn_escaped) { 3129 TALLOC_FREE(ctx); 3130 return WERR_SERVER_UNAVAILABLE; 3131 } 3132 sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename); 3133 if (!sharename_escaped) { 3134 SAFE_FREE(srv_cn_escaped); 3135 TALLOC_FREE(ctx); 3136 return WERR_SERVER_UNAVAILABLE; 3137 } 3138 3139 prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn); 3140 3141 SAFE_FREE(srv_cn_escaped); 3142 SAFE_FREE(sharename_escaped); 3143 3144 mods = ads_init_mods(ctx); 3145 3146 if (mods == NULL) { 3147 SAFE_FREE(prt_dn); 3148 TALLOC_FREE(ctx); 3149 return WERR_NOMEM; 3150 } 3151 3152 get_local_printer_publishing_data(ctx, &mods, printer->info_2->data); 3153 ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, 3154 printer->info_2->sharename); 3155 3156 /* publish it */ 3157 ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods); 3158 if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) { 3159 int i; 3160 for (i=0; mods[i] != 0; i++) 3161 ; 3162 mods[i] = (LDAPMod *)-1; 3163 ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods); 3164 } 3165 3166 if (!ADS_ERR_OK(ads_rc)) 3167 DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc))); 3168 3169 /* retreive the guid and store it locally */ 3170 if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) { 3171 ZERO_STRUCT(guid); 3172 ads_pull_guid(ads, res, &guid); 3173 ads_msgfree(ads, res); 3174 store_printer_guid(printer->info_2, guid); 3175 win_rc = mod_a_printer(printer, 2); 3176 } 3177 TALLOC_FREE(ctx); 3178 3179 return win_rc; 3180 } 3181 3182 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads, 3183 NT_PRINTER_INFO_LEVEL *printer) 3184 { 3185 ADS_STATUS ads_rc; 3186 LDAPMessage *res = NULL; 3187 char *prt_dn = NULL; 3188 3189 DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername)); 3190 3191 /* remove the printer from the directory */ 3192 ads_rc = ads_find_printer_on_server(ads, &res, 3193 printer->info_2->sharename, global_myname()); 3194 3195 if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) { 3196 prt_dn = ads_get_dn(ads, talloc_tos(), res); 3197 if (!prt_dn) { 3198 ads_msgfree(ads, res); 3199 return WERR_NOMEM; 3200 } 3201 ads_rc = ads_del_dn(ads, prt_dn); 3202 TALLOC_FREE(prt_dn); 3203 } 3204 3205 if (res) { 3206 ads_msgfree(ads, res); 3207 } 3208 return WERR_OK; 3209 } 3210 3211 /**************************************************************************** 3212 * Publish a printer in the directory 3213 * 3214 * @param snum describing printer service 3215 * @return WERROR indicating status of publishing 3216 ***************************************************************************/ 3217 3218 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) 3219 { 3220 ADS_STATUS ads_rc; 3221 ADS_STRUCT *ads = NULL; 3222 NT_PRINTER_INFO_LEVEL *printer = NULL; 3223 WERROR win_rc; 3224 3225 win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); 3226 if (!W_ERROR_IS_OK(win_rc)) 3227 goto done; 3228 3229 switch (action) { 3230 case DSPRINT_PUBLISH: 3231 case DSPRINT_UPDATE: 3232 /* set the DsSpooler info and attributes */ 3233 if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) { 3234 win_rc = WERR_NOMEM; 3235 goto done; 3236 } 3237 3238 printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; 3239 break; 3240 case DSPRINT_UNPUBLISH: 3241 printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; 3242 break; 3243 default: 3244 win_rc = WERR_NOT_SUPPORTED; 3245 goto done; 3246 } 3247 3248 win_rc = mod_a_printer(printer, 2); 3249 if (!W_ERROR_IS_OK(win_rc)) { 3250 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc))); 3251 goto done; 3252 } 3253 3254 ads = ads_init(lp_realm(), lp_workgroup(), NULL); 3255 if (!ads) { 3256 DEBUG(3, ("ads_init() failed\n")); 3257 win_rc = WERR_SERVER_UNAVAILABLE; 3258 goto done; 3259 } 3260 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); 3261 SAFE_FREE(ads->auth.password); 3262 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), 3263 NULL, NULL); 3264 3265 /* ads_connect() will find the DC for us */ 3266 ads_rc = ads_connect(ads); 3267 if (!ADS_ERR_OK(ads_rc)) { 3268 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); 3269 win_rc = WERR_ACCESS_DENIED; 3270 goto done; 3271 } 3272 3273 switch (action) { 3274 case DSPRINT_PUBLISH: 3275 case DSPRINT_UPDATE: 3276 win_rc = nt_printer_publish_ads(ads, printer); 3277 break; 3278 case DSPRINT_UNPUBLISH: 3279 win_rc = nt_printer_unpublish_ads(ads, printer); 3280 break; 3281 } 3282 3283 done: 3284 free_a_printer(&printer, 2); 3285 ads_destroy(&ads); 3286 return win_rc; 3287 } 3288 3289 WERROR check_published_printers(void) 3290 { 3291 ADS_STATUS ads_rc; 3292 ADS_STRUCT *ads = NULL; 3293 int snum; 3294 int n_services = lp_numservices(); 3295 NT_PRINTER_INFO_LEVEL *printer = NULL; 3296 3297 ads = ads_init(lp_realm(), lp_workgroup(), NULL); 3298 if (!ads) { 3299 DEBUG(3, ("ads_init() failed\n")); 3300 return WERR_SERVER_UNAVAILABLE; 3301 } 3302 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); 3303 SAFE_FREE(ads->auth.password); 3304 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), 3305 NULL, NULL); 3306 3307 /* ads_connect() will find the DC for us */ 3308 ads_rc = ads_connect(ads); 3309 if (!ADS_ERR_OK(ads_rc)) { 3310 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); 3311 ads_destroy(&ads); 3312 ads_kdestroy("MEMORY:prtpub_cache"); 3313 return WERR_ACCESS_DENIED; 3314 } 3315 3316 for (snum = 0; snum < n_services; snum++) { 3317 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) 3318 continue; 3319 3320 if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, 3321 lp_servicename(snum))) && 3322 (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) 3323 nt_printer_publish_ads(ads, printer); 3324 3325 free_a_printer(&printer, 2); 3326 } 3327 3328 ads_destroy(&ads); 3329 ads_kdestroy("MEMORY:prtpub_cache"); 3330 return WERR_OK; 3331 } 3332 3333 bool is_printer_published(Printer_entry *print_hnd, int snum, 3334 struct GUID *guid) 3335 { 3336 NT_PRINTER_INFO_LEVEL *printer = NULL; 3337 struct regval_ctr *ctr; 3338 struct regval_blob *guid_val; 3339 WERROR win_rc; 3340 int i; 3341 bool ret = False; 3342 DATA_BLOB blob; 3343 3344 win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); 3345 3346 if (!W_ERROR_IS_OK(win_rc) || 3347 !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) || 3348 ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) || 3349 !(ctr = printer->info_2->data->keys[i].values) || 3350 !(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) 3351 { 3352 free_a_printer(&printer, 2); 3353 return False; 3354 } 3355 3356 /* fetching printer guids really ought to be a separate function. */ 3357 3358 if ( guid ) { 3359 char *guid_str; 3360 3361 /* We used to store the guid as REG_BINARY, then swapped 3362 to REG_SZ for Vista compatibility so check for both */ 3363 3364 switch ( regval_type(guid_val) ){ 3365 case REG_SZ: 3366 blob = data_blob_const(regval_data_p(guid_val), 3367 regval_size(guid_val)); 3368 pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str); 3369 ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid )); 3370 talloc_free(guid_str); 3371 break; 3372 case REG_BINARY: 3373 if ( regval_size(guid_val) != sizeof(struct GUID) ) { 3374 ret = False; 3375 break; 3376 } 3377 memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID)); 3378 break; 3379 default: 3380 DEBUG(0,("is_printer_published: GUID value stored as " 3381 "invaluid type (%d)\n", regval_type(guid_val) )); 3382 break; 3383 } 3384 } 3385 3386 free_a_printer(&printer, 2); 3387 return ret; 3388 } 3389 #else 3390 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) 3391 { 3392 return WERR_OK; 3393 } 3394 3395 WERROR check_published_printers(void) 3396 { 3397 return WERR_OK; 3398 } 3399 3400 bool is_printer_published(Printer_entry *print_hnd, int snum, 3401 struct GUID *guid) 3402 { 3403 return False; 3404 } 3405 #endif /* HAVE_ADS */ 3406 3407 /**************************************************************************** 3408 ***************************************************************************/ 3409 3410 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key ) 3411 { 3412 NT_PRINTER_DATA *data; 3413 int i; 3414 int removed_keys = 0; 3415 int empty_slot; 3416 3417 data = p2->data; 3418 empty_slot = data->num_keys; 3419 3420 if ( !key ) 3421 return WERR_INVALID_PARAM; 3422 3423 /* remove all keys */ 3424 3425 if ( !strlen(key) ) { 3426 3427 TALLOC_FREE( data ); 3428 3429 p2->data = NULL; 3430 3431 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n", 3432 p2->printername )); 3433 3434 return WERR_OK; 3435 } 3436 3437 /* remove a specific key (and all subkeys) */ 3438 3439 for ( i=0; i<data->num_keys; i++ ) { 3440 if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) { 3441 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", 3442 data->keys[i].name)); 3443 3444 TALLOC_FREE( data->keys[i].name ); 3445 TALLOC_FREE( data->keys[i].values ); 3446 3447 /* mark the slot as empty */ 3448 3449 ZERO_STRUCTP( &data->keys[i] ); 3450 } 3451 } 3452 3453 /* find the first empty slot */ 3454 3455 for ( i=0; i<data->num_keys; i++ ) { 3456 if ( !data->keys[i].name ) { 3457 empty_slot = i; 3458 removed_keys++; 3459 break; 3460 } 3461 } 3462 3463 if ( i == data->num_keys ) 3464 /* nothing was removed */ 3465 return WERR_INVALID_PARAM; 3466 3467 /* move everything down */ 3468 3469 for ( i=empty_slot+1; i<data->num_keys; i++ ) { 3470 if ( data->keys[i].name ) { 3471 memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) ); 3472 ZERO_STRUCTP( &data->keys[i] ); 3473 empty_slot++; 3474 removed_keys++; 3475 } 3476 } 3477 3478 /* update count */ 3479 3480 data->num_keys -= removed_keys; 3481 3482 /* sanity check to see if anything is left */ 3483 3484 if ( !data->num_keys ) { 3485 DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername )); 3486 3487 SAFE_FREE( data->keys ); 3488 ZERO_STRUCTP( data ); 3489 } 3490 3491 return WERR_OK; 3492 } 3493 3494 /**************************************************************************** 3495 ***************************************************************************/ 3496 3497 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ) 3498 { 3499 WERROR result = WERR_OK; 3500 int key_index; 3501 3502 /* we must have names on non-zero length */ 3503 3504 if ( !key || !*key|| !value || !*value ) 3505 return WERR_INVALID_NAME; 3506 3507 /* find the printer key first */ 3508 3509 key_index = lookup_printerkey( p2->data, key ); 3510 if ( key_index == -1 ) 3511 return WERR_OK; 3512 3513 /* make sure the value exists so we can return the correct error code */ 3514 3515 if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) ) 3516 return WERR_BADFILE; 3517 3518 regval_ctr_delvalue( p2->data->keys[key_index].values, value ); 3519 3520 DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n", 3521 key, value )); 3522 3523 return result; 3524 } 3525 3526 /**************************************************************************** 3527 ***************************************************************************/ 3528 3529 WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value, 3530 uint32 type, uint8 *data, int real_len ) 3531 { 3532 WERROR result = WERR_OK; 3533 int key_index; 3534 3535 /* we must have names on non-zero length */ 3536 3537 if ( !key || !*key|| !value || !*value ) 3538 return WERR_INVALID_NAME; 3539 3540 /* find the printer key first */ 3541 3542 key_index = lookup_printerkey( p2->data, key ); 3543 if ( key_index == -1 ) 3544 key_index = add_new_printer_key( p2->data, key ); 3545 3546 if ( key_index == -1 ) 3547 return WERR_NOMEM; 3548 3549 regval_ctr_addvalue( p2->data->keys[key_index].values, value, 3550 type, (const char *)data, real_len ); 3551 3552 DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n", 3553 key, value, type, real_len )); 3554 3555 return result; 3556 } 3557 3558 /**************************************************************************** 3559 ***************************************************************************/ 3560 3561 struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ) 3562 { 3563 int key_index; 3564 3565 if ( (key_index = lookup_printerkey( p2->data, key )) == -1 ) 3566 return NULL; 3567 3568 DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n", 3569 key, value )); 3570 3571 return regval_ctr_getvalue( p2->data->keys[key_index].values, value ); 3572 } 3573 3574 /**************************************************************************** 3575 Unpack a list of registry values frem the TDB 3576 ***************************************************************************/ 3577 3578 static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen) 3579 { 3580 int len = 0; 3581 uint32 type; 3582 fstring string; 3583 const char *valuename = NULL; 3584 const char *keyname = NULL; 3585 char *str; 3586 int size; 3587 uint8 *data_p; 3588 struct regval_blob *regval_p; 3589 int key_index; 3590 3591 /* add the "PrinterDriverData" key first for performance reasons */ 3592 3593 add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY ); 3594 3595 /* loop and unpack the rest of the registry values */ 3596 3597 while ( True ) { 3598 3599 /* check to see if there are any more registry values */ 3600 3601 regval_p = NULL; 3602 len += tdb_unpack(buf+len, buflen-len, "p", ®val_p); 3603 if ( !regval_p ) 3604 break; 3605 3606 /* unpack the next regval */ 3607 3608 len += tdb_unpack(buf+len, buflen-len, "fdB", 3609 string, 3610 &type, 3611 &size, 3612 &data_p); 3613 3614 /* lookup for subkey names which have a type of REG_NONE */ 3615 /* there's no data with this entry */ 3616 3617 if ( type == REG_NONE ) { 3618 if ( (key_index=lookup_printerkey( printer_data, string)) == -1 ) 3619 add_new_printer_key( printer_data, string ); 3620 continue; 3621 } 3622 3623 /* 3624 * break of the keyname from the value name. 3625 * Valuenames can have embedded '\'s so be careful. 3626 * only support one level of keys. See the 3627 * "Konica Fiery S300 50C-K v1.1. enu" 2k driver. 3628 * -- jerry 3629 */ 3630 3631 str = strchr_m( string, '\\'); 3632 3633 /* Put in "PrinterDriverData" is no key specified */ 3634 3635 if ( !str ) { 3636 keyname = SPOOL_PRINTERDATA_KEY; 3637 valuename = string; 3638 } 3639 else { 3640 *str = '\0'; 3641 keyname = string; 3642 valuename = str+1; 3643 } 3644 3645 /* see if we need a new key */ 3646 3647 if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 ) 3648 key_index = add_new_printer_key( printer_data, keyname ); 3649 3650 if ( key_index == -1 ) { 3651 DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n", 3652 keyname)); 3653 break; 3654 } 3655 3656 DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); 3657 3658 /* Vista doesn't like unknown REG_BINARY values in DsSpooler. 3659 Thanks to Martin Zielinski for the hint. */ 3660 3661 if ( type == REG_BINARY && 3662 strequal( keyname, SPOOL_DSSPOOLER_KEY ) && 3663 strequal( valuename, "objectGUID" ) ) 3664 { 3665 struct GUID guid; 3666 3667 /* convert the GUID to a UNICODE string */ 3668 3669 memcpy( &guid, data_p, sizeof(struct GUID) ); 3670 3671 regval_ctr_addvalue_sz(printer_data->keys[key_index].values, 3672 valuename, 3673 GUID_string(talloc_tos(), &guid)); 3674 3675 } else { 3676 /* add the value */ 3677 3678 regval_ctr_addvalue( printer_data->keys[key_index].values, 3679 valuename, type, (const char *)data_p, 3680 size ); 3681 } 3682 3683 SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */ 3684 3685 } 3686 3687 return len; 3688 } 3689 3690 /**************************************************************************** 3691 ***************************************************************************/ 3692 3693 static char *last_from; 3694 static char *last_to; 3695 3696 static const char *get_last_from(void) 3697 { 3698 if (!last_from) { 3699 return ""; 3700 } 3701 return last_from; 3702 } 3703 3704 static const char *get_last_to(void) 3705 { 3706 if (!last_to) { 3707 return ""; 3708 } 3709 return last_to; 3710 } 3711 3712 static bool set_last_from_to(const char *from, const char *to) 3713 { 3714 char *orig_from = last_from; 3715 char *orig_to = last_to; 3716 3717 last_from = SMB_STRDUP(from); 3718 last_to = SMB_STRDUP(to); 3719 3720 SAFE_FREE(orig_from); 3721 SAFE_FREE(orig_to); 3722 3723 if (!last_from || !last_to) { 3724 SAFE_FREE(last_from); 3725 SAFE_FREE(last_to); 3726 return false; 3727 } 3728 return true; 3729 } 3730 3731 static void map_to_os2_driver(fstring drivername) 3732 { 3733 char *mapfile = lp_os2_driver_map(); 3734 char **lines = NULL; 3735 int numlines = 0; 3736 int i; 3737 3738 if (!strlen(drivername)) 3739 return; 3740 3741 if (!*mapfile) 3742 return; 3743 3744 if (strequal(drivername,get_last_from())) { 3745 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n", 3746 drivername,get_last_to())); 3747 fstrcpy(drivername,get_last_to()); 3748 return; 3749 } 3750 3751 lines = file_lines_load(mapfile, &numlines,0,NULL); 3752 if (numlines == 0 || lines == NULL) { 3753 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile)); 3754 TALLOC_FREE(lines); 3755 return; 3756 } 3757 3758 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile)); 3759 3760 for( i = 0; i < numlines; i++) { 3761 char *nt_name = lines[i]; 3762 char *os2_name = strchr(nt_name,'='); 3763 3764 if (!os2_name) 3765 continue; 3766 3767 *os2_name++ = 0; 3768 3769 while (isspace(*nt_name)) 3770 nt_name++; 3771 3772 if (!*nt_name || strchr("#;",*nt_name)) 3773 continue; 3774 3775 { 3776 int l = strlen(nt_name); 3777 while (l && isspace(nt_name[l-1])) { 3778 nt_name[l-1] = 0; 3779 l--; 3780 } 3781 } 3782 3783 while (isspace(*os2_name)) 3784 os2_name++; 3785 3786 { 3787 int l = strlen(os2_name); 3788 while (l && isspace(os2_name[l-1])) { 3789 os2_name[l-1] = 0; 3790 l--; 3791 } 3792 } 3793 3794 if (strequal(nt_name,drivername)) { 3795 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name)); 3796 set_last_from_to(drivername,os2_name); 3797 fstrcpy(drivername,os2_name); 3798 TALLOC_FREE(lines); 3799 return; 3800 } 3801 } 3802 3803 TALLOC_FREE(lines); 3804 } 3805 3806 /**************************************************************************** 3807 Get a default printer info 2 struct. 3808 ****************************************************************************/ 3809 3810 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, 3811 const char *servername, 3812 const char* sharename, 3813 bool get_loc_com) 3814 { 3815 int snum = lp_servicenumber(sharename); 3816 3817 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername); 3818 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", 3819 servername, sharename); 3820 fstrcpy(info->sharename, sharename); 3821 fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME); 3822 3823 /* by setting the driver name to an empty string, a local NT admin 3824 can now run the **local** APW to install a local printer driver 3825 for a Samba shared printer in 2.2. Without this, drivers **must** be 3826 installed on the Samba server for NT clients --jerry */ 3827 #if 0 /* JERRY --do not uncomment-- */ 3828 if (!*info->drivername) 3829 fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER"); 3830 #endif 3831 3832 3833 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername)); 3834 3835 strlcpy(info->comment, "", sizeof(info->comment)); 3836 fstrcpy(info->printprocessor, "winprint"); 3837 fstrcpy(info->datatype, "RAW"); 3838 3839 #ifdef HAVE_CUPS 3840 if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) { 3841 /* Pull the location and comment strings from cups if we don't 3842 already have one */ 3843 if ( !strlen(info->location) || !strlen(info->comment) ) 3844 cups_pull_comment_location( info ); 3845 } 3846 #endif 3847 3848 info->attributes = PRINTER_ATTRIBUTE_SAMBA; 3849 3850 info->starttime = 0; /* Minutes since 12:00am GMT */ 3851 info->untiltime = 0; /* Minutes since 12:00am GMT */ 3852 info->priority = 1; 3853 info->default_priority = 1; 3854 info->setuptime = (uint32)time(NULL); 3855 3856 /* 3857 * I changed this as I think it is better to have a generic 3858 * DEVMODE than to crash Win2k explorer.exe --jerry 3859 * See the HP Deskjet 990c Win2k drivers for an example. 3860 * 3861 * However the default devmode appears to cause problems 3862 * with the HP CLJ 8500 PCL driver. Hence the addition of 3863 * the "default devmode" parameter --jerry 22/01/2002 3864 */ 3865 3866 if (lp_default_devmode(snum)) { 3867 if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) { 3868 goto fail; 3869 } 3870 } else { 3871 info->devmode = NULL; 3872 } 3873 3874 if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) { 3875 goto fail; 3876 } 3877 3878 info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA); 3879 if (!info->data) { 3880 goto fail; 3881 } 3882 3883 add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY); 3884 3885 return WERR_OK; 3886 3887 fail: 3888 if (info->devmode) 3889 free_nt_devicemode(&info->devmode); 3890 3891 return WERR_ACCESS_DENIED; 3892 } 3893 3894 /**************************************************************************** 3895 ****************************************************************************/ 3896 3897 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, 3898 const char *servername, 3899 const char *sharename, 3900 bool get_loc_com) 3901 { 3902 int len = 0; 3903 int snum = lp_servicenumber(sharename); 3904 TDB_DATA kbuf, dbuf; 3905 fstring printername; 3906 char adevice[MAXDEVICENAME]; 3907 char *comment = NULL; 3908 3909 kbuf = make_printer_tdbkey(talloc_tos(), sharename); 3910 3911 dbuf = tdb_fetch(tdb_printers, kbuf); 3912 if (!dbuf.dptr) { 3913 return get_a_printer_2_default(info, servername, 3914 sharename, get_loc_com); 3915 } 3916 3917 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff", 3918 &info->attributes, 3919 &info->priority, 3920 &info->default_priority, 3921 &info->starttime, 3922 &info->untiltime, 3923 &info->status, 3924 &info->cjobs, 3925 &info->averageppm, 3926 &info->changeid, 3927 &info->c_setprinter, 3928 &info->setuptime, 3929 info->servername, 3930 info->printername, 3931 info->sharename, 3932 info->portname, 3933 info->drivername, 3934 &comment, 3935 info->location, 3936 info->sepfile, 3937 info->printprocessor, 3938 info->datatype, 3939 info->parameters); 3940 3941 if (comment) { 3942 strlcpy(info->comment, comment, sizeof(info->comment)); 3943 SAFE_FREE(comment); 3944 } 3945 3946 /* Samba has to have shared raw drivers. */ 3947 info->attributes |= PRINTER_ATTRIBUTE_SAMBA; 3948 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA; 3949 3950 /* Restore the stripped strings. */ 3951 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername); 3952 3953 if ( lp_force_printername(snum) ) { 3954 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename ); 3955 } else { 3956 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername); 3957 } 3958 3959 fstrcpy(info->printername, printername); 3960 3961 #ifdef HAVE_CUPS 3962 if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) { 3963 /* Pull the location and comment strings from cups if we don't 3964 already have one */ 3965 if ( !strlen(info->location) || !strlen(info->comment) ) 3966 cups_pull_comment_location( info ); 3967 } 3968 #endif 3969 3970 len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len); 3971 3972 /* 3973 * Some client drivers freak out if there is a NULL devmode 3974 * (probably the driver is not checking before accessing 3975 * the devmode pointer) --jerry 3976 * 3977 * See comments in get_a_printer_2_default() 3978 */ 3979 3980 if (lp_default_devmode(snum) && !info->devmode) { 3981 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n", 3982 printername)); 3983 info->devmode = construct_nt_devicemode(printername); 3984 } 3985 3986 slprintf( adevice, sizeof(adevice), "%s", info->printername ); 3987 if (info->devmode) { 3988 fstrcpy(info->devmode->devicename, adevice); 3989 } 3990 3991 if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) { 3992 DEBUG(0,("unpack_values: talloc() failed!\n")); 3993 SAFE_FREE(dbuf.dptr); 3994 return WERR_NOMEM; 3995 } 3996 len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len ); 3997 3998 /* This will get the current RPC talloc context, but we should be 3999 passing this as a parameter... fixme... JRA ! */ 4000 4001 if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) { 4002 SAFE_FREE(dbuf.dptr); 4003 return WERR_NOMEM; 4004 } 4005 4006 /* Fix for OS/2 drivers. */ 4007 4008 if (get_remote_arch() == RA_OS2) { 4009 map_to_os2_driver(info->drivername); 4010 } 4011 4012 SAFE_FREE(dbuf.dptr); 4013 4014 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n", 4015 sharename, info->printername, info->drivername)); 4016 4017 return WERR_OK; 4018 } 4019 4020 /**************************************************************************** 4021 Debugging function, dump at level 6 the struct in the logs. 4022 ****************************************************************************/ 4023 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4024 { 4025 uint32 result; 4026 NT_PRINTER_INFO_LEVEL_2 *info2; 4027 4028 DEBUG(106,("Dumping printer at level [%d]\n", level)); 4029 4030 switch (level) { 4031 case 2: 4032 { 4033 if (printer->info_2 == NULL) 4034 result=5; 4035 else 4036 { 4037 info2=printer->info_2; 4038 4039 DEBUGADD(106,("attributes:[%d]\n", info2->attributes)); 4040 DEBUGADD(106,("priority:[%d]\n", info2->priority)); 4041 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority)); 4042 DEBUGADD(106,("starttime:[%d]\n", info2->starttime)); 4043 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime)); 4044 DEBUGADD(106,("status:[%d]\n", info2->status)); 4045 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs)); 4046 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm)); 4047 DEBUGADD(106,("changeid:[%d]\n", info2->changeid)); 4048 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter)); 4049 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime)); 4050 4051 DEBUGADD(106,("servername:[%s]\n", info2->servername)); 4052 DEBUGADD(106,("printername:[%s]\n", info2->printername)); 4053 DEBUGADD(106,("sharename:[%s]\n", info2->sharename)); 4054 DEBUGADD(106,("portname:[%s]\n", info2->portname)); 4055 DEBUGADD(106,("drivername:[%s]\n", info2->drivername)); 4056 DEBUGADD(106,("comment:[%s]\n", info2->comment)); 4057 DEBUGADD(106,("location:[%s]\n", info2->location)); 4058 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile)); 4059 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor)); 4060 DEBUGADD(106,("datatype:[%s]\n", info2->datatype)); 4061 DEBUGADD(106,("parameters:[%s]\n", info2->parameters)); 4062 result=0; 4063 } 4064 break; 4065 } 4066 default: 4067 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level )); 4068 result=1; 4069 break; 4070 } 4071 4072 return result; 4073 } 4074 4075 /**************************************************************************** 4076 Update the changeid time. 4077 This is SO NASTY as some drivers need this to change, others need it 4078 static. This value will change every second, and I must hope that this 4079 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF 4080 UTAH ! JRA. 4081 ****************************************************************************/ 4082 4083 static uint32 rev_changeid(void) 4084 { 4085 struct timeval tv; 4086 4087 get_process_uptime(&tv); 4088 4089 #if 1 /* JERRY */ 4090 /* Return changeid as msec since spooler restart */ 4091 return tv.tv_sec * 1000 + tv.tv_usec / 1000; 4092 #else 4093 /* 4094 * This setting seems to work well but is too untested 4095 * to replace the above calculation. Left in for experiementation 4096 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002) 4097 */ 4098 return tv.tv_sec * 10 + tv.tv_usec / 100000; 4099 #endif 4100 } 4101 4102 4103 /* 4104 * The function below are the high level ones. 4105 * only those ones must be called from the spoolss code. 4106 * JFM. 4107 */ 4108 4109 /**************************************************************************** 4110 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA. 4111 ****************************************************************************/ 4112 4113 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4114 { 4115 WERROR result; 4116 4117 dump_a_printer(printer, level); 4118 4119 switch (level) { 4120 case 2: 4121 { 4122 /* 4123 * Update the changestamp. Emperical tests show that the 4124 * ChangeID is always updated,but c_setprinter is 4125 * global spooler variable (not per printer). 4126 */ 4127 4128 /* ChangeID **must** be increasing over the lifetime 4129 of client's spoolss service in order for the 4130 client's cache to show updates */ 4131 4132 printer->info_2->changeid = rev_changeid(); 4133 4134 /* 4135 * Because one day someone will ask: 4136 * NT->NT An admin connection to a remote 4137 * printer show changes imeediately in 4138 * the properities dialog 4139 * 4140 * A non-admin connection will only show the 4141 * changes after viewing the properites page 4142 * 2 times. Seems to be related to a 4143 * race condition in the client between the spooler 4144 * updating the local cache and the Explorer.exe GUI 4145 * actually displaying the properties. 4146 * 4147 * This is fixed in Win2k. admin/non-admin 4148 * connections both display changes immediately. 4149 * 4150 * 14/12/01 --jerry 4151 */ 4152 4153 result=update_a_printer_2(printer->info_2); 4154 break; 4155 } 4156 default: 4157 result=WERR_UNKNOWN_LEVEL; 4158 break; 4159 } 4160 4161 return result; 4162 } 4163 4164 /**************************************************************************** 4165 Initialize printer devmode & data with previously saved driver init values. 4166 ****************************************************************************/ 4167 4168 static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) 4169 { 4170 int len = 0; 4171 char *key = NULL; 4172 TDB_DATA dbuf; 4173 NT_PRINTER_INFO_LEVEL_2 info; 4174 4175 4176 ZERO_STRUCT(info); 4177 4178 /* 4179 * Delete any printer data 'values' already set. When called for driver 4180 * replace, there will generally be some, but during an add printer, there 4181 * should not be any (if there are delete them). 4182 */ 4183 4184 if ( info_ptr->data ) 4185 delete_all_printer_data( info_ptr, "" ); 4186 4187 if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, 4188 info_ptr->drivername) < 0) { 4189 return false; 4190 } 4191 4192 dbuf = tdb_fetch_bystring(tdb_drivers, key); 4193 if (!dbuf.dptr) { 4194 /* 4195 * When changing to a driver that has no init info in the tdb, remove 4196 * the previous drivers init info and leave the new on blank. 4197 */ 4198 free_nt_devicemode(&info_ptr->devmode); 4199 SAFE_FREE(key); 4200 return false; 4201 } 4202 4203 SAFE_FREE(key); 4204 /* 4205 * Get the saved DEVMODE.. 4206 */ 4207 4208 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len); 4209 4210 /* 4211 * The saved DEVMODE contains the devicename from the printer used during 4212 * the initialization save. Change it to reflect the new printer. 4213 */ 4214 4215 if ( info.devmode ) { 4216 ZERO_STRUCT(info.devmode->devicename); 4217 fstrcpy(info.devmode->devicename, info_ptr->printername); 4218 } 4219 4220 /* 4221 * NT/2k does not change out the entire DeviceMode of a printer 4222 * when changing the driver. Only the driverextra, private, & 4223 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002) 4224 * 4225 * Later examination revealed that Windows NT/2k does reset the 4226 * the printer's device mode, bit **only** when you change a 4227 * property of the device mode such as the page orientation. 4228 * --jerry 4229 */ 4230 4231 4232 /* Bind the saved DEVMODE to the new the printer */ 4233 4234 free_nt_devicemode(&info_ptr->devmode); 4235 info_ptr->devmode = info.devmode; 4236 4237 DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n", 4238 info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername)); 4239 4240 /* Add the printer data 'values' to the new printer */ 4241 4242 if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) { 4243 DEBUG(0,("set_driver_init_2: talloc() failed!\n")); 4244 return False; 4245 } 4246 4247 len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len ); 4248 4249 SAFE_FREE(dbuf.dptr); 4250 4251 return true; 4252 } 4253 4254 /**************************************************************************** 4255 Initialize printer devmode & data with previously saved driver init values. 4256 When a printer is created using AddPrinter, the drivername bound to the 4257 printer is used to lookup previously saved driver initialization info, which 4258 is bound to the new printer. 4259 ****************************************************************************/ 4260 4261 bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4262 { 4263 bool result = False; 4264 4265 switch (level) { 4266 case 2: 4267 result = set_driver_init_2(printer->info_2); 4268 break; 4269 4270 default: 4271 DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n", 4272 level)); 4273 break; 4274 } 4275 4276 return result; 4277 } 4278 4279 /**************************************************************************** 4280 Delete driver init data stored for a specified driver 4281 ****************************************************************************/ 4282 4283 bool del_driver_init(const char *drivername) 4284 { 4285 char *key; 4286 bool ret; 4287 4288 if (!drivername || !*drivername) { 4289 DEBUG(3,("del_driver_init: No drivername specified!\n")); 4290 return false; 4291 } 4292 4293 if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) { 4294 return false; 4295 } 4296 4297 DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", 4298 drivername)); 4299 4300 ret = (tdb_delete_bystring(tdb_drivers, key) == 0); 4301 SAFE_FREE(key); 4302 return ret; 4303 } 4304 4305 /**************************************************************************** 4306 Pack up the DEVMODE and values for a printer into a 'driver init' entry 4307 in the tdb. Note: this is different from the driver entry and the printer 4308 entry. There should be a single driver init entry for each driver regardless 4309 of whether it was installed from NT or 2K. Technically, they should be 4310 different, but they work out to the same struct. 4311 ****************************************************************************/ 4312 4313 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info) 4314 { 4315 char *key = NULL; 4316 uint8 *buf; 4317 int buflen, len, ret; 4318 int retlen; 4319 TDB_DATA dbuf; 4320 4321 buf = NULL; 4322 buflen = 0; 4323 4324 again: 4325 len = 0; 4326 len += pack_devicemode(info->devmode, buf+len, buflen-len); 4327 4328 retlen = pack_values( info->data, buf+len, buflen-len ); 4329 if (retlen == -1) { 4330 ret = -1; 4331 goto done; 4332 } 4333 len += retlen; 4334 4335 if (buflen < len) { 4336 buf = (uint8 *)SMB_REALLOC(buf, len); 4337 if (!buf) { 4338 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n")); 4339 ret = -1; 4340 goto done; 4341 } 4342 buflen = len; 4343 goto again; 4344 } 4345 4346 SAFE_FREE(key); 4347 if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) { 4348 ret = (uint32)-1; 4349 goto done; 4350 } 4351 4352 dbuf.dptr = buf; 4353 dbuf.dsize = len; 4354 4355 ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE); 4356 4357 done: 4358 if (ret == -1) 4359 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n")); 4360 4361 SAFE_FREE(buf); 4362 4363 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n", 4364 info->sharename, info->drivername)); 4365 4366 return ret; 4367 } 4368 4369 /**************************************************************************** 4370 Update (i.e. save) the driver init info (DEVMODE and values) for a printer 4371 ****************************************************************************/ 4372 4373 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4374 { 4375 uint32 result; 4376 4377 dump_a_printer(printer, level); 4378 4379 switch (level) { 4380 case 2: 4381 result = update_driver_init_2(printer->info_2); 4382 break; 4383 default: 4384 result = 1; 4385 break; 4386 } 4387 4388 return result; 4389 } 4390 4391 /**************************************************************************** 4392 Convert the printer data value, a REG_BINARY array, into an initialization 4393 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc... 4394 got to keep the endians happy :). 4395 ****************************************************************************/ 4396 4397 static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode, 4398 const uint8_t *data, uint32_t data_len) 4399 { 4400 struct spoolss_DeviceMode devmode; 4401 enum ndr_err_code ndr_err; 4402 DATA_BLOB blob; 4403 4404 ZERO_STRUCT(devmode); 4405 4406 blob = data_blob_const(data, data_len); 4407 4408 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode, 4409 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); 4410 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 4411 DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n")); 4412 return false; 4413 } 4414 4415 return convert_devicemode("", &devmode, &nt_devmode); 4416 } 4417 4418 /**************************************************************************** 4419 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that: 4420 4421 1. Use the driver's config DLL to this UNC printername and: 4422 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE 4423 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE 4424 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data. 4425 4426 The last step triggers saving the "driver initialization" information for 4427 this printer into the tdb. Later, new printers that use this driver will 4428 have this initialization information bound to them. This simulates the 4429 driver initialization, as if it had run on the Samba server (as it would 4430 have done on NT). 4431 4432 The Win32 client side code requirement sucks! But until we can run arbitrary 4433 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it. 4434 4435 It would have been easier to use SetPrinter because all the UNMARSHALLING of 4436 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think 4437 about it and you will realize why. JRR 010720 4438 ****************************************************************************/ 4439 4440 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len ) 4441 { 4442 WERROR status = WERR_OK; 4443 TALLOC_CTX *ctx = NULL; 4444 NT_DEVICEMODE *nt_devmode = NULL; 4445 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode; 4446 4447 /* 4448 * When the DEVMODE is already set on the printer, don't try to unpack it. 4449 */ 4450 DEBUG(8,("save_driver_init_2: Enter...\n")); 4451 4452 if ( !printer->info_2->devmode && data_len ) { 4453 /* 4454 * Set devmode on printer info, so entire printer initialization can be 4455 * saved to tdb. 4456 */ 4457 4458 if ((ctx = talloc_init("save_driver_init_2")) == NULL) 4459 return WERR_NOMEM; 4460 4461 if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) { 4462 status = WERR_NOMEM; 4463 goto done; 4464 } 4465 4466 ZERO_STRUCTP(nt_devmode); 4467 4468 /* 4469 * The DEVMODE is held in the 'data' component of the param in raw binary. 4470 * Convert it to to a devmode structure 4471 */ 4472 if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) { 4473 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n")); 4474 status = WERR_INVALID_PARAM; 4475 goto done; 4476 } 4477 4478 printer->info_2->devmode = nt_devmode; 4479 } 4480 4481 /* 4482 * Pack up and add (or update) the DEVMODE and any current printer data to 4483 * a 'driver init' element in the tdb 4484 * 4485 */ 4486 4487 if ( update_driver_init(printer, 2) != 0 ) { 4488 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n")); 4489 status = WERR_NOMEM; 4490 goto done; 4491 } 4492 4493 /* 4494 * If driver initialization info was successfully saved, set the current 4495 * printer to match it. This allows initialization of the current printer 4496 * as well as the driver. 4497 */ 4498 status = mod_a_printer(printer, 2); 4499 if (!W_ERROR_IS_OK(status)) { 4500 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n", 4501 printer->info_2->printername)); 4502 } 4503 4504 done: 4505 talloc_destroy(ctx); 4506 free_nt_devicemode( &nt_devmode ); 4507 4508 printer->info_2->devmode = tmp_devmode; 4509 4510 return status; 4511 } 4512 4513 /**************************************************************************** 4514 Update the driver init info (DEVMODE and specifics) for a printer 4515 ****************************************************************************/ 4516 4517 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len) 4518 { 4519 WERROR status = WERR_OK; 4520 4521 switch (level) { 4522 case 2: 4523 status = save_driver_init_2( printer, data, data_len ); 4524 break; 4525 default: 4526 status = WERR_UNKNOWN_LEVEL; 4527 break; 4528 } 4529 4530 return status; 4531 } 4532 4533 /**************************************************************************** 4534 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory. 4535 4536 Previously the code had a memory allocation problem because it always 4537 used the TALLOC_CTX from the Printer_entry*. This context lasts 4538 as a long as the original handle is open. So if the client made a lot 4539 of getprinter[data]() calls, the memory usage would climb. Now we use 4540 a short lived TALLOC_CTX for printer_info_2 objects returned. We 4541 still use the Printer_entry->ctx for maintaining the cache copy though 4542 since that object must live as long as the handle by definition. 4543 --jerry 4544 4545 ****************************************************************************/ 4546 4547 static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, 4548 const char *sharename, bool get_loc_com) 4549 { 4550 WERROR result; 4551 fstring servername; 4552 4553 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level)); 4554 4555 if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) { 4556 DEBUG(0,("get_a_printer: talloc() fail.\n")); 4557 return WERR_NOMEM; 4558 } 4559 4560 switch (level) { 4561 case 2: 4562 if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) { 4563 DEBUG(0,("get_a_printer: talloc() fail.\n")); 4564 TALLOC_FREE( *pp_printer ); 4565 return WERR_NOMEM; 4566 } 4567 4568 if ( print_hnd ) 4569 fstrcpy( servername, print_hnd->servername ); 4570 else { 4571 fstrcpy( servername, "%L" ); 4572 standard_sub_basic( "", "", servername, 4573 sizeof(servername)-1 ); 4574 } 4575 4576 result = get_a_printer_2( (*pp_printer)->info_2, 4577 servername, sharename, get_loc_com); 4578 4579 /* we have a new printer now. Save it with this handle */ 4580 4581 if ( !W_ERROR_IS_OK(result) ) { 4582 TALLOC_FREE( *pp_printer ); 4583 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", 4584 sharename, (unsigned int)level, win_errstr(result))); 4585 return result; 4586 } 4587 4588 dump_a_printer( *pp_printer, level); 4589 4590 break; 4591 4592 default: 4593 TALLOC_FREE( *pp_printer ); 4594 return WERR_UNKNOWN_LEVEL; 4595 } 4596 4597 return WERR_OK; 4598 } 4599 4600 WERROR get_a_printer( Printer_entry *print_hnd, 4601 NT_PRINTER_INFO_LEVEL **pp_printer, 4602 uint32 level, 4603 const char *sharename) 4604 { 4605 return get_a_printer_internal(print_hnd, pp_printer, level, 4606 sharename, true); 4607 } 4608 4609 WERROR get_a_printer_search( Printer_entry *print_hnd, 4610 NT_PRINTER_INFO_LEVEL **pp_printer, 4611 uint32 level, 4612 const char *sharename) 4613 { 4614 return get_a_printer_internal(print_hnd, pp_printer, level, 4615 sharename, false); 4616 } 4617 4618 /**************************************************************************** 4619 Deletes a NT_PRINTER_INFO_LEVEL struct. 4620 ****************************************************************************/ 4621 4622 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level) 4623 { 4624 NT_PRINTER_INFO_LEVEL *printer = *pp_printer; 4625 4626 if ( !printer ) 4627 return 0; 4628 4629 switch (level) { 4630 case 2: 4631 if ( printer->info_2 ) 4632 free_nt_printer_info_level_2(&printer->info_2); 4633 break; 4634 4635 default: 4636 DEBUG(0,("free_a_printer: unknown level! [%d]\n", level )); 4637 return 1; 4638 } 4639 4640 TALLOC_FREE(*pp_printer); 4641 4642 return 0; 4643 } 4644 4645 /**************************************************************************** 4646 ****************************************************************************/ 4647 4648 uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx, 4649 struct spoolss_AddDriverInfoCtr *r, 4650 char **driver_name, 4651 uint32_t *version) 4652 { 4653 struct spoolss_DriverInfo8 info8; 4654 4655 ZERO_STRUCT(info8); 4656 4657 DEBUG(10,("adding a printer at level [%d]\n", r->level)); 4658 4659 switch (r->level) { 4660 case 3: 4661 info8.version = r->info.info3->version; 4662 info8.driver_name = r->info.info3->driver_name; 4663 info8.architecture = r->info.info3->architecture; 4664 info8.driver_path = r->info.info3->driver_path; 4665 info8.data_file = r->info.info3->data_file; 4666 info8.config_file = r->info.info3->config_file; 4667 info8.help_file = r->info.info3->help_file; 4668 info8.monitor_name = r->info.info3->monitor_name; 4669 info8.default_datatype = r->info.info3->default_datatype; 4670 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) { 4671 info8.dependent_files = r->info.info3->dependent_files->string; 4672 } 4673 break; 4674 case 6: 4675 info8.version = r->info.info6->version; 4676 info8.driver_name = r->info.info6->driver_name; 4677 info8.architecture = r->info.info6->architecture; 4678 info8.driver_path = r->info.info6->driver_path; 4679 info8.data_file = r->info.info6->data_file; 4680 info8.config_file = r->info.info6->config_file; 4681 info8.help_file = r->info.info6->help_file; 4682 info8.monitor_name = r->info.info6->monitor_name; 4683 info8.default_datatype = r->info.info6->default_datatype; 4684 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) { 4685 info8.dependent_files = r->info.info6->dependent_files->string; 4686 } 4687 info8.driver_date = r->info.info6->driver_date; 4688 info8.driver_version = r->info.info6->driver_version; 4689 info8.manufacturer_name = r->info.info6->manufacturer_name; 4690 info8.manufacturer_url = r->info.info6->manufacturer_url; 4691 info8.hardware_id = r->info.info6->hardware_id; 4692 info8.provider = r->info.info6->provider; 4693 break; 4694 case 8: 4695 info8.version = r->info.info8->version; 4696 info8.driver_name = r->info.info8->driver_name; 4697 info8.architecture = r->info.info8->architecture; 4698 info8.driver_path = r->info.info8->driver_path; 4699 info8.data_file = r->info.info8->data_file; 4700 info8.config_file = r->info.info8->config_file; 4701 info8.help_file = r->info.info8->help_file; 4702 info8.monitor_name = r->info.info8->monitor_name; 4703 info8.default_datatype = r->info.info8->default_datatype; 4704 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) { 4705 info8.dependent_files = r->info.info8->dependent_files->string; 4706 } 4707 if (r->info.info8->previous_names && r->info.info8->previous_names->string) { 4708 info8.previous_names = r->info.info8->previous_names->string; 4709 } 4710 info8.driver_date = r->info.info8->driver_date; 4711 info8.driver_version = r->info.info8->driver_version; 4712 info8.manufacturer_name = r->info.info8->manufacturer_name; 4713 info8.manufacturer_url = r->info.info8->manufacturer_url; 4714 info8.hardware_id = r->info.info8->hardware_id; 4715 info8.provider = r->info.info8->provider; 4716 info8.print_processor = r->info.info8->print_processor; 4717 info8.vendor_setup = r->info.info8->vendor_setup; 4718 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) { 4719 info8.color_profiles = r->info.info8->color_profiles->string; 4720 } 4721 info8.inf_path = r->info.info8->inf_path; 4722 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes; 4723 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) { 4724 info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string; 4725 } 4726 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date; 4727 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version; 4728 break; 4729 default: 4730 return -1; 4731 } 4732 4733 *driver_name = talloc_strdup(mem_ctx, info8.driver_name); 4734 if (!*driver_name) { 4735 return -1; 4736 } 4737 *version = info8.version; 4738 4739 return add_a_printer_driver_8(&info8); 4740 } 4741 4742 /**************************************************************************** 4743 ****************************************************************************/ 4744 4745 WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx, 4746 struct spoolss_DriverInfo8 **driver, 4747 const char *drivername, const char *architecture, 4748 uint32_t version) 4749 { 4750 WERROR result; 4751 struct spoolss_DriverInfo3 info3; 4752 struct spoolss_DriverInfo8 *info8; 4753 4754 ZERO_STRUCT(info3); 4755 4756 /* Sometime we just want any version of the driver */ 4757 4758 if (version == DRIVER_ANY_VERSION) { 4759 /* look for Win2k first and then for NT4 */ 4760 result = get_a_printer_driver_3(mem_ctx, 4761 &info3, 4762 drivername, 4763 architecture, 3); 4764 if (!W_ERROR_IS_OK(result)) { 4765 result = get_a_printer_driver_3(mem_ctx, 4766 &info3, 4767 drivername, 4768 architecture, 2); 4769 } 4770 } else { 4771 result = get_a_printer_driver_3(mem_ctx, 4772 &info3, 4773 drivername, 4774 architecture, 4775 version); 4776 } 4777 4778 if (!W_ERROR_IS_OK(result)) { 4779 return result; 4780 } 4781 4782 info8 = talloc_zero(mem_ctx, struct spoolss_DriverInfo8); 4783 if (!info8) { 4784 return WERR_NOMEM; 4785 } 4786 4787 info8->version = info3.version; 4788 info8->driver_name = info3.driver_name; 4789 info8->architecture = info3.architecture; 4790 info8->driver_path = info3.driver_path; 4791 info8->data_file = info3.data_file; 4792 info8->config_file = info3.config_file; 4793 info8->help_file = info3.help_file; 4794 info8->dependent_files = info3.dependent_files; 4795 info8->monitor_name = info3.monitor_name; 4796 info8->default_datatype = info3.default_datatype; 4797 4798 *driver = info8; 4799 4800 return WERR_OK; 4801 } 4802 4803 /**************************************************************************** 4804 ****************************************************************************/ 4805 4806 uint32_t free_a_printer_driver(struct spoolss_DriverInfo8 *driver) 4807 { 4808 talloc_free(driver); 4809 return 0; 4810 } 4811 1168 return err; 1169 } 4812 1170 4813 1171 /**************************************************************************** … … 4816 1174 ****************************************************************************/ 4817 1175 4818 bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r) 1176 bool printer_driver_in_use(TALLOC_CTX *mem_ctx, 1177 const struct auth_serversupplied_info *session_info, 1178 struct messaging_context *msg_ctx, 1179 const struct spoolss_DriverInfo8 *r) 4819 1180 { 4820 1181 int snum; 4821 1182 int n_services = lp_numservices(); 4822 NT_PRINTER_INFO_LEVEL *printer = NULL;4823 1183 bool in_use = False; 1184 struct spoolss_PrinterInfo2 *pinfo2 = NULL; 1185 WERROR result; 1186 struct dcerpc_binding_handle *b = NULL; 4824 1187 4825 1188 if (!r) { … … 4832 1195 4833 1196 for (snum=0; snum<n_services && !in_use; snum++) { 4834 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )1197 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) { 4835 1198 continue; 4836 4837 if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) ) 4838 continue; 4839 4840 if (strequal(r->driver_name, printer->info_2->drivername)) 1199 } 1200 1201 if (b == NULL) { 1202 result = winreg_printer_binding_handle(mem_ctx, 1203 session_info, 1204 msg_ctx, 1205 &b); 1206 if (!W_ERROR_IS_OK(result)) { 1207 return false; 1208 } 1209 } 1210 1211 result = winreg_get_printer(mem_ctx, b, 1212 lp_servicename(snum), 1213 &pinfo2); 1214 if (!W_ERROR_IS_OK(result)) { 1215 continue; /* skip */ 1216 } 1217 1218 if (strequal(r->driver_name, pinfo2->drivername)) { 4841 1219 in_use = True; 4842 4843 free_a_printer( &printer, 2 ); 1220 } 1221 1222 TALLOC_FREE(pinfo2); 4844 1223 } 4845 1224 … … 4847 1226 4848 1227 if ( in_use ) { 4849 struct spoolss_DriverInfo8 *d ;1228 struct spoolss_DriverInfo8 *driver; 4850 1229 WERROR werr; 4851 1230 … … 4856 1235 4857 1236 if (!strequal("Windows NT x86", r->architecture)) { 4858 werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", DRIVER_ANY_VERSION); 4859 } 4860 else { 4861 switch (r->version) { 4862 case 2: 4863 werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 3); 4864 break; 4865 case 3: 4866 werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 2); 4867 break; 4868 default: 4869 DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n", 4870 r->version)); 4871 werr = WERR_UNKNOWN_PRINTER_DRIVER; 4872 break; 4873 } 1237 werr = winreg_get_driver(mem_ctx, b, 1238 "Windows NT x86", 1239 r->driver_name, 1240 DRIVER_ANY_VERSION, 1241 &driver); 1242 } else if (r->version == 2) { 1243 werr = winreg_get_driver(mem_ctx, b, 1244 "Windows NT x86", 1245 r->driver_name, 1246 3, &driver); 1247 } else if (r->version == 3) { 1248 werr = winreg_get_driver(mem_ctx, b, 1249 "Windows NT x86", 1250 r->driver_name, 1251 2, &driver); 1252 } else { 1253 DEBUG(0, ("printer_driver_in_use: ERROR!" 1254 " unknown driver version (%d)\n", 1255 r->version)); 1256 werr = WERR_UNKNOWN_PRINTER_DRIVER; 4874 1257 } 4875 1258 … … 4879 1262 /* it's ok to remove the driver, we have other architctures left */ 4880 1263 in_use = False; 4881 free_a_printer_driver(d);1264 talloc_free(driver); 4882 1265 } 4883 1266 } … … 5031 1414 5032 1415 bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, 1416 const struct auth_serversupplied_info *session_info, 1417 struct messaging_context *msg_ctx, 5033 1418 struct spoolss_DriverInfo8 *info) 5034 1419 { 5035 1420 int i; 5036 int ndrivers;5037 1421 uint32 version; 5038 fstring *list = NULL;5039 1422 struct spoolss_DriverInfo8 *driver; 5040 1423 bool in_use = false; 1424 uint32_t num_drivers; 1425 const char **drivers; 1426 WERROR result; 1427 struct dcerpc_binding_handle *b; 5041 1428 5042 1429 if ( !info ) … … 5047 1434 /* loop over all driver versions */ 5048 1435 5049 DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));1436 DEBUG(5,("printer_driver_files_in_use: Beginning search of drivers...\n")); 5050 1437 5051 1438 /* get the list of drivers */ 5052 1439 5053 list = NULL; 5054 ndrivers = get_ntdrivers(&list, info->architecture, version); 5055 5056 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", 5057 ndrivers, info->architecture, version)); 1440 result = winreg_printer_binding_handle(mem_ctx, 1441 session_info, 1442 msg_ctx, 1443 &b); 1444 if (!W_ERROR_IS_OK(result)) { 1445 return false; 1446 } 1447 1448 result = winreg_get_driver_list(mem_ctx, b, 1449 info->architecture, version, 1450 &num_drivers, &drivers); 1451 if (!W_ERROR_IS_OK(result)) { 1452 return true; 1453 } 1454 1455 DEBUGADD(4, ("we have:[%d] drivers in environment [%s] and version [%d]\n", 1456 num_drivers, info->architecture, version)); 5058 1457 5059 1458 /* check each driver for overlap in files */ 5060 1459 5061 for (i =0; i<ndrivers; i++) {5062 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));1460 for (i = 0; i < num_drivers; i++) { 1461 DEBUGADD(5,("\tdriver: [%s]\n", drivers[i])); 5063 1462 5064 1463 driver = NULL; 5065 1464 5066 if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, list[i], info->architecture, version))) { 5067 SAFE_FREE(list); 1465 result = winreg_get_driver(mem_ctx, b, 1466 info->architecture, drivers[i], 1467 version, &driver); 1468 if (!W_ERROR_IS_OK(result)) { 1469 talloc_free(drivers); 5068 1470 return True; 5069 1471 } … … 5081 1483 } 5082 1484 5083 free_a_printer_driver(driver);5084 } 5085 5086 SAFE_FREE(list);5087 5088 DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));1485 talloc_free(driver); 1486 } 1487 1488 talloc_free(drivers); 1489 1490 DEBUG(5,("printer_driver_files_in_use: Completed search of drivers...\n")); 5089 1491 5090 1492 return in_use; … … 5115 1517 ****************************************************************************/ 5116 1518 5117 static bool delete_driver_files(struct pipes_struct *rpc_pipe,5118 1519 bool delete_driver_files(const struct auth_serversupplied_info *session_info, 1520 const struct spoolss_DriverInfo8 *r) 5119 1521 { 5120 1522 int i = 0; … … 5124 1526 NTSTATUS nt_status; 5125 1527 char *oldcwd; 5126 fstring printdollar;1528 char *printdollar = NULL; 5127 1529 int printdollar_snum; 5128 1530 bool ret = false; … … 5135 1537 r->driver_name, r->version)); 5136 1538 5137 fstrcpy(printdollar, "print$"); 5138 5139 printdollar_snum = find_service(printdollar); 1539 printdollar_snum = find_service(talloc_tos(), "print$", &printdollar); 1540 if (!printdollar) { 1541 return false; 1542 } 5140 1543 if (printdollar_snum == -1) { 5141 1544 return false; … … 5144 1547 nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum, 5145 1548 lp_pathname(printdollar_snum), 5146 rpc_pipe->server_info, &oldcwd);1549 session_info, &oldcwd); 5147 1550 if (!NT_STATUS_IS_OK(nt_status)) { 5148 1551 DEBUG(0,("delete_driver_files: create_conn_struct " … … 5151 1554 } 5152 1555 1556 nt_status = set_conn_force_user_group(conn, printdollar_snum); 1557 if (!NT_STATUS_IS_OK(nt_status)) { 1558 DEBUG(0, ("failed set force user / group\n")); 1559 ret = false; 1560 goto err_free_conn; 1561 } 1562 1563 if (!become_user_by_session(conn, session_info)) { 1564 DEBUG(0, ("failed to become user\n")); 1565 ret = false; 1566 goto err_free_conn; 1567 } 1568 5153 1569 if ( !CAN_WRITE(conn) ) { 5154 1570 DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n")); 5155 goto fail; 1571 ret = false; 1572 goto err_out; 5156 1573 } 5157 1574 … … 5209 1626 } 5210 1627 5211 goto done;5212 fail:5213 ret = false;5214 done:1628 ret = true; 1629 err_out: 1630 unbecome_user(); 1631 err_free_conn: 5215 1632 if (conn != NULL) { 5216 1633 vfs_ChDir(conn, oldcwd); 1634 SMB_VFS_DISCONNECT(conn); 5217 1635 conn_free(conn); 5218 1636 } 5219 1637 return ret; 5220 }5221 5222 /****************************************************************************5223 Remove a printer driver from the TDB. This assumes that the the driver was5224 previously looked up.5225 ***************************************************************************/5226 5227 WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,5228 const struct spoolss_DriverInfo8 *r,5229 uint32 version, bool delete_files )5230 {5231 char *key = NULL;5232 const char *arch;5233 TDB_DATA dbuf;5234 5235 /* delete the tdb data first */5236 5237 arch = get_short_archi(r->architecture);5238 if (!arch) {5239 return WERR_UNKNOWN_PRINTER_DRIVER;5240 }5241 if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,5242 arch, version, r->driver_name) < 0) {5243 return WERR_NOMEM;5244 }5245 5246 DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",5247 key, delete_files ? "TRUE" : "FALSE" ));5248 5249 /* check if the driver actually exists for this environment */5250 5251 dbuf = tdb_fetch_bystring( tdb_drivers, key );5252 if ( !dbuf.dptr ) {5253 DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));5254 SAFE_FREE(key);5255 return WERR_UNKNOWN_PRINTER_DRIVER;5256 }5257 5258 SAFE_FREE( dbuf.dptr );5259 5260 /* ok... the driver exists so the delete should return success */5261 5262 if (tdb_delete_bystring(tdb_drivers, key) == -1) {5263 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));5264 SAFE_FREE(key);5265 return WERR_ACCESS_DENIED;5266 }5267 5268 /*5269 * now delete any associated files if delete_files == True5270 * even if this part failes, we return succes because the5271 * driver doesn not exist any more5272 */5273 5274 if ( delete_files )5275 delete_driver_files(rpc_pipe, r);5276 5277 DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));5278 SAFE_FREE(key);5279 5280 return WERR_OK;5281 }5282 5283 /****************************************************************************5284 Store a security desc for a printer.5285 ****************************************************************************/5286 5287 WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)5288 {5289 SEC_DESC_BUF *new_secdesc_ctr = NULL;5290 SEC_DESC_BUF *old_secdesc_ctr = NULL;5291 TALLOC_CTX *mem_ctx = NULL;5292 TDB_DATA kbuf;5293 TDB_DATA dbuf;5294 DATA_BLOB blob;5295 WERROR status;5296 NTSTATUS nt_status;5297 5298 mem_ctx = talloc_init("nt_printing_setsec");5299 if (mem_ctx == NULL)5300 return WERR_NOMEM;5301 5302 /* The old owner and group sids of the security descriptor are not5303 present when new ACEs are added or removed by changing printer5304 permissions through NT. If they are NULL in the new security5305 descriptor then copy them over from the old one. */5306 5307 if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {5308 DOM_SID *owner_sid, *group_sid;5309 SEC_ACL *dacl, *sacl;5310 SEC_DESC *psd = NULL;5311 size_t size;5312 5313 if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {5314 status = WERR_NOMEM;5315 goto out;5316 }5317 5318 /* Pick out correct owner and group sids */5319 5320 owner_sid = secdesc_ctr->sd->owner_sid ?5321 secdesc_ctr->sd->owner_sid :5322 old_secdesc_ctr->sd->owner_sid;5323 5324 group_sid = secdesc_ctr->sd->group_sid ?5325 secdesc_ctr->sd->group_sid :5326 old_secdesc_ctr->sd->group_sid;5327 5328 dacl = secdesc_ctr->sd->dacl ?5329 secdesc_ctr->sd->dacl :5330 old_secdesc_ctr->sd->dacl;5331 5332 sacl = secdesc_ctr->sd->sacl ?5333 secdesc_ctr->sd->sacl :5334 old_secdesc_ctr->sd->sacl;5335 5336 /* Make a deep copy of the security descriptor */5337 5338 psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,5339 owner_sid, group_sid,5340 sacl,5341 dacl,5342 &size);5343 5344 if (!psd) {5345 status = WERR_NOMEM;5346 goto out;5347 }5348 5349 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);5350 }5351 5352 if (!new_secdesc_ctr) {5353 new_secdesc_ctr = secdesc_ctr;5354 }5355 5356 /* Store the security descriptor in a tdb */5357 5358 nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,5359 &blob.data, &blob.length);5360 if (!NT_STATUS_IS_OK(nt_status)) {5361 status = ntstatus_to_werror(nt_status);5362 goto out;5363 }5364 5365 kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );5366 5367 dbuf.dptr = (unsigned char *)blob.data;5368 dbuf.dsize = blob.length;5369 5370 if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {5371 status = WERR_OK;5372 } else {5373 DEBUG(1,("Failed to store secdesc for %s\n", sharename));5374 status = WERR_BADFUNC;5375 }5376 5377 /* Free malloc'ed memory */5378 talloc_free(blob.data);5379 5380 out:5381 5382 if (mem_ctx)5383 talloc_destroy(mem_ctx);5384 return status;5385 }5386 5387 /****************************************************************************5388 Construct a default security descriptor buffer for a printer.5389 ****************************************************************************/5390 5391 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)5392 {5393 SEC_ACE ace[5]; /* max number of ace entries */5394 int i = 0;5395 uint32_t sa;5396 SEC_ACL *psa = NULL;5397 SEC_DESC_BUF *sdb = NULL;5398 SEC_DESC *psd = NULL;5399 DOM_SID adm_sid;5400 size_t sd_size;5401 5402 /* Create an ACE where Everyone is allowed to print */5403 5404 sa = PRINTER_ACE_PRINT;5405 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,5406 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5407 5408 /* Add the domain admins group if we are a DC */5409 5410 if ( IS_DC ) {5411 DOM_SID domadmins_sid;5412 5413 sid_copy(&domadmins_sid, get_global_sam_sid());5414 sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);5415 5416 sa = PRINTER_ACE_FULL_CONTROL;5417 init_sec_ace(&ace[i++], &domadmins_sid,5418 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,5419 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);5420 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,5421 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5422 }5423 else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {5424 sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);5425 5426 sa = PRINTER_ACE_FULL_CONTROL;5427 init_sec_ace(&ace[i++], &adm_sid,5428 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,5429 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);5430 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,5431 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5432 }5433 5434 /* add BUILTIN\Administrators as FULL CONTROL */5435 5436 sa = PRINTER_ACE_FULL_CONTROL;5437 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,5438 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,5439 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);5440 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,5441 SEC_ACE_TYPE_ACCESS_ALLOWED,5442 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5443 5444 /* Make the security descriptor owned by the BUILTIN\Administrators */5445 5446 /* The ACL revision number in rpc_secdesc.h differs from the one5447 created by NT when setting ACE entries in printer5448 descriptors. NT4 complains about the property being edited by a5449 NT5 machine. */5450 5451 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {5452 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,5453 &global_sid_Builtin_Administrators,5454 &global_sid_Builtin_Administrators,5455 NULL, psa, &sd_size);5456 }5457 5458 if (!psd) {5459 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));5460 return NULL;5461 }5462 5463 sdb = make_sec_desc_buf(ctx, sd_size, psd);5464 5465 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",5466 (unsigned int)sd_size));5467 5468 return sdb;5469 }5470 5471 /****************************************************************************5472 Get a security desc for a printer.5473 ****************************************************************************/5474 5475 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)5476 {5477 TDB_DATA kbuf;5478 TDB_DATA dbuf;5479 DATA_BLOB blob;5480 char *temp;5481 NTSTATUS status;5482 5483 if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {5484 sharename = temp + 1;5485 }5486 5487 /* Fetch security descriptor from tdb */5488 5489 kbuf = make_printers_secdesc_tdbkey(ctx, sharename);5490 5491 dbuf = tdb_fetch(tdb_printers, kbuf);5492 if (dbuf.dptr) {5493 5494 status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,5495 secdesc_ctr);5496 SAFE_FREE(dbuf.dptr);5497 5498 if (NT_STATUS_IS_OK(status)) {5499 return true;5500 }5501 }5502 5503 *secdesc_ctr = construct_default_printer_sdb(ctx);5504 if (!*secdesc_ctr) {5505 return false;5506 }5507 5508 status = marshall_sec_desc_buf(ctx, *secdesc_ctr,5509 &blob.data, &blob.length);5510 if (NT_STATUS_IS_OK(status)) {5511 dbuf.dptr = (unsigned char *)blob.data;5512 dbuf.dsize = blob.length;5513 tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);5514 talloc_free(blob.data);5515 }5516 5517 /* If security descriptor is owned by S-1-1-0 and winbindd is up,5518 this security descriptor has been created when winbindd was5519 down. Take ownership of security descriptor. */5520 5521 if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {5522 DOM_SID owner_sid;5523 5524 /* Change sd owner to workgroup administrator */5525 5526 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {5527 SEC_DESC_BUF *new_secdesc_ctr = NULL;5528 SEC_DESC *psd = NULL;5529 size_t size;5530 5531 /* Create new sd */5532 5533 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);5534 5535 psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,5536 &owner_sid,5537 (*secdesc_ctr)->sd->group_sid,5538 (*secdesc_ctr)->sd->sacl,5539 (*secdesc_ctr)->sd->dacl,5540 &size);5541 5542 if (!psd) {5543 return False;5544 }5545 5546 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);5547 if (!new_secdesc_ctr) {5548 return False;5549 }5550 5551 /* Swap with other one */5552 5553 *secdesc_ctr = new_secdesc_ctr;5554 5555 /* Set it */5556 5557 nt_printing_setsec(sharename, *secdesc_ctr);5558 }5559 }5560 5561 if (DEBUGLEVEL >= 10) {5562 SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;5563 int i;5564 5565 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",5566 sharename, the_acl->num_aces));5567 5568 for (i = 0; i < the_acl->num_aces; i++) {5569 DEBUG(10, ("%s %d %d 0x%08x\n",5570 sid_string_dbg(&the_acl->aces[i].trustee),5571 the_acl->aces[i].type, the_acl->aces[i].flags,5572 the_acl->aces[i].access_mask));5573 }5574 }5575 5576 return True;5577 1638 } 5578 1639 … … 5617 1678 NT5 the object specific ones. */ 5618 1679 5619 void map_printer_permissions( SEC_DESC*sd)1680 void map_printer_permissions(struct security_descriptor *sd) 5620 1681 { 5621 1682 int i; … … 5627 1688 } 5628 1689 5629 void map_job_permissions( SEC_DESC*sd)1690 void map_job_permissions(struct security_descriptor *sd) 5630 1691 { 5631 1692 int i; … … 5661 1722 5662 1723 ****************************************************************************/ 5663 bool print_access_check(struct auth_serversupplied_info *server_info, int snum, 1724 bool print_access_check(const struct auth_serversupplied_info *session_info, 1725 struct messaging_context *msg_ctx, int snum, 5664 1726 int access_type) 5665 1727 { 5666 SEC_DESC_BUF*secdesc = NULL;1728 struct spoolss_security_descriptor *secdesc = NULL; 5667 1729 uint32 access_granted; 1730 size_t sd_size; 5668 1731 NTSTATUS status; 1732 WERROR result; 5669 1733 const char *pname; 5670 1734 TALLOC_CTX *mem_ctx = NULL; 5671 SE_PRIV se_printop = SE_PRINT_OPERATOR;5672 1735 5673 1736 /* If user is NULL then use the current_user structure */ … … 5675 1738 /* Always allow root or SE_PRINT_OPERATROR to do anything */ 5676 1739 5677 if (se rver_info->utok.uid == sec_initial_uid()5678 || user_has_privileges(server_info->ptok, &se_printop )) {1740 if (session_info->utok.uid == sec_initial_uid() 1741 || security_token_has_privilege(session_info->security_token, SEC_PRIV_PRINT_OPERATOR)) { 5679 1742 return True; 5680 1743 } … … 5682 1745 /* Get printer name */ 5683 1746 5684 pname = PRINTERNAME(snum);1747 pname = lp_printername(snum); 5685 1748 5686 1749 if (!pname || !*pname) { … … 5696 1759 } 5697 1760 5698 if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) { 1761 result = winreg_get_printer_secdesc_internal(mem_ctx, 1762 get_session_info_system(), 1763 msg_ctx, 1764 pname, 1765 &secdesc); 1766 if (!W_ERROR_IS_OK(result)) { 5699 1767 talloc_destroy(mem_ctx); 5700 1768 errno = ENOMEM; … … 5703 1771 5704 1772 if (access_type == JOB_ACCESS_ADMINISTER) { 5705 SEC_DESC_BUF*parent_secdesc = secdesc;1773 struct spoolss_security_descriptor *parent_secdesc = secdesc; 5706 1774 5707 1775 /* Create a child security descriptor to check permissions 5708 1776 against. This is because print jobs are child objects 5709 1777 objects of a printer. */ 5710 5711 status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False); 5712 1778 status = se_create_child_secdesc(mem_ctx, 1779 &secdesc, 1780 &sd_size, 1781 parent_secdesc, 1782 parent_secdesc->owner_sid, 1783 parent_secdesc->group_sid, 1784 false); 5713 1785 if (!NT_STATUS_IS_OK(status)) { 5714 1786 talloc_destroy(mem_ctx); … … 5717 1789 } 5718 1790 5719 map_job_permissions(secdesc ->sd);1791 map_job_permissions(secdesc); 5720 1792 } else { 5721 map_printer_permissions(secdesc ->sd);1793 map_printer_permissions(secdesc); 5722 1794 } 5723 1795 5724 1796 /* Check access */ 5725 status = se_access_check(secdesc ->sd, server_info->ptok, access_type,1797 status = se_access_check(secdesc, session_info->security_token, access_type, 5726 1798 &access_granted); 5727 1799 … … 5731 1803 5732 1804 if (!NT_STATUS_IS_OK(status) && 5733 (token_contains_name_in_list(uidtoname(server_info->utok.uid), 5734 pdb_get_domain(server_info->sam_account), 5735 NULL, 5736 server_info->ptok, 1805 (token_contains_name_in_list(uidtoname(session_info->utok.uid), 1806 session_info->info3->base.domain.string, 1807 NULL, session_info->security_token, 5737 1808 lp_printer_admin(snum)))) { 5738 1809 talloc_destroy(mem_ctx); … … 5753 1824 *****************************************************************************/ 5754 1825 5755 bool print_time_access_check(const char *servicename) 5756 { 5757 NT_PRINTER_INFO_LEVEL *printer = NULL; 1826 bool print_time_access_check(const struct auth_serversupplied_info *session_info, 1827 struct messaging_context *msg_ctx, 1828 const char *servicename) 1829 { 1830 struct spoolss_PrinterInfo2 *pinfo2 = NULL; 1831 WERROR result; 5758 1832 bool ok = False; 5759 1833 time_t now = time(NULL); … … 5761 1835 uint32 mins; 5762 1836 5763 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) 1837 result = winreg_get_printer_internal(NULL, session_info, msg_ctx, 1838 servicename, &pinfo2); 1839 if (!W_ERROR_IS_OK(result)) { 5764 1840 return False; 5765 5766 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0) 1841 } 1842 1843 if (pinfo2->starttime == 0 && pinfo2->untiltime == 0) { 5767 1844 ok = True; 1845 } 5768 1846 5769 1847 t = gmtime(&now); 5770 1848 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min; 5771 1849 5772 if (mins >= p rinter->info_2->starttime && mins <= printer->info_2->untiltime)1850 if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) { 5773 1851 ok = True; 5774 5775 free_a_printer(&printer, 2); 5776 5777 if (!ok) 1852 } 1853 1854 TALLOC_FREE(pinfo2); 1855 1856 if (!ok) { 5778 1857 errno = EACCES; 1858 } 5779 1859 5780 1860 return ok; 5781 1861 } 5782 1862 5783 /**************************************************************************** 5784 Fill in the servername sent in the _spoolss_open_printer_ex() call 5785 ****************************************************************************/ 5786 5787 char* get_server_name( Printer_entry *printer ) 5788 { 5789 return printer->servername; 5790 } 5791 5792 1863 void nt_printer_remove(TALLOC_CTX *mem_ctx, 1864 const struct auth_serversupplied_info *session_info, 1865 struct messaging_context *msg_ctx, 1866 const char *printer) 1867 { 1868 WERROR result; 1869 1870 result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx, 1871 printer, ""); 1872 if (!W_ERROR_IS_OK(result)) { 1873 DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s", 1874 printer)); 1875 } 1876 } -
vendor/current/source3/printing/pcap.c
r597 r740 27 27 28 28 /* 29 * This module contains code to parse and cache printcap data, possibly30 * in concert with the CUPS/SYSV/AIX-specific code found elsewhere.31 *32 * The way this module looks at the printcap file is very simplistic.33 * Only the local printcap file is inspected (no searching of NIS34 * databases etc).35 *36 * There are assumed to be one or more printer names per record, held37 * as a set of sub-fields separated by vertical bar symbols ('|') in the38 * first field of the record. The field separator is assumed to be a colon39 * ':' and the record separator a newline.40 *41 * Lines ending with a backspace '\' are assumed to flag that the following42 * line is a continuation line so that a set of lines can be read as one43 * printcap entry.44 *45 * A line stating with a hash '#' is assumed to be a comment and is ignored46 * Comments are discarded before the record is strung together from the47 * set of continuation lines.48 *49 * Opening a pipe for "lpc status" and reading that would probably50 * be pretty effective. Code to do this already exists in the freely51 * distributable PCNFS server code.52 *53 29 * Modified to call SVID/XPG4 support if printcap name is set to "lpstat" 54 30 * in smb.conf under Solaris. … … 62 38 63 39 #include "includes.h" 64 40 #include "printing/pcap.h" 41 #include "printer_list.h" 65 42 66 43 struct pcap_cache { 67 44 char *name; 68 45 char *comment; 46 char *location; 69 47 struct pcap_cache *next; 70 48 }; 71 49 72 /* The systemwide printcap cache. */ 73 static struct pcap_cache *pcap_cache = NULL; 74 75 bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment) 50 bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location) 76 51 { 77 52 struct pcap_cache *p; … … 82 57 p->name = SMB_STRDUP(name); 83 58 p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL; 84 85 DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s\n", 86 p->name, p->comment ? p->comment : "")); 59 p->location = (location && *location) ? SMB_STRDUP(location) : NULL; 60 61 DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s, location: %s\n", 62 p->name, p->comment ? p->comment : "", 63 p->location ? p->location : "")); 87 64 88 65 p->next = *ppcache; … … 101 78 SAFE_FREE(p->name); 102 79 SAFE_FREE(p->comment); 80 SAFE_FREE(p->location); 103 81 SAFE_FREE(p); 104 82 } … … 106 84 } 107 85 108 bool pcap_cache_add(const char *name, const char *comment) 109 { 110 return pcap_cache_add_specific(&pcap_cache, name, comment); 86 bool pcap_cache_add(const char *name, const char *comment, const char *location) 87 { 88 NTSTATUS status; 89 time_t t = time_mono(NULL); 90 91 status = printer_list_set_printer(talloc_tos(), name, comment, location, t); 92 return NT_STATUS_IS_OK(status); 111 93 } 112 94 113 95 bool pcap_cache_loaded(void) 114 96 { 115 return (pcap_cache != NULL); 116 } 117 118 void pcap_cache_replace(const struct pcap_cache *pcache) 97 NTSTATUS status; 98 time_t last; 99 100 status = printer_list_get_last_refresh(&last); 101 return NT_STATUS_IS_OK(status); 102 } 103 104 bool pcap_cache_replace(const struct pcap_cache *pcache) 119 105 { 120 106 const struct pcap_cache *p; 121 122 pcap_cache_destroy_specific(&pcap_cache); 107 NTSTATUS status; 108 109 status = printer_list_mark_reload(); 110 if (!NT_STATUS_IS_OK(status)) { 111 DEBUG(0, ("Failed to mark printer list for reload!\n")); 112 return false; 113 } 114 123 115 for (p = pcache; p; p = p->next) { 124 pcap_cache_add(p->name, p->comment); 125 } 126 } 127 128 void pcap_cache_reload(void (*post_cache_fill_fn)(void)) 116 pcap_cache_add(p->name, p->comment, p->location); 117 } 118 119 status = printer_list_clean_old(); 120 if (!NT_STATUS_IS_OK(status)) { 121 DEBUG(0, ("Failed to cleanup printer list!\n")); 122 return false; 123 } 124 125 return true; 126 } 127 128 void pcap_cache_reload(struct tevent_context *ev, 129 struct messaging_context *msg_ctx, 130 void (*post_cache_fill_fn)(struct tevent_context *, 131 struct messaging_context *)) 129 132 { 130 133 const char *pcap_name = lp_printcapname(); 131 134 bool pcap_reloaded = False; 132 struct pcap_cache *tmp_cache = NULL; 133 XFILE *pcap_file; 134 char *pcap_line; 135 NTSTATUS status; 135 136 bool post_cache_fill_fn_handled = false; 136 137 … … 143 144 } 144 145 145 tmp_cache = pcap_cache; 146 pcap_cache = NULL; 146 status = printer_list_mark_reload(); 147 if (!NT_STATUS_IS_OK(status)) { 148 DEBUG(0, ("Failed to mark printer list for reload!\n")); 149 return; 150 } 147 151 148 152 #ifdef HAVE_CUPS 149 153 if (strequal(pcap_name, "cups")) { 150 pcap_reloaded = cups_cache_reload(post_cache_fill_fn); 154 pcap_reloaded = cups_cache_reload(ev, msg_ctx, 155 post_cache_fill_fn); 151 156 /* 152 157 * cups_cache_reload() is async and calls post_cache_fill_fn() … … 179 184 #endif 180 185 181 /* handle standard printcap - moved from pcap_printer_fn() */ 182 183 if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) { 184 DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name)); 185 goto done; 186 } 187 188 for (; (pcap_line = fgets_slash(NULL, 1024, pcap_file)) != NULL; free(pcap_line)) { 189 char name[MAXPRINTERLEN+1]; 190 char comment[62]; 191 char *p, *q; 192 193 if (*pcap_line == '#' || *pcap_line == 0) 194 continue; 195 196 /* now we have a real printer line - cut at the first : */ 197 if ((p = strchr_m(pcap_line, ':')) != NULL) 198 *p = 0; 199 200 /* 201 * now find the most likely printer name and comment 202 * this is pure guesswork, but it's better than nothing 203 */ 204 for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) { 205 bool has_punctuation; 206 207 if ((q = strchr_m(p, '|')) != NULL) 208 *q++ = 0; 209 210 has_punctuation = (strchr_m(p, ' ') || 211 strchr_m(p, '\t') || 212 strchr_m(p, '"') || 213 strchr_m(p, '\'') || 214 strchr_m(p, ';') || 215 strchr_m(p, ',') || 216 strchr_m(p, '(') || 217 strchr_m(p, ')')); 218 219 if (strlen(p) > strlen(comment) && has_punctuation) { 220 strlcpy(comment, p, sizeof(comment)); 221 continue; 222 } 223 224 if (strlen(p) <= MAXPRINTERLEN && *name == '\0' && !has_punctuation) { 225 if (!*comment) { 226 strlcpy(comment, name, sizeof(comment)); 227 } 228 strlcpy(name, p, sizeof(name)); 229 continue; 230 } 231 232 if (!strchr_m(comment, ' ') && 233 strlen(p) > strlen(comment)) { 234 strlcpy(comment, p, sizeof(comment)); 235 continue; 236 } 237 } 238 239 if (*name && !pcap_cache_add(name, comment)) { 240 x_fclose(pcap_file); 241 goto done; 242 } 243 } 244 245 x_fclose(pcap_file); 246 pcap_reloaded = True; 186 pcap_reloaded = std_pcap_cache_reload(pcap_name); 247 187 248 188 done: 249 189 DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error")); 250 190 251 if (pcap_reloaded) { 252 pcap_cache_destroy_specific(&tmp_cache); 253 if ((post_cache_fill_fn_handled == false) 254 && (post_cache_fill_fn != NULL)) { 255 post_cache_fill_fn(); 191 if ((pcap_reloaded) && (post_cache_fill_fn_handled == false)) { 192 /* cleanup old entries only if the operation was successful, 193 * otherwise keep around the old entries until we can 194 * successfuly reaload */ 195 status = printer_list_clean_old(); 196 if (!NT_STATUS_IS_OK(status)) { 197 DEBUG(0, ("Failed to cleanup printer list!\n")); 256 198 } 257 } else{258 pcap_cache_destroy_specific(&pcap_cache);259 pcap_cache = tmp_cache;199 if (post_cache_fill_fn != NULL) { 200 post_cache_fill_fn(ev, msg_ctx); 201 } 260 202 } 261 203 … … 266 208 bool pcap_printername_ok(const char *printername) 267 209 { 268 struct pcap_cache *p; 269 270 for (p = pcap_cache; p != NULL; p = p->next) 271 if (strequal(p->name, printername)) 272 return True; 273 274 return False; 210 NTSTATUS status; 211 212 status = printer_list_get_printer(talloc_tos(), printername, NULL, NULL, 0); 213 return NT_STATUS_IS_OK(status); 275 214 } 276 215 … … 280 219 281 220 void pcap_printer_fn_specific(const struct pcap_cache *pc, 282 void (*fn)(const char *, const char *, void *),221 void (*fn)(const char *, const char *, const char *, void *), 283 222 void *pdata) 284 223 { … … 286 225 287 226 for (p = pc; p != NULL; p = p->next) 288 fn(p->name, p->comment, p data);227 fn(p->name, p->comment, p->location, pdata); 289 228 290 229 return; 291 230 } 292 231 293 void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *pdata) 294 { 295 pcap_printer_fn_specific(pcap_cache, fn, pdata); 296 } 232 void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata) 233 { 234 NTSTATUS status; 235 236 status = printer_list_run_fn(fn, pdata); 237 if (!NT_STATUS_IS_OK(status)) { 238 DEBUG(3, ("Failed to run fn for all printers!\n")); 239 } 240 return; 241 } -
vendor/current/source3/printing/print_aix.c
r414 r740 26 26 27 27 #include "includes.h" 28 #include "system/filesys.h" 29 #include "printing/pcap.h" 28 30 29 31 #ifdef AIX … … 85 87 /* probably a good printer ??? */ 86 88 iEtat = 0; 87 if (!pcap_cache_add(name, NULL )) {89 if (!pcap_cache_add(name, NULL, NULL)) { 88 90 SAFE_FREE(line); 89 91 x_fclose(pfile); … … 100 102 /* it's a good virtual printer */ 101 103 iEtat = 0; 102 if (!pcap_cache_add(name, NULL )) {104 if (!pcap_cache_add(name, NULL, NULL)) { 103 105 SAFE_FREE(line); 104 106 x_fclose(pfile); -
vendor/current/source3/printing/print_cups.c
r597 r740 25 25 #include "includes.h" 26 26 #include "printing.h" 27 #include "printing/pcap.h" 27 28 #include "librpc/gen_ndr/ndr_printcap.h" 28 29 … … 37 38 ****************************************************************/ 38 39 39 static void gotalarm_sig( void)40 static void gotalarm_sig(int signum) 40 41 { 41 42 gotalarm = 1; … … 91 92 92 93 if (timeout) { 93 CatchSignal(SIGALRM, SIGNAL_CASTgotalarm_sig);94 CatchSignal(SIGALRM, gotalarm_sig); 94 95 alarm(timeout); 95 96 } … … 102 103 103 104 104 CatchSignal(SIGALRM, SIG NAL_CAST SIG_IGN);105 CatchSignal(SIGALRM, SIG_IGN); 105 106 alarm(0); 106 107 … … 127 128 } 128 129 129 DEBUG(10, ("successfully sent blob of len % ld\n", (int64_t)ret));130 DEBUG(10, ("successfully sent blob of len %d\n", (int)ret)); 130 131 return true; 131 132 } … … 152 153 } 153 154 154 DEBUG(10, ("successfully recvd blob of len % ld\n", (int64_t)ret));155 DEBUG(10, ("successfully recvd blob of len %d\n", (int)ret)); 155 156 return true; 156 157 } … … 163 164 char *name; 164 165 char *info; 166 char *location = NULL; 165 167 struct pcap_printer *printer; 166 168 bool ret_ok = false; … … 200 202 if (!pull_utf8_talloc(mem_ctx, 201 203 &info, 204 attr->values[0].string.text, 205 &size)) { 206 goto err_out; 207 } 208 } 209 210 if (strcmp(attr->name, "printer-location") == 0 && 211 attr->value_tag == IPP_TAG_TEXT) { 212 if (!pull_utf8_talloc(mem_ctx, 213 &location, 202 214 attr->values[0].string.text, 203 215 &size)) { … … 229 241 pcap_data->printers[pcap_data->count].name = name; 230 242 pcap_data->printers[pcap_data->count].info = info; 243 pcap_data->printers[pcap_data->count].location = location; 231 244 pcap_data->count++; 232 245 } … … 252 265 { 253 266 "printer-name", 254 "printer-info" 267 "printer-info", 268 "printer-location" 255 269 }; 256 270 bool ret = False; … … 364 378 365 379 ret = false; 366 ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, NULL,&pcap_data,380 ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, &pcap_data, 367 381 (ndr_push_flags_fn_t)ndr_push_pcap_data); 368 382 if (ndr_ret == NDR_ERR_SUCCESS) { … … 374 388 } 375 389 376 static struct pcap_cache *local_pcap_copy; 377 struct fd_event *cache_fd_event; 378 379 static bool cups_pcap_load_async(int *pfd) 390 static struct fd_event *cache_fd_event; 391 392 static bool cups_pcap_load_async(struct tevent_context *ev, 393 struct messaging_context *msg_ctx, 394 int *pfd) 380 395 { 381 396 int fds[2]; 382 397 pid_t pid; 398 NTSTATUS status; 383 399 384 400 *pfd = -1; … … 418 434 close_all_print_db(); 419 435 420 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),421 smbd_event_context(), true))) {436 status = reinit_after_fork(msg_ctx, ev, procid_self(), true); 437 if (!NT_STATUS_IS_OK(status)) { 422 438 DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n")); 423 439 smb_panic("cups_pcap_load_async: reinit_after_fork() failed"); … … 432 448 struct cups_async_cb_args { 433 449 int pipe_fd; 434 void (*post_cache_fill_fn)(void); 450 struct event_context *event_ctx; 451 struct messaging_context *msg_ctx; 452 void (*post_cache_fill_fn)(struct event_context *, 453 struct messaging_context *); 435 454 }; 436 455 … … 458 477 } 459 478 460 ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, NULL,&pcap_data,479 ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, &pcap_data, 461 480 (ndr_pull_flags_fn_t)ndr_pull_pcap_data); 462 481 if (ndr_ret != NDR_ERR_SUCCESS) { … … 473 492 ret_ok = pcap_cache_add_specific(&tmp_pcap_cache, 474 493 pcap_data.printers[i].name, 475 pcap_data.printers[i].info); 494 pcap_data.printers[i].info, 495 pcap_data.printers[i].location); 476 496 if (!ret_ok) { 477 497 DEBUG(0, ("failed to add to tmp pcap cache\n")); 478 break;498 goto err_out; 479 499 } 480 500 } 481 501 502 /* replace the system-wide pcap cache with a (possibly empty) new one */ 503 ret_ok = pcap_cache_replace(tmp_pcap_cache); 482 504 if (!ret_ok) { 483 DEBUG(0,("failed to read a new printer list\n")); 484 pcap_cache_destroy_specific(&tmp_pcap_cache); 485 } else { 486 /* We got a possibly empty namelist, replace our local cache. */ 487 pcap_cache_destroy_specific(&local_pcap_copy); 488 local_pcap_copy = tmp_pcap_cache; 489 490 /* And the systemwide pcap cache. */ 491 pcap_cache_replace(local_pcap_copy); 492 493 /* Caller may have requested post cache fill callback */ 494 if (cb_args->post_cache_fill_fn) { 495 cb_args->post_cache_fill_fn(); 496 } 505 DEBUG(0, ("failed to replace pcap cache\n")); 506 } else if (cb_args->post_cache_fill_fn != NULL) { 507 /* Caller requested post cache fill callback */ 508 cb_args->post_cache_fill_fn(cb_args->event_ctx, 509 cb_args->msg_ctx); 497 510 } 498 511 err_out: 512 pcap_cache_destroy_specific(&tmp_pcap_cache); 499 513 TALLOC_FREE(frame); 500 514 close(cb_args->pipe_fd); … … 503 517 } 504 518 505 bool cups_cache_reload(void (*post_cache_fill_fn)(void)) 519 bool cups_cache_reload(struct tevent_context *ev, 520 struct messaging_context *msg_ctx, 521 void (*post_cache_fill_fn)(struct tevent_context *, 522 struct messaging_context *)) 506 523 { 507 524 struct cups_async_cb_args *cb_args; … … 509 526 510 527 cb_args = TALLOC_P(NULL, struct cups_async_cb_args); 511 if ( !cb_args) {528 if (cb_args == NULL) { 512 529 return false; 513 530 } 531 514 532 cb_args->post_cache_fill_fn = post_cache_fill_fn; 533 cb_args->event_ctx = ev; 534 cb_args->msg_ctx = msg_ctx; 515 535 p_pipe_fd = &cb_args->pipe_fd; 516 536 *p_pipe_fd = -1; 517 537 518 538 /* Set up an async refresh. */ 519 if (!cups_pcap_load_async( p_pipe_fd)) {539 if (!cups_pcap_load_async(ev, msg_ctx, p_pipe_fd)) { 520 540 talloc_free(cb_args); 521 541 return false; 522 542 } 523 if (!local_pcap_copy) { 524 /* We have no local cache, wait directly for 525 * async refresh to complete. 526 */ 527 DEBUG(10,("cups_cache_reload: sync read on fd %d\n", 528 *p_pipe_fd )); 529 530 cups_async_callback(smbd_event_context(), 531 NULL, 532 EVENT_FD_READ, 533 (void *)cb_args); 534 if (!local_pcap_copy) { 535 return false; 536 } 537 } else { 538 /* Replace the system cache with our 539 * local copy. */ 540 pcap_cache_replace(local_pcap_copy); 541 542 DEBUG(10,("cups_cache_reload: async read on fd %d\n", 543 *p_pipe_fd )); 544 545 /* Trigger an event when the pipe can be read. */ 546 cache_fd_event = event_add_fd(smbd_event_context(), 547 NULL, *p_pipe_fd, 548 EVENT_FD_READ, 549 cups_async_callback, 550 (void *)cb_args); 551 if (!cache_fd_event) { 552 close(*p_pipe_fd); 553 talloc_free(cb_args); 554 return false; 555 } 556 } 543 544 DEBUG(10,("cups_cache_reload: async read on fd %d\n", 545 *p_pipe_fd )); 546 547 /* Trigger an event when the pipe can be read. */ 548 cache_fd_event = event_add_fd(ev, 549 NULL, *p_pipe_fd, 550 EVENT_FD_READ, 551 cups_async_callback, 552 (void *)cb_args); 553 if (!cache_fd_event) { 554 close(*p_pipe_fd); 555 TALLOC_FREE(cb_args); 556 return false; 557 } 558 557 559 return true; 558 560 } … … 861 863 cups_lang_t *language = NULL; /* Default language */ 862 864 char uri[HTTP_MAX_URI]; /* printer-uri attribute */ 863 const char *clientname = NULL; /* hostname of client for job-originating-host attribute */864 865 char *new_jobname = NULL; 865 866 int num_options = 0; … … 872 873 size_t size; 873 874 uint32_t jobid = (uint32_t)-1; 874 char addr[INET6_ADDRSTRLEN];875 875 876 876 DEBUG(5,("cups_job_submit(%d, %p)\n", snum, pjob)); … … 914 914 "attributes-natural-language", NULL, language->language); 915 915 916 if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { 916 if (!push_utf8_talloc(frame, &printername, lp_printername(snum), 917 &size)) { 917 918 goto out; 918 919 } … … 929 930 NULL, user); 930 931 931 clientname = client_name(get_client_fd());932 if (strcmp(clientname, "UNKNOWN") == 0) {933 clientname = client_addr(get_client_fd(),addr,sizeof(addr));934 }935 936 932 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, 937 933 "job-originating-host-name", NULL, 938 clientname);934 pjob->clientmachine); 939 935 940 936 /* Get the jobid from the filename. */ … … 985 981 if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { 986 982 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 987 DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum), 983 DEBUG(0,("Unable to print file to %s - %s\n", 984 lp_printername(snum), 988 985 ippErrorString(cupsLastError()))); 989 986 } else { … … 998 995 } 999 996 } else { 1000 DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum), 997 DEBUG(0,("Unable to print file to `%s' - %s\n", 998 lp_printername(snum), 1001 999 ippErrorString(cupsLastError()))); 1002 1000 } … … 1423 1421 "attributes-natural-language", NULL, language->language); 1424 1422 1425 if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { 1423 if (!push_utf8_talloc(frame, &printername, lp_printername(snum), 1424 &size)) { 1426 1425 goto out; 1427 1426 } … … 1443 1442 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) { 1444 1443 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 1445 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum), 1444 DEBUG(0,("Unable to pause printer %s - %s\n", 1445 lp_printername(snum), 1446 1446 ippErrorString(cupsLastError()))); 1447 1447 } else { … … 1449 1449 } 1450 1450 } else { 1451 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum), 1451 DEBUG(0,("Unable to pause printer %s - %s\n", 1452 lp_printername(snum), 1452 1453 ippErrorString(cupsLastError()))); 1453 1454 } … … 1524 1525 "attributes-natural-language", NULL, language->language); 1525 1526 1526 if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { 1527 if (!push_utf8_talloc(frame, &printername, lp_printername(snum), 1528 &size)) { 1527 1529 goto out; 1528 1530 } … … 1544 1546 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) { 1545 1547 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 1546 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum), 1548 DEBUG(0,("Unable to resume printer %s - %s\n", 1549 lp_printername(snum), 1547 1550 ippErrorString(cupsLastError()))); 1548 1551 } else { … … 1550 1553 } 1551 1554 } else { 1552 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum), 1555 DEBUG(0,("Unable to resume printer %s - %s\n", 1556 lp_printername(snum), 1553 1557 ippErrorString(cupsLastError()))); 1554 1558 } … … 1584 1588 }; 1585 1589 1586 bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)1587 {1588 TALLOC_CTX *frame = talloc_stackframe();1589 http_t *http = NULL; /* HTTP connection to server */1590 ipp_t *request = NULL, /* IPP Request */1591 *response = NULL; /* IPP Response */1592 ipp_attribute_t *attr; /* Current attribute */1593 cups_lang_t *language = NULL; /* Default language */1594 char uri[HTTP_MAX_URI];1595 char *sharename = NULL;1596 char *name = NULL;1597 static const char *requested[] =/* Requested attributes */1598 {1599 "printer-name",1600 "printer-info",1601 "printer-location"1602 };1603 bool ret = False;1604 size_t size;1605 1606 DEBUG(5, ("pulling %s location\n", printer->sharename));1607 1608 /*1609 * Make sure we don't ask for passwords...1610 */1611 1612 cupsSetPasswordCB(cups_passwd_cb);1613 1614 /*1615 * Try to connect to the server...1616 */1617 1618 if ((http = cups_connect(frame)) == NULL) {1619 goto out;1620 }1621 1622 request = ippNew();1623 1624 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;1625 request->request.op.request_id = 1;1626 1627 language = cupsLangDefault();1628 1629 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,1630 "attributes-charset", NULL, "utf-8");1631 1632 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,1633 "attributes-natural-language", NULL, language->language);1634 1635 if (!push_utf8_talloc(frame, &sharename, printer->sharename, &size)) {1636 goto out;1637 }1638 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",1639 sharename);1640 1641 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,1642 "printer-uri", NULL, uri);1643 1644 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,1645 "requested-attributes",1646 (sizeof(requested) / sizeof(requested[0])),1647 NULL, requested);1648 1649 /*1650 * Do the request and get back a response...1651 */1652 1653 if ((response = cupsDoRequest(http, request, "/")) == NULL) {1654 DEBUG(0,("Unable to get printer attributes - %s\n",1655 ippErrorString(cupsLastError())));1656 goto out;1657 }1658 1659 for (attr = response->attrs; attr != NULL;) {1660 /*1661 * Skip leading attributes until we hit a printer...1662 */1663 1664 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)1665 attr = attr->next;1666 1667 if (attr == NULL)1668 break;1669 1670 /*1671 * Pull the needed attributes from this printer...1672 */1673 1674 while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {1675 if (strcmp(attr->name, "printer-name") == 0 &&1676 attr->value_tag == IPP_TAG_NAME) {1677 if (!pull_utf8_talloc(frame,1678 &name,1679 attr->values[0].string.text,1680 &size)) {1681 goto out;1682 }1683 }1684 1685 /* Grab the comment if we don't have one */1686 if ( (strcmp(attr->name, "printer-info") == 0)1687 && (attr->value_tag == IPP_TAG_TEXT)1688 && !strlen(printer->comment) )1689 {1690 char *comment = NULL;1691 if (!pull_utf8_talloc(frame,1692 &comment,1693 attr->values[0].string.text,1694 &size)) {1695 goto out;1696 }1697 DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",1698 comment));1699 strlcpy(printer->comment,1700 comment,1701 sizeof(printer->comment));1702 }1703 1704 /* Grab the location if we don't have one */1705 if ( (strcmp(attr->name, "printer-location") == 0)1706 && (attr->value_tag == IPP_TAG_TEXT)1707 && !strlen(printer->location) )1708 {1709 char *location = NULL;1710 if (!pull_utf8_talloc(frame,1711 &location,1712 attr->values[0].string.text,1713 &size)) {1714 goto out;1715 }1716 DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",1717 location));1718 strlcpy(printer->location,1719 location,1720 sizeof(printer->location));1721 }1722 1723 attr = attr->next;1724 }1725 1726 /*1727 * We have everything needed...1728 */1729 1730 if (name != NULL)1731 break;1732 }1733 1734 ret = True;1735 1736 out:1737 if (response)1738 ippDelete(response);1739 1740 if (language)1741 cupsLangFree(language);1742 1743 if (http)1744 httpClose(http);1745 1746 TALLOC_FREE(frame);1747 return ret;1748 }1749 1750 1590 #else 1751 1591 /* this keeps fussy compilers happy */ -
vendor/current/source3/printing/print_generic.c
r414 r740 118 118 /* need to pause the spooled entry */ 119 119 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); 120 return print_run_command(snum, PRINTERNAME(snum), True,120 return print_run_command(snum, lp_printername(snum), True, 121 121 lp_lppausecommand(snum), NULL, 122 122 "%j", jobstr, … … 133 133 /* need to pause the spooled entry */ 134 134 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); 135 return print_run_command(snum, PRINTERNAME(snum), True,135 return print_run_command(snum, lp_printername(snum), True, 136 136 lp_lpresumecommand(snum), NULL, 137 137 "%j", jobstr, … … 195 195 196 196 /* send it to the system spooler */ 197 ret = print_run_command(snum, PRINTERNAME(snum), True,197 ret = print_run_command(snum, lp_printername(snum), True, 198 198 lp_printcommand(snum), NULL, 199 199 "%s", p, … … 275 275 static int generic_queue_pause(int snum) 276 276 { 277 return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL); 277 return print_run_command(snum, lp_printername(snum), True, 278 lp_queuepausecommand(snum), NULL, NULL); 278 279 } 279 280 … … 283 284 static int generic_queue_resume(int snum) 284 285 { 285 return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL); 286 return print_run_command(snum, lp_printername(snum), True, 287 lp_queueresumecommand(snum), NULL, NULL); 286 288 } 287 289 -
vendor/current/source3/printing/print_iprint.c
r414 r740 22 22 #include "includes.h" 23 23 #include "printing.h" 24 #include "printing/pcap.h" 24 25 25 26 #ifdef HAVE_IPRINT … … 297 298 298 299 if (name != NULL && !secure && smb_enabled) 299 pcap_cache_add(name, info );300 pcap_cache_add(name, info, NULL); 300 301 } 301 302 … … 575 576 "attributes-natural-language", NULL, language->language); 576 577 577 slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum)); 578 slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), 579 lp_printername(snum)); 578 580 579 581 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); … … 588 590 */ 589 591 590 slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum)); 592 slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", 593 lp_printername(snum)); 591 594 592 595 if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { … … 673 676 "attributes-natural-language", NULL, language->language); 674 677 675 slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum)); 678 slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), 679 lp_printername(snum)); 676 680 677 681 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); … … 686 690 */ 687 691 688 slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum)); 692 slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", 693 lp_printername(snum)); 689 694 690 695 if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { … … 727 732 cups_lang_t *language = NULL; /* Default language */ 728 733 char uri[HTTP_MAX_URI]; /* printer-uri attribute */ 729 const char *clientname = NULL; /* hostname of client for job-originating-host attribute */730 char addr[INET6_ADDRSTRLEN];731 734 732 735 DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); … … 772 775 "attributes-natural-language", NULL, language->language); 773 776 774 slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum)); 777 slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), 778 lp_printername(snum)); 775 779 776 780 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, … … 780 784 NULL, pjob->user); 781 785 782 clientname = client_name(get_client_fd());783 if (strcmp(clientname, "UNKNOWN") == 0) {784 clientname = client_addr(get_client_fd(),addr,sizeof(addr));785 }786 787 786 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, 788 787 "job-originating-host-name", NULL, 789 clientname);788 pjob->clientmachine); 790 789 791 790 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, … … 796 795 */ 797 796 798 slprintf(uri, sizeof(uri) - 1, "/ipp/%s", PRINTERNAME(snum));797 slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(snum)); 799 798 800 799 if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { 801 800 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 802 DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum), 801 DEBUG(0,("Unable to print file to %s - %s\n", 802 lp_printername(snum), 803 803 ippErrorString(cupsLastError()))); 804 804 } else { … … 806 806 } 807 807 } else { 808 DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum), 808 DEBUG(0,("Unable to print file to `%s' - %s\n", 809 lp_printername(snum), 809 810 ippErrorString(cupsLastError()))); 810 811 } -
vendor/current/source3/printing/print_svid.c
r414 r740 33 33 34 34 #include "includes.h" 35 #include "printing/pcap.h" 35 36 36 37 #if defined(SYSV) || defined(HPUX) … … 111 112 112 113 /* add it to the cache */ 113 if (!pcap_cache_add(name, NULL )) {114 if (!pcap_cache_add(name, NULL, NULL)) { 114 115 TALLOC_FREE(lines); 115 116 return False; -
vendor/current/source3/printing/printing.c
r478 r740 21 21 22 22 #include "includes.h" 23 #include "system/syslog.h" 24 #include "system/filesys.h" 23 25 #include "printing.h" 26 #include "../librpc/gen_ndr/ndr_spoolss.h" 27 #include "nt_printing.h" 28 #include "../librpc/gen_ndr/netlogon.h" 29 #include "printing/notify.h" 30 #include "printing/pcap.h" 31 #include "serverid.h" 32 #include "smbd/smbd.h" 33 #include "auth.h" 34 #include "messages.h" 35 #include "util_tdb.h" 24 36 25 37 extern struct current_user current_user; … … 27 39 28 40 /* Current printer interface */ 29 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid);41 static bool remove_from_jobs_added(const char* sharename, uint32 jobid); 30 42 31 43 /* … … 134 146 } 135 147 136 staticvoid rap_jobid_delete(const char* sharename, uint32 jobid)148 void rap_jobid_delete(const char* sharename, uint32 jobid) 137 149 { 138 150 TDB_DATA key, data; … … 275 287 } 276 288 289 /**************************************************************************** 290 Pack the devicemode to store it in a tdb. 291 ****************************************************************************/ 292 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen) 293 { 294 enum ndr_err_code ndr_err; 295 DATA_BLOB blob; 296 int len = 0; 297 298 if (devmode) { 299 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), 300 devmode, 301 (ndr_push_flags_fn_t) 302 ndr_push_spoolss_DeviceMode); 303 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 304 DEBUG(10, ("pack_devicemode: " 305 "error encoding spoolss_DeviceMode\n")); 306 goto done; 307 } 308 } else { 309 ZERO_STRUCT(blob); 310 } 311 312 len = tdb_pack(buf, buflen, "B", blob.length, blob.data); 313 314 if (devmode) { 315 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname)); 316 } 317 318 done: 319 return len; 320 } 321 322 /**************************************************************************** 323 Unpack the devicemode to store it in a tdb. 324 ****************************************************************************/ 325 static int unpack_devicemode(TALLOC_CTX *mem_ctx, 326 const uint8 *buf, int buflen, 327 struct spoolss_DeviceMode **devmode) 328 { 329 struct spoolss_DeviceMode *dm; 330 enum ndr_err_code ndr_err; 331 char *data = NULL; 332 int data_len = 0; 333 DATA_BLOB blob; 334 int len = 0; 335 336 *devmode = NULL; 337 338 len = tdb_unpack(buf, buflen, "B", &data_len, &data); 339 if (!data) { 340 return len; 341 } 342 343 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); 344 if (!dm) { 345 goto done; 346 } 347 348 blob = data_blob_const(data, data_len); 349 350 ndr_err = ndr_pull_struct_blob(&blob, dm, dm, 351 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); 352 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 353 DEBUG(10, ("unpack_devicemode: " 354 "error parsing spoolss_DeviceMode\n")); 355 goto done; 356 } 357 358 DEBUG(8, ("Unpacked devicemode [%s](%s)\n", 359 dm->devicename, dm->formname)); 360 if (dm->driverextra_data.data) { 361 DEBUG(8, ("with a private section of %d bytes\n", 362 dm->__driverextra_length)); 363 } 364 365 *devmode = dm; 366 367 done: 368 SAFE_FREE(data); 369 return len; 370 } 371 277 372 /*********************************************************************** 278 373 unpack a pjob from a tdb buffer 279 374 ***********************************************************************/ 280 375 281 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )376 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) 282 377 { 283 378 int len = 0; … … 289 384 return -1; 290 385 291 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff ",386 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff", 292 387 &pjpid, 293 388 &pjsysjob, … … 302 397 pjob->jobname, 303 398 pjob->user, 399 pjob->clientmachine, 304 400 pjob->queuename); 305 401 … … 307 403 return -1; 308 404 309 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) 405 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode); 406 if (used == -1) { 310 407 return -1; 408 } 311 409 312 410 len += used; … … 352 450 } 353 451 354 if ( pjob.nt_devmode ) { 355 free_nt_devicemode( &pjob.nt_devmode ); 356 } 452 talloc_free(pjob.devmode); 357 453 358 454 ZERO_STRUCT( pjob ); … … 438 534 439 535 static const struct { 440 uint32 lpq_status;441 uint32 spoolss_status;536 uint32_t lpq_status; 537 uint32_t spoolss_status; 442 538 } lpq_to_spoolss_status_map[] = { 443 539 { LPQ_QUEUED, JOB_STATUS_QUEUED }, … … 452 548 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ }, 453 549 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, 454 { -1, 0 }550 { (uint32_t)-1, 0 } 455 551 }; 456 552 … … 471 567 } 472 568 473 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, 474 struct printjob *new_data) 475 { 476 bool new_job = False; 477 478 if (!old_data) 479 new_job = True; 480 481 /* Job attributes that can't be changed. We only send 482 notification for these on a new job. */ 569 /*************************************************************************** 570 Append a jobid to the 'jobs changed' list. 571 ***************************************************************************/ 572 573 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid) 574 { 575 TDB_DATA data; 576 uint32_t store_jobid; 577 578 SIVAL(&store_jobid, 0, jobid); 579 data.dptr = (uint8 *) &store_jobid; 580 data.dsize = 4; 581 582 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 583 584 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), 585 data) == 0); 586 } 587 588 /*************************************************************************** 589 Remove a jobid from the 'jobs changed' list. 590 ***************************************************************************/ 591 592 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid) 593 { 594 struct tdb_print_db *pdb = get_print_db_byname(sharename); 595 TDB_DATA data, key; 596 size_t job_count, i; 597 bool ret = False; 598 bool gotlock = False; 599 600 if (!pdb) { 601 return False; 602 } 603 604 ZERO_STRUCT(data); 605 606 key = string_tdb_data("INFO/jobs_changed"); 607 608 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) 609 goto out; 610 611 gotlock = True; 612 613 data = tdb_fetch(pdb->tdb, key); 614 615 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) 616 goto out; 617 618 job_count = data.dsize / 4; 619 for (i = 0; i < job_count; i++) { 620 uint32 ch_jobid; 621 622 ch_jobid = IVAL(data.dptr, i*4); 623 if (ch_jobid == jobid) { 624 if (i < job_count -1 ) 625 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); 626 data.dsize -= 4; 627 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) 628 goto out; 629 break; 630 } 631 } 632 633 ret = True; 634 out: 635 636 if (gotlock) 637 tdb_chainunlock(pdb->tdb, key); 638 SAFE_FREE(data.dptr); 639 release_print_db(pdb); 640 if (ret) 641 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); 642 else 643 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); 644 return ret; 645 } 646 647 static void pjob_store_notify(struct tevent_context *ev, 648 struct messaging_context *msg_ctx, 649 const char* sharename, uint32 jobid, 650 struct printjob *old_data, 651 struct printjob *new_data, 652 bool *pchanged) 653 { 654 bool new_job = false; 655 bool changed = false; 656 657 if (old_data == NULL) { 658 new_job = true; 659 } 483 660 484 661 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the … … 490 667 491 668 if (new_job) { 492 notify_job_submitted(sharename, jobid, new_data->starttime); 493 notify_job_username(sharename, jobid, new_data->user); 494 } 495 496 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 497 notify_job_name(sharename, jobid, new_data->jobname); 498 499 /* Job attributes of a new job or attributes that can be 500 modified. */ 501 502 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 503 notify_job_name(sharename, jobid, new_data->jobname); 504 505 if (new_job || old_data->status != new_data->status) 506 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status)); 507 508 if (new_job || old_data->size != new_data->size) 509 notify_job_total_bytes(sharename, jobid, new_data->size); 510 511 if (new_job || old_data->page_count != new_data->page_count) 512 notify_job_total_pages(sharename, jobid, new_data->page_count); 669 notify_job_submitted(ev, msg_ctx, 670 sharename, jobid, new_data->starttime); 671 notify_job_username(ev, msg_ctx, 672 sharename, jobid, new_data->user); 673 notify_job_name(ev, msg_ctx, 674 sharename, jobid, new_data->jobname); 675 notify_job_status(ev, msg_ctx, 676 sharename, jobid, map_to_spoolss_status(new_data->status)); 677 notify_job_total_bytes(ev, msg_ctx, 678 sharename, jobid, new_data->size); 679 notify_job_total_pages(ev, msg_ctx, 680 sharename, jobid, new_data->page_count); 681 } else { 682 if (!strequal(old_data->jobname, new_data->jobname)) { 683 notify_job_name(ev, msg_ctx, sharename, 684 jobid, new_data->jobname); 685 changed = true; 686 } 687 688 if (old_data->status != new_data->status) { 689 notify_job_status(ev, msg_ctx, 690 sharename, jobid, 691 map_to_spoolss_status(new_data->status)); 692 } 693 694 if (old_data->size != new_data->size) { 695 notify_job_total_bytes(ev, msg_ctx, 696 sharename, jobid, new_data->size); 697 } 698 699 if (old_data->page_count != new_data->page_count) { 700 notify_job_total_pages(ev, msg_ctx, 701 sharename, jobid, 702 new_data->page_count); 703 } 704 } 705 706 *pchanged = changed; 513 707 } 514 708 … … 517 711 ****************************************************************************/ 518 712 519 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) 713 static bool pjob_store(struct tevent_context *ev, 714 struct messaging_context *msg_ctx, 715 const char* sharename, uint32 jobid, 716 struct printjob *pjob) 520 717 { 521 718 uint32_t tmp; … … 541 738 len = 0; 542 739 buflen = newlen; 543 len += tdb_pack(buf+len, buflen-len, "dddddddddffff ",740 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff", 544 741 (uint32)pjob->pid, 545 742 (uint32)pjob->sysjob, … … 554 751 pjob->jobname, 555 752 pjob->user, 753 pjob->clientmachine, 556 754 pjob->queuename); 557 755 558 len += pack_devicemode(pjob-> nt_devmode, buf+len, buflen-len);756 len += pack_devicemode(pjob->devmode, buf+len, buflen-len); 559 757 560 758 if (buflen != len) { … … 576 774 TDB_REPLACE) == 0); 577 775 578 release_print_db(pdb);579 580 776 /* Send notify updates for what has changed */ 581 777 582 778 if ( ret ) { 779 bool changed = false; 583 780 struct printjob old_pjob; 584 781 … … 587 784 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) 588 785 { 589 pjob_store_notify( sharename, jobid, &old_pjob , pjob ); 590 free_nt_devicemode( &old_pjob.nt_devmode ); 786 pjob_store_notify(server_event_context(), 787 msg_ctx, 788 sharename, jobid, &old_pjob, 789 pjob, 790 &changed); 791 talloc_free(old_pjob.devmode); 792 793 if (changed) { 794 add_to_jobs_changed(pdb, jobid); 795 } 591 796 } 797 592 798 } 593 799 else { 594 800 /* new job */ 595 pjob_store_notify( sharename, jobid, NULL, pjob ); 596 } 597 } 598 801 pjob_store_notify(server_event_context(), msg_ctx, 802 sharename, jobid, NULL, pjob, 803 &changed); 804 } 805 } 806 807 release_print_db(pdb); 599 808 done: 600 809 SAFE_FREE( old_data.dptr ); … … 608 817 ****************************************************************************/ 609 818 610 void pjob_delete(const char* sharename, uint32 jobid) 819 static void pjob_delete(struct tevent_context *ev, 820 struct messaging_context *msg_ctx, 821 const char* sharename, uint32 jobid) 611 822 { 612 823 uint32_t tmp; … … 634 845 635 846 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; 636 notify_job_status( sharename, jobid, job_status);847 notify_job_status(ev, msg_ctx, sharename, jobid, job_status); 637 848 638 849 /* Remove from printing.tdb */ 639 850 640 851 tdb_delete(pdb->tdb, print_key(jobid, &tmp)); 641 remove_from_jobs_ changed(sharename, jobid);852 remove_from_jobs_added(sharename, jobid); 642 853 release_print_db( pdb ); 643 854 rap_jobid_delete(sharename, jobid); … … 648 859 ****************************************************************************/ 649 860 650 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid) 861 static void print_unix_job(struct tevent_context *ev, 862 struct messaging_context *msg_ctx, 863 const char *sharename, print_queue_struct *q, 864 uint32 jobid) 651 865 { 652 866 struct printjob pj, *old_pj; … … 679 893 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename ); 680 894 681 pjob_store( sharename, jobid, &pj);895 pjob_store(ev, msg_ctx, sharename, jobid, &pj); 682 896 } 683 897 … … 690 904 const char *lprm_command; 691 905 struct printif *print_if; 906 struct tevent_context *ev; 907 struct messaging_context *msg_ctx; 692 908 }; 693 909 … … 709 925 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) 710 926 return 0; 711 free_nt_devicemode( &pjob.nt_devmode);927 talloc_free(pjob.devmode); 712 928 713 929 … … 723 939 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", 724 940 (unsigned int)jobid )); 725 pjob_delete(ts->sharename, jobid); 941 pjob_delete(ts->ev, ts->msg_ctx, 942 ts->sharename, jobid); 726 943 return 0; 727 944 } … … 739 956 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", 740 957 (unsigned int)jobid, (unsigned int)pjob.pid )); 741 pjob_delete(ts->sharename, jobid); 958 pjob_delete(ts->ev, ts->msg_ctx, 959 ts->sharename, jobid); 742 960 } else 743 961 ts->total_jobs++; … … 769 987 /* if we can't delete, then reset the job status */ 770 988 pjob.status = LPQ_QUEUED; 771 pjob_store(ts->sharename, jobid, &pjob); 989 pjob_store(ts->ev, ts->msg_ctx, 990 ts->sharename, jobid, &pjob); 772 991 } 773 992 else { 774 993 /* if we deleted the job, the remove the tdb record */ 775 pjob_delete(ts->sharename, jobid); 994 pjob_delete(ts->ev, 995 ts->msg_ctx, 996 ts->sharename, jobid); 776 997 pjob.status = LPQ_DELETED; 777 998 } … … 801 1022 (unsigned int)pjob.starttime, 802 1023 (unsigned int)ts->lpq_time )); 803 pjob_delete(ts->sharename, jobid); 1024 pjob_delete(ts->ev, ts->msg_ctx, 1025 ts->sharename, jobid); 804 1026 } else 805 1027 ts->total_jobs++; … … 998 1220 } 999 1221 1000 static TDB_DATA get_jobs_ changed_data(struct tdb_print_db *pdb)1222 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb) 1001 1223 { 1002 1224 TDB_DATA data; … … 1004 1226 ZERO_STRUCT(data); 1005 1227 1006 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));1228 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 1007 1229 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { 1008 1230 SAFE_FREE(data.dptr); … … 1013 1235 } 1014 1236 1015 static void check_job_ changed(const char *sharename, TDB_DATA data, uint32 jobid)1237 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid) 1016 1238 { 1017 1239 unsigned int i; … … 1023 1245 ch_jobid = IVAL(data.dptr, i*4); 1024 1246 if (ch_jobid == jobid) 1025 remove_from_jobs_ changed(sharename, jobid);1247 remove_from_jobs_added(sharename, jobid); 1026 1248 } 1027 1249 } … … 1093 1315 1094 1316 /**************************************************************************** 1095 main work for updating the lpq cahe for a printer queue 1096 ****************************************************************************/ 1097 1098 static void print_queue_update_internal( const char *sharename, 1317 main work for updating the lpq cache for a printer queue 1318 ****************************************************************************/ 1319 1320 static void print_queue_update_internal( struct tevent_context *ev, 1321 struct messaging_context *msg_ctx, 1322 const char *sharename, 1099 1323 struct printif *current_printif, 1100 1324 char *lpq_command, char *lprm_command ) … … 1140 1364 in hash order. */ 1141 1365 1142 qsort(queue, qcount, sizeof(print_queue_struct), 1143 QSORT_CAST(printjob_comp)); 1366 TYPESAFE_QSORT(queue, qcount, printjob_comp); 1144 1367 1145 1368 /* … … 1154 1377 */ 1155 1378 1156 jcdata = get_jobs_ changed_data(pdb);1379 jcdata = get_jobs_added_data(pdb); 1157 1380 1158 1381 for (i=0; i<qcount; i++) { … … 1161 1384 if (jobid == (uint32)-1) { 1162 1385 /* assume its a unix print job */ 1163 print_unix_job(sharename, &queue[i], jobid); 1386 print_unix_job(ev, msg_ctx, 1387 sharename, &queue[i], jobid); 1164 1388 continue; 1165 1389 } … … 1171 1395 with jobs in the queue. All we can do is treat them 1172 1396 like unix jobs. Pity. */ 1173 print_unix_job(sharename, &queue[i], jobid); 1397 print_unix_job(ev, msg_ctx, 1398 sharename, &queue[i], jobid); 1174 1399 continue; 1175 1400 } … … 1182 1407 pjob->status = queue[i].status; 1183 1408 1184 pjob_store( sharename, jobid, pjob);1185 1186 check_job_ changed(sharename, jcdata, jobid);1409 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1410 1411 check_job_added(sharename, jcdata, jobid); 1187 1412 } 1188 1413 … … 1199 1424 tstruct.lprm_command = lprm_command; 1200 1425 tstruct.print_if = current_printif; 1426 tstruct.ev = ev; 1427 tstruct.msg_ctx = msg_ctx; 1201 1428 1202 1429 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); … … 1256 1483 ****************************************************************************/ 1257 1484 1258 static void print_queue_update_with_lock( const char *sharename, 1485 static void print_queue_update_with_lock( struct tevent_context *ev, 1486 struct messaging_context *msg_ctx, 1487 const char *sharename, 1259 1488 struct printif *current_printif, 1260 1489 char *lpq_command, char *lprm_command ) … … 1325 1554 /* do the main work now */ 1326 1555 1327 print_queue_update_internal( sharename, current_printif, 1328 lpq_command, lprm_command ); 1556 print_queue_update_internal(ev, msg_ctx, 1557 sharename, current_printif, 1558 lpq_command, lprm_command); 1329 1559 1330 1560 /* Delete our pid from the db. */ … … 1336 1566 this is the receive function of the background lpq updater 1337 1567 ****************************************************************************/ 1338 staticvoid print_queue_receive(struct messaging_context *msg,1568 void print_queue_receive(struct messaging_context *msg, 1339 1569 void *private_data, 1340 1570 uint32_t msg_type, … … 1360 1590 } 1361 1591 1362 print_queue_update_with_lock(s harename,1592 print_queue_update_with_lock(server_event_context(), msg, sharename, 1363 1593 get_printer_fns_from_type((enum printing_types)printing_type), 1364 1594 lpqcommand, lprmcommand ); … … 1381 1611 } 1382 1612 1613 extern struct child_pid *children; 1614 extern int num_children; 1615 1383 1616 static void add_child_pid(pid_t pid) 1384 1617 { 1385 extern struct child_pid *children;1386 1618 struct child_pid *child; 1387 extern int num_children;1388 1619 1389 1620 child = SMB_MALLOC_P(struct child_pid); … … 1402 1633 main thread of the background lpq updater 1403 1634 ****************************************************************************/ 1404 void start_background_queue(void) 1635 void start_background_queue(struct tevent_context *ev, 1636 struct messaging_context *msg_ctx) 1405 1637 { 1406 1638 /* Use local variables for this as we don't … … 1430 1662 struct tevent_fd *fde; 1431 1663 int ret; 1664 NTSTATUS status; 1432 1665 1433 1666 /* Child. */ … … 1437 1670 pause_pipe[0] = -1; 1438 1671 1439 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),1440 smbd_event_context(), 1441 true))) {1672 status = reinit_after_fork(msg_ctx, ev, procid_self(), true); 1673 1674 if (!NT_STATUS_IS_OK(status)) { 1442 1675 DEBUG(0,("reinit_after_fork() failed\n")); 1443 1676 smb_panic("reinit_after_fork() failed"); … … 1445 1678 1446 1679 smbd_setup_sig_term_handler(); 1447 smbd_setup_sig_hup_handler(); 1448 1449 claim_connection( NULL, "smbd lpq backend", 1450 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 1680 smbd_setup_sig_hup_handler(ev, msg_ctx); 1681 1682 if (!serverid_register(procid_self(), 1683 FLAG_MSG_GENERAL|FLAG_MSG_SMBD 1684 |FLAG_MSG_PRINT_GENERAL)) { 1685 exit(1); 1686 } 1451 1687 1452 1688 if (!locking_init()) { … … 1454 1690 } 1455 1691 1456 messaging_register(smbd_messaging_context(), NULL, 1457 MSG_PRINTER_UPDATE, print_queue_receive); 1458 1459 fde = tevent_add_fd(smbd_event_context(), smbd_event_context(), 1460 pause_pipe[1], TEVENT_FD_READ, 1692 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, 1693 print_queue_receive); 1694 1695 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ, 1461 1696 printing_pause_fd_handler, 1462 1697 NULL); … … 1467 1702 1468 1703 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); 1469 ret = tevent_loop_wait( smbd_event_context());1704 ret = tevent_loop_wait(ev); 1470 1705 /* should not be reached */ 1471 1706 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", … … 1481 1716 ****************************************************************************/ 1482 1717 1483 static void print_queue_update(int snum, bool force) 1718 static void print_queue_update(struct messaging_context *msg_ctx, 1719 int snum, bool force) 1484 1720 { 1485 1721 fstring key; … … 1502 1738 lp_lpqcommand(snum), 1503 1739 "%p", 1504 PRINTERNAME(snum),1740 lp_printername(snum), 1505 1741 false, false, false); 1506 1742 if (!lpqcommand) { … … 1522 1758 lp_lprmcommand(snum), 1523 1759 "%p", 1524 PRINTERNAME(snum),1760 lp_printername(snum), 1525 1761 false, false, false); 1526 1762 if (!lprmcommand) { … … 1547 1783 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); 1548 1784 current_printif = get_printer_fns( snum ); 1549 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand ); 1785 print_queue_update_with_lock(server_event_context(), msg_ctx, 1786 sharename, current_printif, 1787 lpqcommand, lprmcommand); 1550 1788 1551 1789 return; … … 1600 1838 /* finally send the message */ 1601 1839 1602 messaging_send_buf(smbd_messaging_context(), 1603 pid_to_procid(background_lpq_updater_pid), 1840 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid), 1604 1841 MSG_PRINTER_UPDATE, (uint8 *)buffer, len); 1605 1842 … … 1808 2045 1809 2046 /**************************************************************************** 1810 Give the fd used for a jobid.1811 ****************************************************************************/1812 1813 int print_job_fd(const char* sharename, uint32 jobid)1814 {1815 struct printjob *pjob = print_job_find(sharename, jobid);1816 if (!pjob)1817 return -1;1818 /* don't allow another process to get this info - it is meaningless */1819 if (pjob->pid != sys_getpid())1820 return -1;1821 return pjob->fd;1822 }1823 1824 /****************************************************************************1825 2047 Give the filename used for a jobid. 1826 2048 Only valid for the process doing the spooling and when the job … … 1843 2065 ****************************************************************************/ 1844 2066 1845 NT_DEVICEMODE*print_job_devmode(const char* sharename, uint32 jobid)2067 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid) 1846 2068 { 1847 2069 struct printjob *pjob = print_job_find(sharename, jobid); … … 1850 2072 return NULL; 1851 2073 1852 return pjob->nt_devmode; 1853 } 1854 1855 /**************************************************************************** 1856 Set the place in the queue for a job. 1857 ****************************************************************************/ 1858 1859 bool print_job_set_place(const char *sharename, uint32 jobid, int place) 1860 { 1861 DEBUG(2,("print_job_set_place not implemented yet\n")); 1862 return False; 2074 return pjob->devmode; 1863 2075 } 1864 2076 … … 1867 2079 ****************************************************************************/ 1868 2080 1869 bool print_job_set_name(const char *sharename, uint32 jobid, char *name) 2081 bool print_job_set_name(struct tevent_context *ev, 2082 struct messaging_context *msg_ctx, 2083 const char *sharename, uint32 jobid, const char *name) 1870 2084 { 1871 2085 struct printjob *pjob; … … 1876 2090 1877 2091 fstrcpy(pjob->jobname, name); 1878 return pjob_store(sharename, jobid, pjob); 1879 } 2092 return pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2093 } 2094 2095 /**************************************************************************** 2096 Get the name of a job. Only possible for owner. 2097 ****************************************************************************/ 2098 2099 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name) 2100 { 2101 struct printjob *pjob; 2102 2103 pjob = print_job_find(sharename, jobid); 2104 if (!pjob || pjob->pid != sys_getpid()) { 2105 return false; 2106 } 2107 2108 *name = talloc_strdup(mem_ctx, pjob->jobname); 2109 if (!*name) { 2110 return false; 2111 } 2112 2113 return true; 2114 } 2115 1880 2116 1881 2117 /*************************************************************************** 1882 Remove a jobid from the 'jobs changed' list.2118 Remove a jobid from the 'jobs added' list. 1883 2119 ***************************************************************************/ 1884 2120 1885 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid)2121 static bool remove_from_jobs_added(const char* sharename, uint32 jobid) 1886 2122 { 1887 2123 struct tdb_print_db *pdb = get_print_db_byname(sharename); … … 1897 2133 ZERO_STRUCT(data); 1898 2134 1899 key = string_tdb_data("INFO/jobs_ changed");2135 key = string_tdb_data("INFO/jobs_added"); 1900 2136 1901 2137 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) … … 1932 2168 release_print_db(pdb); 1933 2169 if (ret) 1934 DEBUG(10,("remove_from_jobs_ changed: removed jobid %u\n", (unsigned int)jobid ));2170 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid )); 1935 2171 else 1936 DEBUG(10,("remove_from_jobs_ changed: Failed to remove jobid %u\n", (unsigned int)jobid ));2172 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid )); 1937 2173 return ret; 1938 2174 } … … 1942 2178 ****************************************************************************/ 1943 2179 1944 static bool print_job_delete1(int snum, uint32 jobid) 2180 static bool print_job_delete1(struct tevent_context *ev, 2181 struct messaging_context *msg_ctx, 2182 int snum, uint32 jobid) 1945 2183 { 1946 2184 const char* sharename = lp_const_servicename(snum); … … 1971 2209 1972 2210 pjob->status = LPQ_DELETING; 1973 pjob_store( sharename, jobid, pjob);2211 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1974 2212 1975 2213 if (pjob->spooled && pjob->sysjob != -1) 1976 2214 { 1977 2215 result = (*(current_printif->job_delete))( 1978 PRINTERNAME(snum),2216 lp_printername(snum), 1979 2217 lp_lprmcommand(snum), 1980 2218 pjob); … … 1989 2227 if (!pdb) 1990 2228 return False; 1991 pjob_delete( sharename, jobid);2229 pjob_delete(ev, msg_ctx, sharename, jobid); 1992 2230 /* Ensure we keep a rough count of the number of total jobs... */ 1993 2231 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); … … 1996 2234 } 1997 2235 1998 remove_from_jobs_ changed( sharename, jobid );2236 remove_from_jobs_added( sharename, jobid ); 1999 2237 2000 2238 return (result == 0); … … 2005 2243 ****************************************************************************/ 2006 2244 2007 static bool is_owner( struct auth_serversupplied_info *server_info,2245 static bool is_owner(const struct auth_serversupplied_info *server_info, 2008 2246 const char *servicename, 2009 2247 uint32 jobid) … … 2021 2259 ****************************************************************************/ 2022 2260 2023 bool print_job_delete(struct auth_serversupplied_info *server_info, int snum, 2024 uint32 jobid, WERROR *errcode) 2025 { 2026 const char* sharename = lp_const_servicename( snum ); 2261 WERROR print_job_delete(const struct auth_serversupplied_info *server_info, 2262 struct messaging_context *msg_ctx, 2263 int snum, uint32_t jobid) 2264 { 2265 const char* sharename = lp_const_servicename(snum); 2027 2266 struct printjob *pjob; 2028 2267 bool owner; 2029 2268 char *fname; 2030 2269 2031 *errcode = WERR_OK;2032 2033 2270 owner = is_owner(server_info, lp_const_servicename(snum), jobid); 2034 2271 … … 2037 2274 2038 2275 if (!owner && 2039 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2276 !print_access_check(server_info, msg_ctx, snum, 2277 JOB_ACCESS_ADMINISTER)) { 2040 2278 DEBUG(3, ("delete denied by security descriptor\n")); 2041 *errcode = WERR_ACCESS_DENIED;2042 2279 2043 2280 /* BEGIN_ADMIN_LOG */ … … 2046 2283 pause, or resume print job. User name: %s. Printer name: %s.", 2047 2284 uidtoname(server_info->utok.uid), 2048 PRINTERNAME(snum) );2285 lp_printername(snum) ); 2049 2286 /* END_ADMIN_LOG */ 2050 2287 2051 return False;2288 return WERR_ACCESS_DENIED; 2052 2289 } 2053 2290 … … 2059 2296 */ 2060 2297 2061 if ( (fname = print_job_fname( sharename, jobid )) != NULL )2062 {2298 fname = print_job_fname(sharename, jobid); 2299 if (fname != NULL) { 2063 2300 /* remove the spool file */ 2064 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); 2065 if ( unlink( fname ) == -1 ) { 2066 *errcode = map_werror_from_unix(errno); 2067 return False; 2068 } 2069 } 2070 2071 if (!print_job_delete1(snum, jobid)) { 2072 *errcode = WERR_ACCESS_DENIED; 2073 return False; 2301 DEBUG(10, ("print_job_delete: " 2302 "Removing spool file [%s]\n", fname)); 2303 if (unlink(fname) == -1) { 2304 return map_werror_from_unix(errno); 2305 } 2306 } 2307 2308 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) { 2309 return WERR_ACCESS_DENIED; 2074 2310 } 2075 2311 … … 2077 2313 job still exists */ 2078 2314 2079 print_queue_update( snum, True);2315 print_queue_update(msg_ctx, snum, True); 2080 2316 2081 2317 pjob = print_job_find(sharename, jobid); 2082 if ( pjob && (pjob->status != LPQ_DELETING) ) 2083 *errcode = WERR_ACCESS_DENIED; 2084 2085 return (pjob == NULL ); 2318 if (pjob && (pjob->status != LPQ_DELETING)) { 2319 return WERR_ACCESS_DENIED; 2320 } 2321 2322 return WERR_PRINTER_HAS_JOBS_QUEUED; 2086 2323 } 2087 2324 … … 2090 2327 ****************************************************************************/ 2091 2328 2092 bool print_job_pause(struct auth_serversupplied_info *server_info, int snum, 2093 uint32 jobid, WERROR *errcode) 2329 bool print_job_pause(const struct auth_serversupplied_info *server_info, 2330 struct messaging_context *msg_ctx, 2331 int snum, uint32 jobid, WERROR *errcode) 2094 2332 { 2095 2333 const char* sharename = lp_const_servicename(snum); … … 2113 2351 2114 2352 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2115 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2353 !print_access_check(server_info, msg_ctx, snum, 2354 JOB_ACCESS_ADMINISTER)) { 2116 2355 DEBUG(3, ("pause denied by security descriptor\n")); 2117 2356 … … 2121 2360 pause, or resume print job. User name: %s. Printer name: %s.", 2122 2361 uidtoname(server_info->utok.uid), 2123 PRINTERNAME(snum) );2362 lp_printername(snum) ); 2124 2363 /* END_ADMIN_LOG */ 2125 2364 … … 2141 2380 /* Send a printer notify message */ 2142 2381 2143 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED); 2382 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2383 JOB_STATUS_PAUSED); 2144 2384 2145 2385 /* how do we tell if this succeeded? */ … … 2152 2392 ****************************************************************************/ 2153 2393 2154 bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, 2155 uint32 jobid, WERROR *errcode) 2394 bool print_job_resume(const struct auth_serversupplied_info *server_info, 2395 struct messaging_context *msg_ctx, 2396 int snum, uint32 jobid, WERROR *errcode) 2156 2397 { 2157 2398 const char *sharename = lp_const_servicename(snum); … … 2175 2416 2176 2417 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2177 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2418 !print_access_check(server_info, msg_ctx, snum, 2419 JOB_ACCESS_ADMINISTER)) { 2178 2420 DEBUG(3, ("resume denied by security descriptor\n")); 2179 2421 *errcode = WERR_ACCESS_DENIED; … … 2184 2426 pause, or resume print job. User name: %s. Printer name: %s.", 2185 2427 uidtoname(server_info->utok.uid), 2186 PRINTERNAME(snum) );2428 lp_printername(snum) ); 2187 2429 /* END_ADMIN_LOG */ 2188 2430 return False; … … 2201 2443 /* Send a printer notify message */ 2202 2444 2203 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED); 2445 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2446 JOB_STATUS_QUEUED); 2204 2447 2205 2448 return True; … … 2210 2453 ****************************************************************************/ 2211 2454 2212 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size) 2455 ssize_t print_job_write(struct tevent_context *ev, 2456 struct messaging_context *msg_ctx, 2457 int snum, uint32 jobid, const char *buf, size_t size) 2213 2458 { 2214 2459 const char* sharename = lp_const_servicename(snum); 2215 int return_code;2460 ssize_t return_code; 2216 2461 struct printjob *pjob; 2217 2462 … … 2224 2469 return -1; 2225 2470 2226 return_code = write_data_at_offset(pjob->fd, buf, size, pos); 2471 /* if SMBD is spooling this can't be allowed */ 2472 if (pjob->status == PJOB_SMBD_SPOOLING) { 2473 return -1; 2474 } 2475 2476 return_code = write_data(pjob->fd, buf, size); 2227 2477 2228 2478 if (return_code>0) { 2229 2479 pjob->size += size; 2230 pjob_store( sharename, jobid, pjob);2480 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2231 2481 } 2232 2482 return return_code; … … 2271 2521 ****************************************************************************/ 2272 2522 2273 int print_queue_length(int snum, print_status_struct *pstatus) 2523 int print_queue_length(struct messaging_context *msg_ctx, int snum, 2524 print_status_struct *pstatus) 2274 2525 { 2275 2526 const char* sharename = lp_const_servicename( snum ); … … 2281 2532 /* make sure the database is up to date */ 2282 2533 if (print_cache_expired(lp_const_servicename(snum), True)) 2283 print_queue_update( snum, False);2534 print_queue_update(msg_ctx, snum, False); 2284 2535 2285 2536 /* also fetch the queue status */ … … 2297 2548 ***************************************************************************/ 2298 2549 2299 static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) 2550 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum, 2551 const char *sharename, uint32 *pjobid) 2300 2552 { 2301 2553 int i; 2302 2554 uint32 jobid; 2555 enum TDB_ERROR terr; 2556 int ret; 2303 2557 2304 2558 *pjobid = (uint32)-1; … … 2306 2560 for (i = 0; i < 3; i++) { 2307 2561 /* Lock the database - only wait 20 seconds. */ 2308 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) { 2309 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); 2310 return False; 2562 ret = tdb_lock_bystring_with_timeout(pdb->tdb, 2563 "INFO/nextjob", 20); 2564 if (ret == -1) { 2565 DEBUG(0, ("allocate_print_jobid: " 2566 "Failed to lock printing database %s\n", 2567 sharename)); 2568 terr = tdb_error(pdb->tdb); 2569 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2311 2570 } 2312 2571 2313 2572 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { 2314 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { 2315 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", 2316 sharename)); 2573 terr = tdb_error(pdb->tdb); 2574 if (terr != TDB_ERR_NOEXIST) { 2575 DEBUG(0, ("allocate_print_jobid: " 2576 "Failed to fetch INFO/nextjob " 2577 "for print queue %s\n", sharename)); 2317 2578 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2318 return False;2579 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2319 2580 } 2320 DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename)); 2581 DEBUG(10, ("allocate_print_jobid: " 2582 "No existing jobid in %s\n", sharename)); 2321 2583 jobid = 0; 2322 2584 } 2323 2585 2324 DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename)); 2586 DEBUG(10, ("allocate_print_jobid: " 2587 "Read jobid %u from %s\n", jobid, sharename)); 2325 2588 2326 2589 jobid = NEXT_JOBID(jobid); 2327 2590 2328 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { 2329 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n")); 2591 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid); 2592 if (ret == -1) { 2593 terr = tdb_error(pdb->tdb); 2594 DEBUG(3, ("allocate_print_jobid: " 2595 "Failed to store INFO/nextjob.\n")); 2330 2596 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2331 return False;2597 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2332 2598 } 2333 2599 … … 2338 2604 break; 2339 2605 } 2340 DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename)); 2606 DEBUG(10, ("allocate_print_jobid: " 2607 "Found jobid %u in %s\n", jobid, sharename)); 2341 2608 } 2342 2609 2343 2610 if (i > 2) { 2344 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", 2345 sharename)); 2611 DEBUG(0, ("allocate_print_jobid: " 2612 "Failed to allocate a print job for queue %s\n", 2613 sharename)); 2346 2614 /* Probably full... */ 2347 errno = ENOSPC; 2348 return False; 2615 return WERR_NO_SPOOL_SPACE; 2349 2616 } 2350 2617 … … 2357 2624 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum, 2358 2625 TDB_INSERT) == -1) { 2359 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", 2360 jobid )); 2361 return False; 2626 DEBUG(3, ("allocate_print_jobid: " 2627 "jobid (%d) failed to store placeholder.\n", 2628 jobid )); 2629 terr = tdb_error(pdb->tdb); 2630 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2362 2631 } 2363 2632 } 2364 2633 2365 2634 *pjobid = jobid; 2366 return True;2635 return WERR_OK; 2367 2636 } 2368 2637 2369 2638 /*************************************************************************** 2370 Append a jobid to the 'jobs changed' list.2639 Append a jobid to the 'jobs added' list. 2371 2640 ***************************************************************************/ 2372 2641 2373 static bool add_to_jobs_ changed(struct tdb_print_db *pdb, uint32 jobid)2642 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid) 2374 2643 { 2375 2644 TDB_DATA data; … … 2380 2649 data.dsize = 4; 2381 2650 2382 DEBUG(10,("add_to_jobs_ changed: Added jobid %u\n", (unsigned int)jobid ));2383 2384 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_ changed"),2651 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 2652 2653 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"), 2385 2654 data) == 0); 2655 } 2656 2657 2658 /*************************************************************************** 2659 Do all checks needed to determine if we can start a job. 2660 ***************************************************************************/ 2661 2662 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info, 2663 struct messaging_context *msg_ctx, 2664 int snum, int *njobs) 2665 { 2666 const char *sharename = lp_const_servicename(snum); 2667 uint64_t dspace, dsize; 2668 uint64_t minspace; 2669 int ret; 2670 2671 if (!print_access_check(server_info, msg_ctx, snum, 2672 PRINTER_ACCESS_USE)) { 2673 DEBUG(3, ("print_job_checks: " 2674 "job start denied by security descriptor\n")); 2675 return WERR_ACCESS_DENIED; 2676 } 2677 2678 if (!print_time_access_check(server_info, msg_ctx, sharename)) { 2679 DEBUG(3, ("print_job_checks: " 2680 "job start denied by time check\n")); 2681 return WERR_ACCESS_DENIED; 2682 } 2683 2684 /* see if we have sufficient disk space */ 2685 if (lp_minprintspace(snum)) { 2686 minspace = lp_minprintspace(snum); 2687 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize); 2688 if (ret == 0 && dspace < 2*minspace) { 2689 DEBUG(3, ("print_job_checks: " 2690 "disk space check failed.\n")); 2691 return WERR_NO_SPOOL_SPACE; 2692 } 2693 } 2694 2695 /* for autoloaded printers, check that the printcap entry still exists */ 2696 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) { 2697 DEBUG(3, ("print_job_checks: printer name %s check failed.\n", 2698 sharename)); 2699 return WERR_ACCESS_DENIED; 2700 } 2701 2702 /* Insure the maximum queue size is not violated */ 2703 *njobs = print_queue_length(msg_ctx, snum, NULL); 2704 if (*njobs > lp_maxprintjobs(snum)) { 2705 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) " 2706 "larger than max printjobs per queue (%d).\n", 2707 sharename, *njobs, lp_maxprintjobs(snum))); 2708 return WERR_NO_SPOOL_SPACE; 2709 } 2710 2711 return WERR_OK; 2712 } 2713 2714 /*************************************************************************** 2715 Create a job file. 2716 ***************************************************************************/ 2717 2718 static WERROR print_job_spool_file(int snum, uint32_t jobid, 2719 const char *output_file, 2720 struct printjob *pjob) 2721 { 2722 WERROR werr; 2723 SMB_STRUCT_STAT st; 2724 const char *path; 2725 int len; 2726 2727 /* if this file is within the printer path, it means that smbd 2728 * is spooling it and will pass us control when it is finished. 2729 * Verify that the file name is ok, within path, and it is 2730 * already already there */ 2731 if (output_file) { 2732 path = lp_pathname(snum); 2733 len = strlen(path); 2734 if (strncmp(output_file, path, len) == 0 && 2735 (output_file[len - 1] == '/' || output_file[len] == '/')) { 2736 2737 /* verify path is not too long */ 2738 if (strlen(output_file) >= sizeof(pjob->filename)) { 2739 return WERR_INVALID_NAME; 2740 } 2741 2742 /* verify that the file exists */ 2743 if (sys_stat(output_file, &st, false) != 0) { 2744 return WERR_INVALID_NAME; 2745 } 2746 2747 fstrcpy(pjob->filename, output_file); 2748 2749 DEBUG(3, ("print_job_spool_file:" 2750 "External spooling activated")); 2751 2752 /* we do not open the file until spooling is done */ 2753 pjob->fd = -1; 2754 pjob->status = PJOB_SMBD_SPOOLING; 2755 2756 return WERR_OK; 2757 } 2758 } 2759 2760 slprintf(pjob->filename, sizeof(pjob->filename)-1, 2761 "%s/%s%.8u.XXXXXX", lp_pathname(snum), 2762 PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2763 pjob->fd = mkstemp(pjob->filename); 2764 2765 if (pjob->fd == -1) { 2766 werr = map_werror_from_unix(errno); 2767 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) { 2768 /* Common setup error, force a report. */ 2769 DEBUG(0, ("print_job_spool_file: " 2770 "insufficient permissions to open spool " 2771 "file %s.\n", pjob->filename)); 2772 } else { 2773 /* Normal case, report at level 3 and above. */ 2774 DEBUG(3, ("print_job_spool_file: " 2775 "can't open spool file %s\n", 2776 pjob->filename)); 2777 } 2778 return werr; 2779 } 2780 2781 return WERR_OK; 2386 2782 } 2387 2783 … … 2390 2786 ***************************************************************************/ 2391 2787 2392 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, 2393 const char *jobname, NT_DEVICEMODE *nt_devmode ) 2394 { 2395 uint32 jobid; 2788 WERROR print_job_start(const struct auth_serversupplied_info *server_info, 2789 struct messaging_context *msg_ctx, 2790 const char *clientmachine, 2791 int snum, const char *docname, const char *filename, 2792 struct spoolss_DeviceMode *devmode, uint32_t *_jobid) 2793 { 2794 uint32_t jobid; 2396 2795 char *path; 2397 2796 struct printjob pjob; … … 2399 2798 struct tdb_print_db *pdb = get_print_db_byname(sharename); 2400 2799 int njobs; 2401 2402 errno = 0; 2403 2404 if (!pdb) 2405 return (uint32)-1; 2406 2407 if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) { 2408 DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); 2800 WERROR werr; 2801 2802 if (!pdb) { 2803 return WERR_INTERNAL_DB_CORRUPTION; 2804 } 2805 2806 path = lp_pathname(snum); 2807 2808 werr = print_job_checks(server_info, msg_ctx, snum, &njobs); 2809 if (!W_ERROR_IS_OK(werr)) { 2409 2810 release_print_db(pdb); 2410 return (uint32)-1; 2411 } 2412 2413 if (!print_time_access_check(lp_servicename(snum))) { 2414 DEBUG(3, ("print_job_start: job start denied by time check\n")); 2415 release_print_db(pdb); 2416 return (uint32)-1; 2417 } 2418 2419 path = lp_pathname(snum); 2420 2421 /* see if we have sufficient disk space */ 2422 if (lp_minprintspace(snum)) { 2423 uint64_t dspace, dsize; 2424 if (sys_fsusage(path, &dspace, &dsize) == 0 && 2425 dspace < 2*(uint64_t)lp_minprintspace(snum)) { 2426 DEBUG(3, ("print_job_start: disk space check failed.\n")); 2427 release_print_db(pdb); 2428 errno = ENOSPC; 2429 return (uint32)-1; 2430 } 2431 } 2432 2433 /* for autoloaded printers, check that the printcap entry still exists */ 2434 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) { 2435 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); 2436 release_print_db(pdb); 2437 errno = ENOENT; 2438 return (uint32)-1; 2439 } 2440 2441 /* Insure the maximum queue size is not violated */ 2442 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { 2443 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", 2444 sharename, njobs, lp_maxprintjobs(snum) )); 2445 release_print_db(pdb); 2446 errno = ENOSPC; 2447 return (uint32)-1; 2448 } 2449 2450 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", 2451 sharename, njobs, lp_maxprintjobs(snum) )); 2452 2453 if (!allocate_print_jobid(pdb, snum, sharename, &jobid)) 2811 return werr; 2812 } 2813 2814 DEBUG(10, ("print_job_start: " 2815 "Queue %s number of jobs (%d), max printjobs = %d\n", 2816 sharename, njobs, lp_maxprintjobs(snum))); 2817 2818 werr = allocate_print_jobid(pdb, snum, sharename, &jobid); 2819 if (!W_ERROR_IS_OK(werr)) { 2454 2820 goto fail; 2821 } 2455 2822 2456 2823 /* create the database entry */ … … 2466 2833 pjob.spooled = False; 2467 2834 pjob.smbjob = True; 2468 pjob.nt_devmode = nt_devmode; 2469 2470 fstrcpy(pjob.jobname, jobname); 2835 pjob.devmode = devmode; 2836 2837 fstrcpy(pjob.jobname, docname); 2838 2839 fstrcpy(pjob.clientmachine, clientmachine); 2471 2840 2472 2841 fstrcpy(pjob.user, lp_printjob_username(snum)); … … 2474 2843 path, server_info->utok.gid, 2475 2844 server_info->sanitized_username, 2476 pdb_get_domain(server_info->sam_account),2845 server_info->info3->base.domain.string, 2477 2846 pjob.user, sizeof(pjob.user)-1); 2478 2847 /* ensure NULL termination */ … … 2482 2851 2483 2852 /* we have a job entry - now create the spool file */ 2484 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 2485 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2486 pjob.fd = mkstemp(pjob.filename); 2487 2488 if (pjob.fd == -1) { 2489 if (errno == EACCES) { 2490 /* Common setup error, force a report. */ 2491 DEBUG(0, ("print_job_start: insufficient permissions \ 2492 to open spool file %s.\n", pjob.filename)); 2493 } else { 2494 /* Normal case, report at level 3 and above. */ 2495 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename)); 2496 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno))); 2497 } 2853 werr = print_job_spool_file(snum, jobid, filename, &pjob); 2854 if (!W_ERROR_IS_OK(werr)) { 2498 2855 goto fail; 2499 2856 } 2500 2857 2501 pjob_store(s harename, jobid, &pjob);2502 2503 /* Update the 'jobs changed' entry used by print_queue_status. */2504 add_to_jobs_ changed(pdb, jobid);2858 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob); 2859 2860 /* Update the 'jobs added' entry used by print_queue_status. */ 2861 add_to_jobs_added(pdb, jobid); 2505 2862 2506 2863 /* Ensure we keep a rough count of the number of total jobs... */ … … 2509 2866 release_print_db(pdb); 2510 2867 2511 return jobid; 2512 2513 fail: 2514 if (jobid != -1) 2515 pjob_delete(sharename, jobid); 2868 *_jobid = jobid; 2869 return WERR_OK; 2870 2871 fail: 2872 if (jobid != -1) { 2873 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2874 } 2516 2875 2517 2876 release_print_db(pdb); 2518 2877 2519 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); 2520 return (uint32)-1; 2878 DEBUG(3, ("print_job_start: returning fail. " 2879 "Error = %s\n", win_errstr(werr))); 2880 return werr; 2521 2881 } 2522 2882 … … 2525 2885 ****************************************************************************/ 2526 2886 2527 void print_job_endpage(int snum, uint32 jobid) 2887 void print_job_endpage(struct messaging_context *msg_ctx, 2888 int snum, uint32 jobid) 2528 2889 { 2529 2890 const char* sharename = lp_const_servicename(snum); … … 2538 2899 2539 2900 pjob->page_count++; 2540 pjob_store(s harename, jobid, pjob);2901 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2541 2902 } 2542 2903 … … 2547 2908 ****************************************************************************/ 2548 2909 2549 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) 2910 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum, 2911 uint32 jobid, enum file_close_type close_type) 2550 2912 { 2551 2913 const char* sharename = lp_const_servicename(snum); … … 2554 2916 SMB_STRUCT_STAT sbuf; 2555 2917 struct printif *current_printif = get_printer_fns( snum ); 2918 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 2556 2919 2557 2920 pjob = print_job_find(sharename, jobid); 2558 2921 2559 if (!pjob) 2560 return False; 2561 2562 if (pjob->spooled || pjob->pid != sys_getpid()) 2563 return False; 2564 2565 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && 2566 (sys_fstat(pjob->fd, &sbuf, false) == 0)) { 2922 if (!pjob) { 2923 return NT_STATUS_PRINT_CANCELLED; 2924 } 2925 2926 if (pjob->spooled || pjob->pid != sys_getpid()) { 2927 return NT_STATUS_ACCESS_DENIED; 2928 } 2929 2930 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) { 2931 if (pjob->status == PJOB_SMBD_SPOOLING) { 2932 /* take over the file now, smbd is done */ 2933 if (sys_stat(pjob->filename, &sbuf, false) != 0) { 2934 status = map_nt_error_from_unix(errno); 2935 DEBUG(3, ("print_job_end: " 2936 "stat file failed for jobid %d\n", 2937 jobid)); 2938 goto fail; 2939 } 2940 2941 pjob->status = LPQ_SPOOLING; 2942 2943 } else { 2944 2945 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) { 2946 status = map_nt_error_from_unix(errno); 2947 close(pjob->fd); 2948 DEBUG(3, ("print_job_end: " 2949 "stat file failed for jobid %d\n", 2950 jobid)); 2951 goto fail; 2952 } 2953 2954 close(pjob->fd); 2955 } 2956 2567 2957 pjob->size = sbuf.st_ex_size; 2568 close(pjob->fd);2569 pjob->fd = -1;2570 2958 } else { 2571 2959 2572 2960 /* 2573 * Not a normal close or we couldn't stat the job file, 2574 * so something has gone wrong. Cleanup. 2961 * Not a normal close, something has gone wrong. Cleanup. 2575 2962 */ 2576 close(pjob->fd);2577 pjob->fd = -1;2578 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));2963 if (pjob->fd != -1) { 2964 close(pjob->fd); 2965 } 2579 2966 goto fail; 2580 2967 } … … 2588 2975 pjob->filename, pjob->size ? "deleted" : "zero length" )); 2589 2976 unlink(pjob->filename); 2590 pjob_delete(s harename, jobid);2591 return True;2977 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2978 return NT_STATUS_OK; 2592 2979 } 2593 2980 2594 2981 ret = (*(current_printif->job_submit))(snum, pjob); 2595 2982 2596 if (ret) 2983 if (ret) { 2984 status = NT_STATUS_PRINT_CANCELLED; 2597 2985 goto fail; 2986 } 2598 2987 2599 2988 /* The print job has been successfully handed over to the back-end */ … … 2601 2990 pjob->spooled = True; 2602 2991 pjob->status = LPQ_QUEUED; 2603 pjob_store(s harename, jobid, pjob);2992 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2604 2993 2605 2994 /* make sure the database is up to date */ 2606 2995 if (print_cache_expired(lp_const_servicename(snum), True)) 2607 print_queue_update( snum, False);2608 2609 return True;2996 print_queue_update(msg_ctx, snum, False); 2997 2998 return NT_STATUS_OK; 2610 2999 2611 3000 fail: … … 2613 3002 /* The print job was not successfully started. Cleanup */ 2614 3003 /* Still need to add proper error return propagation! 010122:JRR */ 3004 pjob->fd = -1; 2615 3005 unlink(pjob->filename); 2616 pjob_delete(s harename, jobid);2617 return False;3006 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 3007 return status; 2618 3008 } 2619 3009 … … 2622 3012 ****************************************************************************/ 2623 3013 2624 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) 2625 { 2626 TDB_DATA data, cgdata; 3014 static bool get_stored_queue_info(struct messaging_context *msg_ctx, 3015 struct tdb_print_db *pdb, int snum, 3016 int *pcount, print_queue_struct **ppqueue) 3017 { 3018 TDB_DATA data, cgdata, jcdata; 2627 3019 print_queue_struct *queue = NULL; 2628 3020 uint32 qcount = 0; 2629 3021 uint32 extra_count = 0; 3022 uint32_t changed_count = 0; 2630 3023 int total_count = 0; 2631 3024 size_t len = 0; … … 2637 3030 /* make sure the database is up to date */ 2638 3031 if (print_cache_expired(lp_const_servicename(snum), True)) 2639 print_queue_update( snum, False);3032 print_queue_update(msg_ctx, snum, False); 2640 3033 2641 3034 *pcount = 0; … … 2651 3044 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); 2652 3045 2653 /* Get the changed jobs list. */2654 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));3046 /* Get the added jobs list. */ 3047 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 2655 3048 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) 2656 3049 extra_count = cgdata.dsize/4; 3050 3051 /* Get the changed jobs list. */ 3052 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); 3053 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0)) 3054 changed_count = jcdata.dsize / 4; 2657 3055 2658 3056 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count)); … … 2688 3086 total_count = qcount; 2689 3087 2690 /* Add in the changed jobids. */3088 /* Add new jobids to the queue. */ 2691 3089 for( i = 0; i < extra_count; i++) { 2692 3090 uint32 jobid; … … 2694 3092 2695 3093 jobid = IVAL(cgdata.dptr, i*4); 2696 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));3094 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid)); 2697 3095 pjob = print_job_find(lp_const_servicename(snum), jobid); 2698 3096 if (!pjob) { 2699 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));2700 remove_from_jobs_ changed(sharename, jobid);3097 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid)); 3098 remove_from_jobs_added(sharename, jobid); 2701 3099 continue; 2702 3100 } … … 2713 3111 } 2714 3112 3113 /* Update the changed jobids. */ 3114 for (i = 0; i < changed_count; i++) { 3115 uint32_t jobid = IVAL(jcdata.dptr, i * 4); 3116 uint32_t j; 3117 bool found = false; 3118 3119 for (j = 0; j < total_count; j++) { 3120 if (queue[j].job == jobid) { 3121 found = true; 3122 break; 3123 } 3124 } 3125 3126 if (found) { 3127 struct printjob *pjob; 3128 3129 DEBUG(5,("get_stored_queue_info: changed job: %u\n", 3130 (unsigned int) jobid)); 3131 3132 pjob = print_job_find(sharename, jobid); 3133 if (pjob == NULL) { 3134 DEBUG(5,("get_stored_queue_info: failed to find " 3135 "changed job = %u\n", 3136 (unsigned int) jobid)); 3137 remove_from_jobs_changed(sharename, jobid); 3138 continue; 3139 } 3140 3141 queue[j].job = jobid; 3142 queue[j].size = pjob->size; 3143 queue[j].page_count = pjob->page_count; 3144 queue[j].status = pjob->status; 3145 queue[j].priority = 1; 3146 queue[j].time = pjob->starttime; 3147 fstrcpy(queue[j].fs_user, pjob->user); 3148 fstrcpy(queue[j].fs_file, pjob->jobname); 3149 3150 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n", 3151 (unsigned int) j, (unsigned int) jobid, pjob->jobname)); 3152 } 3153 3154 remove_from_jobs_changed(sharename, jobid); 3155 } 3156 2715 3157 /* Sort the queue by submission time otherwise they are displayed 2716 3158 in hash order. */ 2717 3159 2718 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));3160 TYPESAFE_QSORT(queue, total_count, printjob_comp); 2719 3161 2720 3162 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count)); … … 2740 3182 ****************************************************************************/ 2741 3183 2742 int print_queue_status( int snum,3184 int print_queue_status(struct messaging_context *msg_ctx, int snum, 2743 3185 print_queue_struct **ppqueue, 2744 3186 print_status_struct *status) … … 2753 3195 2754 3196 if (print_cache_expired(lp_const_servicename(snum), True)) 2755 print_queue_update( snum, False);3197 print_queue_update(msg_ctx, snum, False); 2756 3198 2757 3199 /* return if we are done */ … … 2790 3232 */ 2791 3233 2792 if (!get_stored_queue_info( pdb, snum, &count, ppqueue)) {3234 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) { 2793 3235 release_print_db(pdb); 2794 3236 return 0; … … 2803 3245 ****************************************************************************/ 2804 3246 2805 WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum) 3247 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info, 3248 struct messaging_context *msg_ctx, int snum) 2806 3249 { 2807 3250 int ret; 2808 3251 struct printif *current_printif = get_printer_fns( snum ); 2809 3252 2810 if (!print_access_check(server_info, snum,3253 if (!print_access_check(server_info, msg_ctx, snum, 2811 3254 PRINTER_ACCESS_ADMINISTER)) { 2812 3255 return WERR_ACCESS_DENIED; … … 2829 3272 /* Send a printer notify message */ 2830 3273 2831 notify_printer_status(snum, PRINTER_STATUS_PAUSED); 3274 notify_printer_status(server_event_context(), msg_ctx, snum, 3275 PRINTER_STATUS_PAUSED); 2832 3276 2833 3277 return WERR_OK; … … 2838 3282 ****************************************************************************/ 2839 3283 2840 WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum) 3284 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info, 3285 struct messaging_context *msg_ctx, int snum) 2841 3286 { 2842 3287 int ret; 2843 3288 struct printif *current_printif = get_printer_fns( snum ); 2844 3289 2845 if (!print_access_check(server_info, snum,3290 if (!print_access_check(server_info, msg_ctx, snum, 2846 3291 PRINTER_ACCESS_ADMINISTER)) { 2847 3292 return WERR_ACCESS_DENIED; … … 2860 3305 /* make sure the database is up to date */ 2861 3306 if (print_cache_expired(lp_const_servicename(snum), True)) 2862 print_queue_update( snum, True);3307 print_queue_update(msg_ctx, snum, True); 2863 3308 2864 3309 /* Send a printer notify message */ 2865 3310 2866 notify_printer_status(snum, PRINTER_STATUS_OK); 3311 notify_printer_status(server_event_context(), msg_ctx, snum, 3312 PRINTER_STATUS_OK); 2867 3313 2868 3314 return WERR_OK; … … 2873 3319 ****************************************************************************/ 2874 3320 2875 WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum) 3321 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info, 3322 struct messaging_context *msg_ctx, int snum) 2876 3323 { 2877 3324 print_queue_struct *queue; … … 2881 3328 2882 3329 /* Force and update so the count is accurate (i.e. not a cached count) */ 2883 print_queue_update(snum, True); 2884 2885 can_job_admin = print_access_check(server_info, snum, 3330 print_queue_update(msg_ctx, snum, True); 3331 3332 can_job_admin = print_access_check(server_info, 3333 msg_ctx, 3334 snum, 2886 3335 JOB_ACCESS_ADMINISTER); 2887 njobs = print_queue_status( snum, &queue, &status);3336 njobs = print_queue_status(msg_ctx, snum, &queue, &status); 2888 3337 2889 3338 if ( can_job_admin ) … … 2895 3344 2896 3345 if (owner || can_job_admin) { 2897 print_job_delete1(snum, queue[i].job); 3346 print_job_delete1(server_event_context(), msg_ctx, 3347 snum, queue[i].job); 2898 3348 } 2899 3349 } … … 2903 3353 2904 3354 /* update the cache */ 2905 print_queue_update( snum, True);3355 print_queue_update(msg_ctx, snum, True); 2906 3356 2907 3357 SAFE_FREE(queue); -
vendor/current/source3/printing/printing_db.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "system/filesys.h" 23 24 #include "printing.h" 25 #include "util_tdb.h" 24 26 25 27 static struct tdb_print_db *print_db_head; … … 99 101 } 100 102 101 if (geteuid() != 0) {103 if (geteuid() != sec_initial_uid()) { 102 104 become_root(); 103 105 done_become_root = True; … … 159 161 ****************************************************************************/ 160 162 161 TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT*tdb, const char *printer_name, bool cleanlist)163 struct TDB_DATA get_printer_notify_pid_list(struct tdb_context *tdb, const char *printer_name, bool cleanlist) 162 164 { 163 165 TDB_DATA data; -
vendor/current/source3/printing/tests/vlp.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "system/passwd.h" 24 #include "system/filesys.h" 25 #include "printing.h" 26 #include "util_tdb.h" 23 27 24 28 #ifdef malloc
Note:
See TracChangeset
for help on using the changeset viewer.