Changeset 745 for trunk/server/source3/printing
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 1 deleted
- 13 edited
- 17 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/printing/load.c
r599 r745 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 -
trunk/server/source3/printing/notify.c
r414 r745 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 -
trunk/server/source3/printing/nt_printing.c
r599 r745 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 } -
trunk/server/source3/printing/pcap.c
r599 r745 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 } -
trunk/server/source3/printing/print_aix.c
r414 r745 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); -
trunk/server/source3/printing/print_cups.c
r664 r745 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 … … 41 42 ****************************************************************/ 42 43 43 static void gotalarm_sig( void)44 static void gotalarm_sig(int signum) 44 45 { 45 46 gotalarm = 1; … … 95 96 96 97 if (timeout) { 97 CatchSignal(SIGALRM, SIGNAL_CASTgotalarm_sig);98 CatchSignal(SIGALRM, gotalarm_sig); 98 99 alarm(timeout); 99 100 } … … 106 107 107 108 108 CatchSignal(SIGALRM, SIG NAL_CAST SIG_IGN);109 CatchSignal(SIGALRM, SIG_IGN); 109 110 alarm(0); 110 111 … … 131 132 } 132 133 133 DEBUG(10, ("successfully sent blob of len % ld\n", (int64_t)ret));134 DEBUG(10, ("successfully sent blob of len %d\n", (int)ret)); 134 135 return true; 135 136 } … … 156 157 } 157 158 158 DEBUG(10, ("successfully recvd blob of len % ld\n", (int64_t)ret));159 DEBUG(10, ("successfully recvd blob of len %d\n", (int)ret)); 159 160 return true; 160 161 } … … 167 168 char *name; 168 169 char *info; 170 char *location = NULL; 169 171 struct pcap_printer *printer; 170 172 bool ret_ok = false; … … 204 206 if (!pull_utf8_talloc(mem_ctx, 205 207 &info, 208 attr->values[0].string.text, 209 &size)) { 210 goto err_out; 211 } 212 } 213 214 if (strcmp(attr->name, "printer-location") == 0 && 215 attr->value_tag == IPP_TAG_TEXT) { 216 if (!pull_utf8_talloc(mem_ctx, 217 &location, 206 218 attr->values[0].string.text, 207 219 &size)) { … … 233 245 pcap_data->printers[pcap_data->count].name = name; 234 246 pcap_data->printers[pcap_data->count].info = info; 247 pcap_data->printers[pcap_data->count].location = location; 235 248 pcap_data->count++; 236 249 } … … 256 269 { 257 270 "printer-name", 258 "printer-info" 271 "printer-info", 272 "printer-location" 259 273 }; 260 274 bool ret = False; … … 368 382 369 383 ret = false; 370 ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, NULL,&pcap_data,384 ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, &pcap_data, 371 385 (ndr_push_flags_fn_t)ndr_push_pcap_data); 372 386 if (ndr_ret == NDR_ERR_SUCCESS) { … … 378 392 } 379 393 380 static struct pcap_cache *local_pcap_copy; 381 struct fd_event *cache_fd_event; 382 383 static bool cups_pcap_load_async(int *pfd) 394 static struct fd_event *cache_fd_event; 395 396 static bool cups_pcap_load_async(struct tevent_context *ev, 397 struct messaging_context *msg_ctx, 398 int *pfd) 384 399 { 385 400 int fds[2]; 386 401 pid_t pid; 402 NTSTATUS status; 387 403 388 404 *pfd = -1; … … 422 438 close_all_print_db(); 423 439 424 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),425 smbd_event_context(), true))) {440 status = reinit_after_fork(msg_ctx, ev, procid_self(), true); 441 if (!NT_STATUS_IS_OK(status)) { 426 442 DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n")); 427 443 smb_panic("cups_pcap_load_async: reinit_after_fork() failed"); … … 436 452 struct cups_async_cb_args { 437 453 int pipe_fd; 438 void (*post_cache_fill_fn)(void); 454 struct event_context *event_ctx; 455 struct messaging_context *msg_ctx; 456 void (*post_cache_fill_fn)(struct event_context *, 457 struct messaging_context *); 439 458 }; 440 459 … … 462 481 } 463 482 464 ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, NULL,&pcap_data,483 ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, &pcap_data, 465 484 (ndr_pull_flags_fn_t)ndr_pull_pcap_data); 466 485 if (ndr_ret != NDR_ERR_SUCCESS) { … … 477 496 ret_ok = pcap_cache_add_specific(&tmp_pcap_cache, 478 497 pcap_data.printers[i].name, 479 pcap_data.printers[i].info); 498 pcap_data.printers[i].info, 499 pcap_data.printers[i].location); 480 500 if (!ret_ok) { 481 501 DEBUG(0, ("failed to add to tmp pcap cache\n")); 482 break;502 goto err_out; 483 503 } 484 504 } 485 505 506 /* replace the system-wide pcap cache with a (possibly empty) new one */ 507 ret_ok = pcap_cache_replace(tmp_pcap_cache); 486 508 if (!ret_ok) { 487 DEBUG(0,("failed to read a new printer list\n")); 488 pcap_cache_destroy_specific(&tmp_pcap_cache); 489 } else { 490 /* We got a possibly empty namelist, replace our local cache. */ 491 pcap_cache_destroy_specific(&local_pcap_copy); 492 local_pcap_copy = tmp_pcap_cache; 493 494 /* And the systemwide pcap cache. */ 495 pcap_cache_replace(local_pcap_copy); 496 497 /* Caller may have requested post cache fill callback */ 498 if (cb_args->post_cache_fill_fn) { 499 cb_args->post_cache_fill_fn(); 500 } 509 DEBUG(0, ("failed to replace pcap cache\n")); 510 } else if (cb_args->post_cache_fill_fn != NULL) { 511 /* Caller requested post cache fill callback */ 512 cb_args->post_cache_fill_fn(cb_args->event_ctx, 513 cb_args->msg_ctx); 501 514 } 502 515 err_out: 516 pcap_cache_destroy_specific(&tmp_pcap_cache); 503 517 TALLOC_FREE(frame); 504 518 close(cb_args->pipe_fd); … … 507 521 } 508 522 509 bool cups_cache_reload(void (*post_cache_fill_fn)(void)) 523 bool cups_cache_reload(struct tevent_context *ev, 524 struct messaging_context *msg_ctx, 525 void (*post_cache_fill_fn)(struct tevent_context *, 526 struct messaging_context *)) 510 527 { 511 528 struct cups_async_cb_args *cb_args; … … 513 530 514 531 cb_args = TALLOC_P(NULL, struct cups_async_cb_args); 515 if ( !cb_args) {532 if (cb_args == NULL) { 516 533 return false; 517 534 } 535 518 536 cb_args->post_cache_fill_fn = post_cache_fill_fn; 537 cb_args->event_ctx = ev; 538 cb_args->msg_ctx = msg_ctx; 519 539 p_pipe_fd = &cb_args->pipe_fd; 520 540 *p_pipe_fd = -1; 521 541 522 542 /* Set up an async refresh. */ 523 if (!cups_pcap_load_async( p_pipe_fd)) {543 if (!cups_pcap_load_async(ev, msg_ctx, p_pipe_fd)) { 524 544 talloc_free(cb_args); 525 545 return false; 526 546 } 527 if (!local_pcap_copy) { 528 /* We have no local cache, wait directly for 529 * async refresh to complete. 530 */ 531 DEBUG(10,("cups_cache_reload: sync read on fd %d\n", 532 *p_pipe_fd )); 533 534 cups_async_callback(smbd_event_context(), 535 NULL, 536 EVENT_FD_READ, 537 (void *)cb_args); 538 if (!local_pcap_copy) { 539 return false; 540 } 541 } else { 542 /* Replace the system cache with our 543 * local copy. */ 544 pcap_cache_replace(local_pcap_copy); 545 546 DEBUG(10,("cups_cache_reload: async read on fd %d\n", 547 *p_pipe_fd )); 548 549 /* Trigger an event when the pipe can be read. */ 550 cache_fd_event = event_add_fd(smbd_event_context(), 551 NULL, *p_pipe_fd, 552 EVENT_FD_READ, 553 cups_async_callback, 554 (void *)cb_args); 555 if (!cache_fd_event) { 556 close(*p_pipe_fd); 557 talloc_free(cb_args); 558 return false; 559 } 560 } 547 548 DEBUG(10,("cups_cache_reload: async read on fd %d\n", 549 *p_pipe_fd )); 550 551 /* Trigger an event when the pipe can be read. */ 552 cache_fd_event = event_add_fd(ev, 553 NULL, *p_pipe_fd, 554 EVENT_FD_READ, 555 cups_async_callback, 556 (void *)cb_args); 557 if (!cache_fd_event) { 558 close(*p_pipe_fd); 559 TALLOC_FREE(cb_args); 560 return false; 561 } 562 561 563 return true; 562 564 } … … 865 867 cups_lang_t *language = NULL; /* Default language */ 866 868 char uri[HTTP_MAX_URI]; /* printer-uri attribute */ 867 const char *clientname = NULL; /* hostname of client for job-originating-host attribute */868 869 char *new_jobname = NULL; 869 870 int num_options = 0; … … 876 877 size_t size; 877 878 uint32_t jobid = (uint32_t)-1; 878 char addr[INET6_ADDRSTRLEN];879 879 880 880 DEBUG(5,("cups_job_submit(%d, %p)\n", snum, pjob)); … … 918 918 "attributes-natural-language", NULL, language->language); 919 919 920 if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { 920 if (!push_utf8_talloc(frame, &printername, lp_printername(snum), 921 &size)) { 921 922 goto out; 922 923 } … … 933 934 NULL, user); 934 935 935 clientname = client_name(get_client_fd());936 if (strcmp(clientname, "UNKNOWN") == 0) {937 clientname = client_addr(get_client_fd(),addr,sizeof(addr));938 }939 940 936 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, 941 937 "job-originating-host-name", NULL, 942 clientname);938 pjob->clientmachine); 943 939 944 940 /* Get the jobid from the filename. */ … … 989 985 if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { 990 986 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 991 DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum), 987 DEBUG(0,("Unable to print file to %s - %s\n", 988 lp_printername(snum), 992 989 ippErrorString(cupsLastError()))); 993 990 } else { … … 1002 999 } 1003 1000 } else { 1004 DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum), 1001 DEBUG(0,("Unable to print file to `%s' - %s\n", 1002 lp_printername(snum), 1005 1003 ippErrorString(cupsLastError()))); 1006 1004 } … … 1427 1425 "attributes-natural-language", NULL, language->language); 1428 1426 1429 if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { 1427 if (!push_utf8_talloc(frame, &printername, lp_printername(snum), 1428 &size)) { 1430 1429 goto out; 1431 1430 } … … 1447 1446 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) { 1448 1447 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 1449 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum), 1448 DEBUG(0,("Unable to pause printer %s - %s\n", 1449 lp_printername(snum), 1450 1450 ippErrorString(cupsLastError()))); 1451 1451 } else { … … 1453 1453 } 1454 1454 } else { 1455 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum), 1455 DEBUG(0,("Unable to pause printer %s - %s\n", 1456 lp_printername(snum), 1456 1457 ippErrorString(cupsLastError()))); 1457 1458 } … … 1528 1529 "attributes-natural-language", NULL, language->language); 1529 1530 1530 if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { 1531 if (!push_utf8_talloc(frame, &printername, lp_printername(snum), 1532 &size)) { 1531 1533 goto out; 1532 1534 } … … 1548 1550 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) { 1549 1551 if (response->request.status.status_code >= IPP_OK_CONFLICT) { 1550 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum), 1552 DEBUG(0,("Unable to resume printer %s - %s\n", 1553 lp_printername(snum), 1551 1554 ippErrorString(cupsLastError()))); 1552 1555 } else { … … 1554 1557 } 1555 1558 } else { 1556 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum), 1559 DEBUG(0,("Unable to resume printer %s - %s\n", 1560 lp_printername(snum), 1557 1561 ippErrorString(cupsLastError()))); 1558 1562 } … … 1588 1592 }; 1589 1593 1590 bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)1591 {1592 TALLOC_CTX *frame = talloc_stackframe();1593 http_t *http = NULL; /* HTTP connection to server */1594 ipp_t *request = NULL, /* IPP Request */1595 *response = NULL; /* IPP Response */1596 ipp_attribute_t *attr; /* Current attribute */1597 cups_lang_t *language = NULL; /* Default language */1598 char uri[HTTP_MAX_URI];1599 char *sharename = NULL;1600 char *name = NULL;1601 static const char *requested[] =/* Requested attributes */1602 {1603 "printer-name",1604 "printer-info",1605 "printer-location"1606 };1607 bool ret = False;1608 size_t size;1609 1610 DEBUG(5, ("pulling %s location\n", printer->sharename));1611 1612 /*1613 * Make sure we don't ask for passwords...1614 */1615 1616 cupsSetPasswordCB(cups_passwd_cb);1617 1618 /*1619 * Try to connect to the server...1620 */1621 1622 if ((http = cups_connect(frame)) == NULL) {1623 goto out;1624 }1625 1626 request = ippNew();1627 1628 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;1629 request->request.op.request_id = 1;1630 1631 language = cupsLangDefault();1632 1633 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,1634 "attributes-charset", NULL, "utf-8");1635 1636 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,1637 "attributes-natural-language", NULL, language->language);1638 1639 if (!push_utf8_talloc(frame, &sharename, printer->sharename, &size)) {1640 goto out;1641 }1642 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",1643 sharename);1644 1645 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,1646 "printer-uri", NULL, uri);1647 1648 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,1649 "requested-attributes",1650 (sizeof(requested) / sizeof(requested[0])),1651 NULL, requested);1652 1653 /*1654 * Do the request and get back a response...1655 */1656 1657 if ((response = cupsDoRequest(http, request, "/")) == NULL) {1658 DEBUG(0,("Unable to get printer attributes - %s\n",1659 ippErrorString(cupsLastError())));1660 goto out;1661 }1662 1663 for (attr = response->attrs; attr != NULL;) {1664 /*1665 * Skip leading attributes until we hit a printer...1666 */1667 1668 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)1669 attr = attr->next;1670 1671 if (attr == NULL)1672 break;1673 1674 /*1675 * Pull the needed attributes from this printer...1676 */1677 1678 while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {1679 if (strcmp(attr->name, "printer-name") == 0 &&1680 attr->value_tag == IPP_TAG_NAME) {1681 if (!pull_utf8_talloc(frame,1682 &name,1683 attr->values[0].string.text,1684 &size)) {1685 goto out;1686 }1687 }1688 1689 /* Grab the comment if we don't have one */1690 if ( (strcmp(attr->name, "printer-info") == 0)1691 && (attr->value_tag == IPP_TAG_TEXT)1692 && !strlen(printer->comment) )1693 {1694 char *comment = NULL;1695 if (!pull_utf8_talloc(frame,1696 &comment,1697 attr->values[0].string.text,1698 &size)) {1699 goto out;1700 }1701 DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",1702 comment));1703 strlcpy(printer->comment,1704 comment,1705 sizeof(printer->comment));1706 }1707 1708 /* Grab the location if we don't have one */1709 if ( (strcmp(attr->name, "printer-location") == 0)1710 && (attr->value_tag == IPP_TAG_TEXT)1711 && !strlen(printer->location) )1712 {1713 char *location = NULL;1714 if (!pull_utf8_talloc(frame,1715 &location,1716 attr->values[0].string.text,1717 &size)) {1718 goto out;1719 }1720 DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",1721 location));1722 strlcpy(printer->location,1723 location,1724 sizeof(printer->location));1725 }1726 1727 attr = attr->next;1728 }1729 1730 /*1731 * We have everything needed...1732 */1733 1734 if (name != NULL)1735 break;1736 }1737 1738 ret = True;1739 1740 out:1741 if (response)1742 ippDelete(response);1743 1744 if (language)1745 cupsLangFree(language);1746 1747 if (http)1748 httpClose(http);1749 1750 TALLOC_FREE(frame);1751 return ret;1752 }1753 1754 1594 #else 1755 1595 /* this keeps fussy compilers happy */ -
trunk/server/source3/printing/print_generic.c
r414 r745 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 -
trunk/server/source3/printing/print_iprint.c
r414 r745 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 } -
trunk/server/source3/printing/print_svid.c
r414 r745 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; -
trunk/server/source3/printing/printing.c
r664 r745 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 #ifdef __OS2__ … … 31 43 32 44 /* Current printer interface */ 33 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid);45 static bool remove_from_jobs_added(const char* sharename, uint32 jobid); 34 46 35 47 /* … … 138 150 } 139 151 140 staticvoid rap_jobid_delete(const char* sharename, uint32 jobid)152 void rap_jobid_delete(const char* sharename, uint32 jobid) 141 153 { 142 154 TDB_DATA key, data; … … 279 291 } 280 292 293 /**************************************************************************** 294 Pack the devicemode to store it in a tdb. 295 ****************************************************************************/ 296 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen) 297 { 298 enum ndr_err_code ndr_err; 299 DATA_BLOB blob; 300 int len = 0; 301 302 if (devmode) { 303 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), 304 devmode, 305 (ndr_push_flags_fn_t) 306 ndr_push_spoolss_DeviceMode); 307 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 308 DEBUG(10, ("pack_devicemode: " 309 "error encoding spoolss_DeviceMode\n")); 310 goto done; 311 } 312 } else { 313 ZERO_STRUCT(blob); 314 } 315 316 len = tdb_pack(buf, buflen, "B", blob.length, blob.data); 317 318 if (devmode) { 319 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname)); 320 } 321 322 done: 323 return len; 324 } 325 326 /**************************************************************************** 327 Unpack the devicemode to store it in a tdb. 328 ****************************************************************************/ 329 static int unpack_devicemode(TALLOC_CTX *mem_ctx, 330 const uint8 *buf, int buflen, 331 struct spoolss_DeviceMode **devmode) 332 { 333 struct spoolss_DeviceMode *dm; 334 enum ndr_err_code ndr_err; 335 char *data = NULL; 336 int data_len = 0; 337 DATA_BLOB blob; 338 int len = 0; 339 340 *devmode = NULL; 341 342 len = tdb_unpack(buf, buflen, "B", &data_len, &data); 343 if (!data) { 344 return len; 345 } 346 347 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); 348 if (!dm) { 349 goto done; 350 } 351 352 blob = data_blob_const(data, data_len); 353 354 ndr_err = ndr_pull_struct_blob(&blob, dm, dm, 355 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); 356 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 357 DEBUG(10, ("unpack_devicemode: " 358 "error parsing spoolss_DeviceMode\n")); 359 goto done; 360 } 361 362 DEBUG(8, ("Unpacked devicemode [%s](%s)\n", 363 dm->devicename, dm->formname)); 364 if (dm->driverextra_data.data) { 365 DEBUG(8, ("with a private section of %d bytes\n", 366 dm->__driverextra_length)); 367 } 368 369 *devmode = dm; 370 371 done: 372 SAFE_FREE(data); 373 return len; 374 } 375 281 376 /*********************************************************************** 282 377 unpack a pjob from a tdb buffer 283 378 ***********************************************************************/ 284 379 285 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )380 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob ) 286 381 { 287 382 int len = 0; … … 293 388 return -1; 294 389 295 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff ",390 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff", 296 391 &pjpid, 297 392 &pjsysjob, … … 306 401 pjob->jobname, 307 402 pjob->user, 403 pjob->clientmachine, 308 404 pjob->queuename); 309 405 … … 311 407 return -1; 312 408 313 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 ) 409 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode); 410 if (used == -1) { 314 411 return -1; 412 } 315 413 316 414 len += used; … … 356 454 } 357 455 358 if ( pjob.nt_devmode ) { 359 free_nt_devicemode( &pjob.nt_devmode ); 360 } 456 talloc_free(pjob.devmode); 361 457 362 458 ZERO_STRUCT( pjob ); … … 442 538 443 539 static const struct { 444 uint32 lpq_status;445 uint32 spoolss_status;540 uint32_t lpq_status; 541 uint32_t spoolss_status; 446 542 } lpq_to_spoolss_status_map[] = { 447 543 { LPQ_QUEUED, JOB_STATUS_QUEUED }, … … 456 552 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ }, 457 553 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, 458 { -1, 0 }554 { (uint32_t)-1, 0 } 459 555 }; 460 556 … … 475 571 } 476 572 477 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data, 478 struct printjob *new_data) 479 { 480 bool new_job = False; 481 482 if (!old_data) 483 new_job = True; 484 485 /* Job attributes that can't be changed. We only send 486 notification for these on a new job. */ 573 /*************************************************************************** 574 Append a jobid to the 'jobs changed' list. 575 ***************************************************************************/ 576 577 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid) 578 { 579 TDB_DATA data; 580 uint32_t store_jobid; 581 582 SIVAL(&store_jobid, 0, jobid); 583 data.dptr = (uint8 *) &store_jobid; 584 data.dsize = 4; 585 586 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 587 588 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), 589 data) == 0); 590 } 591 592 /*************************************************************************** 593 Remove a jobid from the 'jobs changed' list. 594 ***************************************************************************/ 595 596 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid) 597 { 598 struct tdb_print_db *pdb = get_print_db_byname(sharename); 599 TDB_DATA data, key; 600 size_t job_count, i; 601 bool ret = False; 602 bool gotlock = False; 603 604 if (!pdb) { 605 return False; 606 } 607 608 ZERO_STRUCT(data); 609 610 key = string_tdb_data("INFO/jobs_changed"); 611 612 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) 613 goto out; 614 615 gotlock = True; 616 617 data = tdb_fetch(pdb->tdb, key); 618 619 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) 620 goto out; 621 622 job_count = data.dsize / 4; 623 for (i = 0; i < job_count; i++) { 624 uint32 ch_jobid; 625 626 ch_jobid = IVAL(data.dptr, i*4); 627 if (ch_jobid == jobid) { 628 if (i < job_count -1 ) 629 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); 630 data.dsize -= 4; 631 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) 632 goto out; 633 break; 634 } 635 } 636 637 ret = True; 638 out: 639 640 if (gotlock) 641 tdb_chainunlock(pdb->tdb, key); 642 SAFE_FREE(data.dptr); 643 release_print_db(pdb); 644 if (ret) 645 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); 646 else 647 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); 648 return ret; 649 } 650 651 static void pjob_store_notify(struct tevent_context *ev, 652 struct messaging_context *msg_ctx, 653 const char* sharename, uint32 jobid, 654 struct printjob *old_data, 655 struct printjob *new_data, 656 bool *pchanged) 657 { 658 bool new_job = false; 659 bool changed = false; 660 661 if (old_data == NULL) { 662 new_job = true; 663 } 487 664 488 665 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the … … 494 671 495 672 if (new_job) { 496 notify_job_submitted(sharename, jobid, new_data->starttime); 497 notify_job_username(sharename, jobid, new_data->user); 498 } 499 500 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 501 notify_job_name(sharename, jobid, new_data->jobname); 502 503 /* Job attributes of a new job or attributes that can be 504 modified. */ 505 506 if (new_job || !strequal(old_data->jobname, new_data->jobname)) 507 notify_job_name(sharename, jobid, new_data->jobname); 508 509 if (new_job || old_data->status != new_data->status) 510 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status)); 511 512 if (new_job || old_data->size != new_data->size) 513 notify_job_total_bytes(sharename, jobid, new_data->size); 514 515 if (new_job || old_data->page_count != new_data->page_count) 516 notify_job_total_pages(sharename, jobid, new_data->page_count); 673 notify_job_submitted(ev, msg_ctx, 674 sharename, jobid, new_data->starttime); 675 notify_job_username(ev, msg_ctx, 676 sharename, jobid, new_data->user); 677 notify_job_name(ev, msg_ctx, 678 sharename, jobid, new_data->jobname); 679 notify_job_status(ev, msg_ctx, 680 sharename, jobid, map_to_spoolss_status(new_data->status)); 681 notify_job_total_bytes(ev, msg_ctx, 682 sharename, jobid, new_data->size); 683 notify_job_total_pages(ev, msg_ctx, 684 sharename, jobid, new_data->page_count); 685 } else { 686 if (!strequal(old_data->jobname, new_data->jobname)) { 687 notify_job_name(ev, msg_ctx, sharename, 688 jobid, new_data->jobname); 689 changed = true; 690 } 691 692 if (old_data->status != new_data->status) { 693 notify_job_status(ev, msg_ctx, 694 sharename, jobid, 695 map_to_spoolss_status(new_data->status)); 696 } 697 698 if (old_data->size != new_data->size) { 699 notify_job_total_bytes(ev, msg_ctx, 700 sharename, jobid, new_data->size); 701 } 702 703 if (old_data->page_count != new_data->page_count) { 704 notify_job_total_pages(ev, msg_ctx, 705 sharename, jobid, 706 new_data->page_count); 707 } 708 } 709 710 *pchanged = changed; 517 711 } 518 712 … … 521 715 ****************************************************************************/ 522 716 523 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob) 717 static bool pjob_store(struct tevent_context *ev, 718 struct messaging_context *msg_ctx, 719 const char* sharename, uint32 jobid, 720 struct printjob *pjob) 524 721 { 525 722 uint32_t tmp; … … 545 742 len = 0; 546 743 buflen = newlen; 547 len += tdb_pack(buf+len, buflen-len, "dddddddddffff ",744 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff", 548 745 (uint32)pjob->pid, 549 746 (uint32)pjob->sysjob, … … 558 755 pjob->jobname, 559 756 pjob->user, 757 pjob->clientmachine, 560 758 pjob->queuename); 561 759 562 len += pack_devicemode(pjob-> nt_devmode, buf+len, buflen-len);760 len += pack_devicemode(pjob->devmode, buf+len, buflen-len); 563 761 564 762 if (buflen != len) { … … 580 778 TDB_REPLACE) == 0); 581 779 582 release_print_db(pdb);583 584 780 /* Send notify updates for what has changed */ 585 781 586 782 if ( ret ) { 783 bool changed = false; 587 784 struct printjob old_pjob; 588 785 … … 591 788 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) 592 789 { 593 pjob_store_notify( sharename, jobid, &old_pjob , pjob ); 594 free_nt_devicemode( &old_pjob.nt_devmode ); 790 pjob_store_notify(server_event_context(), 791 msg_ctx, 792 sharename, jobid, &old_pjob, 793 pjob, 794 &changed); 795 talloc_free(old_pjob.devmode); 796 797 if (changed) { 798 add_to_jobs_changed(pdb, jobid); 799 } 595 800 } 801 596 802 } 597 803 else { 598 804 /* new job */ 599 pjob_store_notify( sharename, jobid, NULL, pjob ); 600 } 601 } 602 805 pjob_store_notify(server_event_context(), msg_ctx, 806 sharename, jobid, NULL, pjob, 807 &changed); 808 } 809 } 810 811 release_print_db(pdb); 603 812 done: 604 813 SAFE_FREE( old_data.dptr ); … … 612 821 ****************************************************************************/ 613 822 614 void pjob_delete(const char* sharename, uint32 jobid) 823 static void pjob_delete(struct tevent_context *ev, 824 struct messaging_context *msg_ctx, 825 const char* sharename, uint32 jobid) 615 826 { 616 827 uint32_t tmp; … … 638 849 639 850 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED; 640 notify_job_status( sharename, jobid, job_status);851 notify_job_status(ev, msg_ctx, sharename, jobid, job_status); 641 852 642 853 /* Remove from printing.tdb */ 643 854 644 855 tdb_delete(pdb->tdb, print_key(jobid, &tmp)); 645 remove_from_jobs_ changed(sharename, jobid);856 remove_from_jobs_added(sharename, jobid); 646 857 release_print_db( pdb ); 647 858 rap_jobid_delete(sharename, jobid); … … 652 863 ****************************************************************************/ 653 864 654 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid) 865 static void print_unix_job(struct tevent_context *ev, 866 struct messaging_context *msg_ctx, 867 const char *sharename, print_queue_struct *q, 868 uint32 jobid) 655 869 { 656 870 struct printjob pj, *old_pj; … … 683 897 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename ); 684 898 685 pjob_store( sharename, jobid, &pj);899 pjob_store(ev, msg_ctx, sharename, jobid, &pj); 686 900 } 687 901 … … 694 908 const char *lprm_command; 695 909 struct printif *print_if; 910 struct tevent_context *ev; 911 struct messaging_context *msg_ctx; 696 912 }; 697 913 … … 713 929 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) 714 930 return 0; 715 free_nt_devicemode( &pjob.nt_devmode);931 talloc_free(pjob.devmode); 716 932 717 933 … … 727 943 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", 728 944 (unsigned int)jobid )); 729 pjob_delete(ts->sharename, jobid); 945 pjob_delete(ts->ev, ts->msg_ctx, 946 ts->sharename, jobid); 730 947 return 0; 731 948 } … … 743 960 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n", 744 961 (unsigned int)jobid, (unsigned int)pjob.pid )); 745 pjob_delete(ts->sharename, jobid); 962 pjob_delete(ts->ev, ts->msg_ctx, 963 ts->sharename, jobid); 746 964 } else 747 965 ts->total_jobs++; … … 773 991 /* if we can't delete, then reset the job status */ 774 992 pjob.status = LPQ_QUEUED; 775 pjob_store(ts->sharename, jobid, &pjob); 993 pjob_store(ts->ev, ts->msg_ctx, 994 ts->sharename, jobid, &pjob); 776 995 } 777 996 else { 778 997 /* if we deleted the job, the remove the tdb record */ 779 pjob_delete(ts->sharename, jobid); 998 pjob_delete(ts->ev, 999 ts->msg_ctx, 1000 ts->sharename, jobid); 780 1001 pjob.status = LPQ_DELETED; 781 1002 } … … 805 1026 (unsigned int)pjob.starttime, 806 1027 (unsigned int)ts->lpq_time )); 807 pjob_delete(ts->sharename, jobid); 1028 pjob_delete(ts->ev, ts->msg_ctx, 1029 ts->sharename, jobid); 808 1030 } else 809 1031 ts->total_jobs++; … … 1002 1224 } 1003 1225 1004 static TDB_DATA get_jobs_ changed_data(struct tdb_print_db *pdb)1226 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb) 1005 1227 { 1006 1228 TDB_DATA data; … … 1008 1230 ZERO_STRUCT(data); 1009 1231 1010 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));1232 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 1011 1233 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { 1012 1234 SAFE_FREE(data.dptr); … … 1017 1239 } 1018 1240 1019 static void check_job_ changed(const char *sharename, TDB_DATA data, uint32 jobid)1241 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid) 1020 1242 { 1021 1243 unsigned int i; … … 1027 1249 ch_jobid = IVAL(data.dptr, i*4); 1028 1250 if (ch_jobid == jobid) 1029 remove_from_jobs_ changed(sharename, jobid);1251 remove_from_jobs_added(sharename, jobid); 1030 1252 } 1031 1253 } … … 1097 1319 1098 1320 /**************************************************************************** 1099 main work for updating the lpq cahe for a printer queue 1100 ****************************************************************************/ 1101 1102 static void print_queue_update_internal( const char *sharename, 1321 main work for updating the lpq cache for a printer queue 1322 ****************************************************************************/ 1323 1324 static void print_queue_update_internal( struct tevent_context *ev, 1325 struct messaging_context *msg_ctx, 1326 const char *sharename, 1103 1327 struct printif *current_printif, 1104 1328 char *lpq_command, char *lprm_command ) … … 1144 1368 in hash order. */ 1145 1369 1146 qsort(queue, qcount, sizeof(print_queue_struct), 1147 QSORT_CAST(printjob_comp)); 1370 TYPESAFE_QSORT(queue, qcount, printjob_comp); 1148 1371 1149 1372 /* … … 1158 1381 */ 1159 1382 1160 jcdata = get_jobs_ changed_data(pdb);1383 jcdata = get_jobs_added_data(pdb); 1161 1384 1162 1385 for (i=0; i<qcount; i++) { … … 1165 1388 if (jobid == (uint32)-1) { 1166 1389 /* assume its a unix print job */ 1167 print_unix_job(sharename, &queue[i], jobid); 1390 print_unix_job(ev, msg_ctx, 1391 sharename, &queue[i], jobid); 1168 1392 continue; 1169 1393 } … … 1175 1399 with jobs in the queue. All we can do is treat them 1176 1400 like unix jobs. Pity. */ 1177 print_unix_job(sharename, &queue[i], jobid); 1401 print_unix_job(ev, msg_ctx, 1402 sharename, &queue[i], jobid); 1178 1403 continue; 1179 1404 } … … 1186 1411 pjob->status = queue[i].status; 1187 1412 1188 pjob_store( sharename, jobid, pjob);1189 1190 check_job_ changed(sharename, jcdata, jobid);1413 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1414 1415 check_job_added(sharename, jcdata, jobid); 1191 1416 } 1192 1417 … … 1203 1428 tstruct.lprm_command = lprm_command; 1204 1429 tstruct.print_if = current_printif; 1430 tstruct.ev = ev; 1431 tstruct.msg_ctx = msg_ctx; 1205 1432 1206 1433 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct); … … 1260 1487 ****************************************************************************/ 1261 1488 1262 static void print_queue_update_with_lock( const char *sharename, 1489 static void print_queue_update_with_lock( struct tevent_context *ev, 1490 struct messaging_context *msg_ctx, 1491 const char *sharename, 1263 1492 struct printif *current_printif, 1264 1493 char *lpq_command, char *lprm_command ) … … 1329 1558 /* do the main work now */ 1330 1559 1331 print_queue_update_internal( sharename, current_printif, 1332 lpq_command, lprm_command ); 1560 print_queue_update_internal(ev, msg_ctx, 1561 sharename, current_printif, 1562 lpq_command, lprm_command); 1333 1563 1334 1564 /* Delete our pid from the db. */ … … 1340 1570 this is the receive function of the background lpq updater 1341 1571 ****************************************************************************/ 1342 staticvoid print_queue_receive(struct messaging_context *msg,1572 void print_queue_receive(struct messaging_context *msg, 1343 1573 void *private_data, 1344 1574 uint32_t msg_type, … … 1364 1594 } 1365 1595 1366 print_queue_update_with_lock(s harename,1596 print_queue_update_with_lock(server_event_context(), msg, sharename, 1367 1597 get_printer_fns_from_type((enum printing_types)printing_type), 1368 1598 lpqcommand, lprmcommand ); … … 1385 1615 } 1386 1616 1617 extern struct child_pid *children; 1618 extern int num_children; 1619 1387 1620 static void add_child_pid(pid_t pid) 1388 1621 { 1389 extern struct child_pid *children;1390 1622 struct child_pid *child; 1391 extern int num_children;1392 1623 1393 1624 child = SMB_MALLOC_P(struct child_pid); … … 1406 1637 main thread of the background lpq updater 1407 1638 ****************************************************************************/ 1408 void start_background_queue(void) 1639 void start_background_queue(struct tevent_context *ev, 1640 struct messaging_context *msg_ctx) 1409 1641 { 1410 1642 /* Use local variables for this as we don't … … 1434 1666 struct tevent_fd *fde; 1435 1667 int ret; 1668 NTSTATUS status; 1436 1669 1437 1670 /* Child. */ … … 1441 1674 pause_pipe[0] = -1; 1442 1675 1443 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),1444 smbd_event_context(), 1445 true))) {1676 status = reinit_after_fork(msg_ctx, ev, procid_self(), true); 1677 1678 if (!NT_STATUS_IS_OK(status)) { 1446 1679 DEBUG(0,("reinit_after_fork() failed\n")); 1447 1680 smb_panic("reinit_after_fork() failed"); … … 1449 1682 1450 1683 smbd_setup_sig_term_handler(); 1451 smbd_setup_sig_hup_handler(); 1452 1453 claim_connection( NULL, "smbd lpq backend", 1454 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 1684 smbd_setup_sig_hup_handler(ev, msg_ctx); 1685 1686 if (!serverid_register(procid_self(), 1687 FLAG_MSG_GENERAL|FLAG_MSG_SMBD 1688 |FLAG_MSG_PRINT_GENERAL)) { 1689 exit(1); 1690 } 1455 1691 1456 1692 if (!locking_init()) { … … 1458 1694 } 1459 1695 1460 messaging_register(smbd_messaging_context(), NULL, 1461 MSG_PRINTER_UPDATE, print_queue_receive); 1462 1463 fde = tevent_add_fd(smbd_event_context(), smbd_event_context(), 1464 pause_pipe[1], TEVENT_FD_READ, 1696 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, 1697 print_queue_receive); 1698 1699 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ, 1465 1700 printing_pause_fd_handler, 1466 1701 NULL); … … 1471 1706 1472 1707 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); 1473 ret = tevent_loop_wait( smbd_event_context());1708 ret = tevent_loop_wait(ev); 1474 1709 /* should not be reached */ 1475 1710 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", … … 1485 1720 ****************************************************************************/ 1486 1721 1487 static void print_queue_update(int snum, bool force) 1722 static void print_queue_update(struct messaging_context *msg_ctx, 1723 int snum, bool force) 1488 1724 { 1489 1725 fstring key; … … 1506 1742 lp_lpqcommand(snum), 1507 1743 "%p", 1508 PRINTERNAME(snum),1744 lp_printername(snum), 1509 1745 false, false, false); 1510 1746 if (!lpqcommand) { … … 1526 1762 lp_lprmcommand(snum), 1527 1763 "%p", 1528 PRINTERNAME(snum),1764 lp_printername(snum), 1529 1765 false, false, false); 1530 1766 if (!lprmcommand) { … … 1551 1787 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename)); 1552 1788 current_printif = get_printer_fns( snum ); 1553 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand ); 1789 print_queue_update_with_lock(server_event_context(), msg_ctx, 1790 sharename, current_printif, 1791 lpqcommand, lprmcommand); 1554 1792 1555 1793 return; … … 1604 1842 /* finally send the message */ 1605 1843 1606 messaging_send_buf(smbd_messaging_context(), 1607 pid_to_procid(background_lpq_updater_pid), 1844 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid), 1608 1845 MSG_PRINTER_UPDATE, (uint8 *)buffer, len); 1609 1846 … … 1812 2049 1813 2050 /**************************************************************************** 1814 Give the fd used for a jobid.1815 ****************************************************************************/1816 1817 int print_job_fd(const char* sharename, uint32 jobid)1818 {1819 struct printjob *pjob = print_job_find(sharename, jobid);1820 if (!pjob)1821 return -1;1822 /* don't allow another process to get this info - it is meaningless */1823 if (pjob->pid != sys_getpid())1824 return -1;1825 return pjob->fd;1826 }1827 1828 /****************************************************************************1829 2051 Give the filename used for a jobid. 1830 2052 Only valid for the process doing the spooling and when the job … … 1847 2069 ****************************************************************************/ 1848 2070 1849 NT_DEVICEMODE*print_job_devmode(const char* sharename, uint32 jobid)2071 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid) 1850 2072 { 1851 2073 struct printjob *pjob = print_job_find(sharename, jobid); … … 1854 2076 return NULL; 1855 2077 1856 return pjob->nt_devmode; 1857 } 1858 1859 /**************************************************************************** 1860 Set the place in the queue for a job. 1861 ****************************************************************************/ 1862 1863 bool print_job_set_place(const char *sharename, uint32 jobid, int place) 1864 { 1865 DEBUG(2,("print_job_set_place not implemented yet\n")); 1866 return False; 2078 return pjob->devmode; 1867 2079 } 1868 2080 … … 1871 2083 ****************************************************************************/ 1872 2084 1873 bool print_job_set_name(const char *sharename, uint32 jobid, char *name) 2085 bool print_job_set_name(struct tevent_context *ev, 2086 struct messaging_context *msg_ctx, 2087 const char *sharename, uint32 jobid, const char *name) 1874 2088 { 1875 2089 struct printjob *pjob; … … 1880 2094 1881 2095 fstrcpy(pjob->jobname, name); 1882 return pjob_store(sharename, jobid, pjob); 1883 } 2096 return pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2097 } 2098 2099 /**************************************************************************** 2100 Get the name of a job. Only possible for owner. 2101 ****************************************************************************/ 2102 2103 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name) 2104 { 2105 struct printjob *pjob; 2106 2107 pjob = print_job_find(sharename, jobid); 2108 if (!pjob || pjob->pid != sys_getpid()) { 2109 return false; 2110 } 2111 2112 *name = talloc_strdup(mem_ctx, pjob->jobname); 2113 if (!*name) { 2114 return false; 2115 } 2116 2117 return true; 2118 } 2119 1884 2120 1885 2121 /*************************************************************************** 1886 Remove a jobid from the 'jobs changed' list.2122 Remove a jobid from the 'jobs added' list. 1887 2123 ***************************************************************************/ 1888 2124 1889 static bool remove_from_jobs_ changed(const char* sharename, uint32 jobid)2125 static bool remove_from_jobs_added(const char* sharename, uint32 jobid) 1890 2126 { 1891 2127 struct tdb_print_db *pdb = get_print_db_byname(sharename); … … 1901 2137 ZERO_STRUCT(data); 1902 2138 1903 key = string_tdb_data("INFO/jobs_ changed");2139 key = string_tdb_data("INFO/jobs_added"); 1904 2140 1905 2141 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) … … 1936 2172 release_print_db(pdb); 1937 2173 if (ret) 1938 DEBUG(10,("remove_from_jobs_ changed: removed jobid %u\n", (unsigned int)jobid ));2174 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid )); 1939 2175 else 1940 DEBUG(10,("remove_from_jobs_ changed: Failed to remove jobid %u\n", (unsigned int)jobid ));2176 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid )); 1941 2177 return ret; 1942 2178 } … … 1946 2182 ****************************************************************************/ 1947 2183 1948 static bool print_job_delete1(int snum, uint32 jobid) 2184 static bool print_job_delete1(struct tevent_context *ev, 2185 struct messaging_context *msg_ctx, 2186 int snum, uint32 jobid) 1949 2187 { 1950 2188 const char* sharename = lp_const_servicename(snum); … … 1975 2213 1976 2214 pjob->status = LPQ_DELETING; 1977 pjob_store( sharename, jobid, pjob);2215 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 1978 2216 1979 2217 if (pjob->spooled && pjob->sysjob != -1) 1980 2218 { 1981 2219 result = (*(current_printif->job_delete))( 1982 PRINTERNAME(snum),2220 lp_printername(snum), 1983 2221 lp_lprmcommand(snum), 1984 2222 pjob); … … 1993 2231 if (!pdb) 1994 2232 return False; 1995 pjob_delete( sharename, jobid);2233 pjob_delete(ev, msg_ctx, sharename, jobid); 1996 2234 /* Ensure we keep a rough count of the number of total jobs... */ 1997 2235 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1); … … 2000 2238 } 2001 2239 2002 remove_from_jobs_ changed( sharename, jobid );2240 remove_from_jobs_added( sharename, jobid ); 2003 2241 2004 2242 return (result == 0); … … 2009 2247 ****************************************************************************/ 2010 2248 2011 static bool is_owner( struct auth_serversupplied_info *server_info,2249 static bool is_owner(const struct auth_serversupplied_info *server_info, 2012 2250 const char *servicename, 2013 2251 uint32 jobid) … … 2025 2263 ****************************************************************************/ 2026 2264 2027 bool print_job_delete(struct auth_serversupplied_info *server_info, int snum, 2028 uint32 jobid, WERROR *errcode) 2029 { 2030 const char* sharename = lp_const_servicename( snum ); 2265 WERROR print_job_delete(const struct auth_serversupplied_info *server_info, 2266 struct messaging_context *msg_ctx, 2267 int snum, uint32_t jobid) 2268 { 2269 const char* sharename = lp_const_servicename(snum); 2031 2270 struct printjob *pjob; 2032 2271 bool owner; 2033 2272 char *fname; 2034 2273 2035 *errcode = WERR_OK;2036 2037 2274 owner = is_owner(server_info, lp_const_servicename(snum), jobid); 2038 2275 … … 2041 2278 2042 2279 if (!owner && 2043 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2280 !print_access_check(server_info, msg_ctx, snum, 2281 JOB_ACCESS_ADMINISTER)) { 2044 2282 DEBUG(3, ("delete denied by security descriptor\n")); 2045 *errcode = WERR_ACCESS_DENIED;2046 2283 2047 2284 /* BEGIN_ADMIN_LOG */ … … 2050 2287 pause, or resume print job. User name: %s. Printer name: %s.", 2051 2288 uidtoname(server_info->utok.uid), 2052 PRINTERNAME(snum) );2289 lp_printername(snum) ); 2053 2290 /* END_ADMIN_LOG */ 2054 2291 2055 return False;2292 return WERR_ACCESS_DENIED; 2056 2293 } 2057 2294 … … 2063 2300 */ 2064 2301 2065 if ( (fname = print_job_fname( sharename, jobid )) != NULL )2066 {2302 fname = print_job_fname(sharename, jobid); 2303 if (fname != NULL) { 2067 2304 /* remove the spool file */ 2068 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname )); 2069 if ( unlink( fname ) == -1 ) { 2070 *errcode = map_werror_from_unix(errno); 2071 return False; 2072 } 2073 } 2074 2075 if (!print_job_delete1(snum, jobid)) { 2076 *errcode = WERR_ACCESS_DENIED; 2077 return False; 2305 DEBUG(10, ("print_job_delete: " 2306 "Removing spool file [%s]\n", fname)); 2307 if (unlink(fname) == -1) { 2308 return map_werror_from_unix(errno); 2309 } 2310 } 2311 2312 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) { 2313 return WERR_ACCESS_DENIED; 2078 2314 } 2079 2315 … … 2081 2317 job still exists */ 2082 2318 2083 print_queue_update( snum, True);2319 print_queue_update(msg_ctx, snum, True); 2084 2320 2085 2321 pjob = print_job_find(sharename, jobid); 2086 if ( pjob && (pjob->status != LPQ_DELETING) ) 2087 *errcode = WERR_ACCESS_DENIED; 2088 2089 return (pjob == NULL ); 2322 if (pjob && (pjob->status != LPQ_DELETING)) { 2323 return WERR_ACCESS_DENIED; 2324 } 2325 2326 return WERR_PRINTER_HAS_JOBS_QUEUED; 2090 2327 } 2091 2328 … … 2094 2331 ****************************************************************************/ 2095 2332 2096 bool print_job_pause(struct auth_serversupplied_info *server_info, int snum, 2097 uint32 jobid, WERROR *errcode) 2333 bool print_job_pause(const struct auth_serversupplied_info *server_info, 2334 struct messaging_context *msg_ctx, 2335 int snum, uint32 jobid, WERROR *errcode) 2098 2336 { 2099 2337 const char* sharename = lp_const_servicename(snum); … … 2117 2355 2118 2356 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2119 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2357 !print_access_check(server_info, msg_ctx, snum, 2358 JOB_ACCESS_ADMINISTER)) { 2120 2359 DEBUG(3, ("pause denied by security descriptor\n")); 2121 2360 … … 2125 2364 pause, or resume print job. User name: %s. Printer name: %s.", 2126 2365 uidtoname(server_info->utok.uid), 2127 PRINTERNAME(snum) );2366 lp_printername(snum) ); 2128 2367 /* END_ADMIN_LOG */ 2129 2368 … … 2145 2384 /* Send a printer notify message */ 2146 2385 2147 notify_job_status(sharename, jobid, JOB_STATUS_PAUSED); 2386 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2387 JOB_STATUS_PAUSED); 2148 2388 2149 2389 /* how do we tell if this succeeded? */ … … 2156 2396 ****************************************************************************/ 2157 2397 2158 bool print_job_resume(struct auth_serversupplied_info *server_info, int snum, 2159 uint32 jobid, WERROR *errcode) 2398 bool print_job_resume(const struct auth_serversupplied_info *server_info, 2399 struct messaging_context *msg_ctx, 2400 int snum, uint32 jobid, WERROR *errcode) 2160 2401 { 2161 2402 const char *sharename = lp_const_servicename(snum); … … 2179 2420 2180 2421 if (!is_owner(server_info, lp_const_servicename(snum), jobid) && 2181 !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) { 2422 !print_access_check(server_info, msg_ctx, snum, 2423 JOB_ACCESS_ADMINISTER)) { 2182 2424 DEBUG(3, ("resume denied by security descriptor\n")); 2183 2425 *errcode = WERR_ACCESS_DENIED; … … 2188 2430 pause, or resume print job. User name: %s. Printer name: %s.", 2189 2431 uidtoname(server_info->utok.uid), 2190 PRINTERNAME(snum) );2432 lp_printername(snum) ); 2191 2433 /* END_ADMIN_LOG */ 2192 2434 return False; … … 2205 2447 /* Send a printer notify message */ 2206 2448 2207 notify_job_status(sharename, jobid, JOB_STATUS_QUEUED); 2449 notify_job_status(server_event_context(), msg_ctx, sharename, jobid, 2450 JOB_STATUS_QUEUED); 2208 2451 2209 2452 return True; … … 2214 2457 ****************************************************************************/ 2215 2458 2216 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size) 2459 ssize_t print_job_write(struct tevent_context *ev, 2460 struct messaging_context *msg_ctx, 2461 int snum, uint32 jobid, const char *buf, size_t size) 2217 2462 { 2218 2463 const char* sharename = lp_const_servicename(snum); 2219 int return_code;2464 ssize_t return_code; 2220 2465 struct printjob *pjob; 2221 2466 … … 2228 2473 return -1; 2229 2474 2230 return_code = write_data_at_offset(pjob->fd, buf, size, pos); 2475 /* if SMBD is spooling this can't be allowed */ 2476 if (pjob->status == PJOB_SMBD_SPOOLING) { 2477 return -1; 2478 } 2479 2480 return_code = write_data(pjob->fd, buf, size); 2231 2481 2232 2482 if (return_code>0) { 2233 2483 pjob->size += size; 2234 pjob_store( sharename, jobid, pjob);2484 pjob_store(ev, msg_ctx, sharename, jobid, pjob); 2235 2485 } 2236 2486 return return_code; … … 2275 2525 ****************************************************************************/ 2276 2526 2277 int print_queue_length(int snum, print_status_struct *pstatus) 2527 int print_queue_length(struct messaging_context *msg_ctx, int snum, 2528 print_status_struct *pstatus) 2278 2529 { 2279 2530 const char* sharename = lp_const_servicename( snum ); … … 2285 2536 /* make sure the database is up to date */ 2286 2537 if (print_cache_expired(lp_const_servicename(snum), True)) 2287 print_queue_update( snum, False);2538 print_queue_update(msg_ctx, snum, False); 2288 2539 2289 2540 /* also fetch the queue status */ … … 2301 2552 ***************************************************************************/ 2302 2553 2303 static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid) 2554 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum, 2555 const char *sharename, uint32 *pjobid) 2304 2556 { 2305 2557 int i; 2306 2558 uint32 jobid; 2559 enum TDB_ERROR terr; 2560 int ret; 2307 2561 2308 2562 *pjobid = (uint32)-1; … … 2310 2564 for (i = 0; i < 3; i++) { 2311 2565 /* Lock the database - only wait 20 seconds. */ 2312 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) { 2313 DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename)); 2314 return False; 2566 ret = tdb_lock_bystring_with_timeout(pdb->tdb, 2567 "INFO/nextjob", 20); 2568 if (ret == -1) { 2569 DEBUG(0, ("allocate_print_jobid: " 2570 "Failed to lock printing database %s\n", 2571 sharename)); 2572 terr = tdb_error(pdb->tdb); 2573 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2315 2574 } 2316 2575 2317 2576 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) { 2318 if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) { 2319 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n", 2320 sharename)); 2577 terr = tdb_error(pdb->tdb); 2578 if (terr != TDB_ERR_NOEXIST) { 2579 DEBUG(0, ("allocate_print_jobid: " 2580 "Failed to fetch INFO/nextjob " 2581 "for print queue %s\n", sharename)); 2321 2582 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2322 return False;2583 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2323 2584 } 2324 DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename)); 2585 DEBUG(10, ("allocate_print_jobid: " 2586 "No existing jobid in %s\n", sharename)); 2325 2587 jobid = 0; 2326 2588 } 2327 2589 2328 DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename)); 2590 DEBUG(10, ("allocate_print_jobid: " 2591 "Read jobid %u from %s\n", jobid, sharename)); 2329 2592 2330 2593 jobid = NEXT_JOBID(jobid); 2331 2594 2332 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) { 2333 DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n")); 2595 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid); 2596 if (ret == -1) { 2597 terr = tdb_error(pdb->tdb); 2598 DEBUG(3, ("allocate_print_jobid: " 2599 "Failed to store INFO/nextjob.\n")); 2334 2600 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); 2335 return False;2601 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2336 2602 } 2337 2603 … … 2342 2608 break; 2343 2609 } 2344 DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename)); 2610 DEBUG(10, ("allocate_print_jobid: " 2611 "Found jobid %u in %s\n", jobid, sharename)); 2345 2612 } 2346 2613 2347 2614 if (i > 2) { 2348 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n", 2349 sharename)); 2615 DEBUG(0, ("allocate_print_jobid: " 2616 "Failed to allocate a print job for queue %s\n", 2617 sharename)); 2350 2618 /* Probably full... */ 2351 errno = ENOSPC; 2352 return False; 2619 return WERR_NO_SPOOL_SPACE; 2353 2620 } 2354 2621 … … 2361 2628 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum, 2362 2629 TDB_INSERT) == -1) { 2363 DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n", 2364 jobid )); 2365 return False; 2630 DEBUG(3, ("allocate_print_jobid: " 2631 "jobid (%d) failed to store placeholder.\n", 2632 jobid )); 2633 terr = tdb_error(pdb->tdb); 2634 return ntstatus_to_werror(map_nt_error_from_tdb(terr)); 2366 2635 } 2367 2636 } 2368 2637 2369 2638 *pjobid = jobid; 2370 return True;2639 return WERR_OK; 2371 2640 } 2372 2641 2373 2642 /*************************************************************************** 2374 Append a jobid to the 'jobs changed' list.2643 Append a jobid to the 'jobs added' list. 2375 2644 ***************************************************************************/ 2376 2645 2377 static bool add_to_jobs_ changed(struct tdb_print_db *pdb, uint32 jobid)2646 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid) 2378 2647 { 2379 2648 TDB_DATA data; … … 2384 2653 data.dsize = 4; 2385 2654 2386 DEBUG(10,("add_to_jobs_ changed: Added jobid %u\n", (unsigned int)jobid ));2387 2388 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_ changed"),2655 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); 2656 2657 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"), 2389 2658 data) == 0); 2659 } 2660 2661 2662 /*************************************************************************** 2663 Do all checks needed to determine if we can start a job. 2664 ***************************************************************************/ 2665 2666 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info, 2667 struct messaging_context *msg_ctx, 2668 int snum, int *njobs) 2669 { 2670 const char *sharename = lp_const_servicename(snum); 2671 uint64_t dspace, dsize; 2672 uint64_t minspace; 2673 int ret; 2674 2675 if (!print_access_check(server_info, msg_ctx, snum, 2676 PRINTER_ACCESS_USE)) { 2677 DEBUG(3, ("print_job_checks: " 2678 "job start denied by security descriptor\n")); 2679 return WERR_ACCESS_DENIED; 2680 } 2681 2682 if (!print_time_access_check(server_info, msg_ctx, sharename)) { 2683 DEBUG(3, ("print_job_checks: " 2684 "job start denied by time check\n")); 2685 return WERR_ACCESS_DENIED; 2686 } 2687 2688 /* see if we have sufficient disk space */ 2689 if (lp_minprintspace(snum)) { 2690 minspace = lp_minprintspace(snum); 2691 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize); 2692 if (ret == 0 && dspace < 2*minspace) { 2693 DEBUG(3, ("print_job_checks: " 2694 "disk space check failed.\n")); 2695 return WERR_NO_SPOOL_SPACE; 2696 } 2697 } 2698 2699 /* for autoloaded printers, check that the printcap entry still exists */ 2700 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) { 2701 DEBUG(3, ("print_job_checks: printer name %s check failed.\n", 2702 sharename)); 2703 return WERR_ACCESS_DENIED; 2704 } 2705 2706 /* Insure the maximum queue size is not violated */ 2707 *njobs = print_queue_length(msg_ctx, snum, NULL); 2708 if (*njobs > lp_maxprintjobs(snum)) { 2709 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) " 2710 "larger than max printjobs per queue (%d).\n", 2711 sharename, *njobs, lp_maxprintjobs(snum))); 2712 return WERR_NO_SPOOL_SPACE; 2713 } 2714 2715 return WERR_OK; 2716 } 2717 2718 /*************************************************************************** 2719 Create a job file. 2720 ***************************************************************************/ 2721 2722 static WERROR print_job_spool_file(int snum, uint32_t jobid, 2723 const char *output_file, 2724 struct printjob *pjob) 2725 { 2726 WERROR werr; 2727 SMB_STRUCT_STAT st; 2728 const char *path; 2729 int len; 2730 2731 /* if this file is within the printer path, it means that smbd 2732 * is spooling it and will pass us control when it is finished. 2733 * Verify that the file name is ok, within path, and it is 2734 * already already there */ 2735 if (output_file) { 2736 path = lp_pathname(snum); 2737 len = strlen(path); 2738 if (strncmp(output_file, path, len) == 0 && 2739 (output_file[len - 1] == '/' || output_file[len] == '/')) { 2740 2741 /* verify path is not too long */ 2742 if (strlen(output_file) >= sizeof(pjob->filename)) { 2743 return WERR_INVALID_NAME; 2744 } 2745 2746 /* verify that the file exists */ 2747 if (sys_stat(output_file, &st, false) != 0) { 2748 return WERR_INVALID_NAME; 2749 } 2750 2751 fstrcpy(pjob->filename, output_file); 2752 2753 DEBUG(3, ("print_job_spool_file:" 2754 "External spooling activated")); 2755 2756 /* we do not open the file until spooling is done */ 2757 pjob->fd = -1; 2758 pjob->status = PJOB_SMBD_SPOOLING; 2759 2760 return WERR_OK; 2761 } 2762 } 2763 2764 slprintf(pjob->filename, sizeof(pjob->filename)-1, 2765 "%s/%s%.8u.XXXXXX", lp_pathname(snum), 2766 PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2767 pjob->fd = mkstemp(pjob->filename); 2768 2769 if (pjob->fd == -1) { 2770 werr = map_werror_from_unix(errno); 2771 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) { 2772 /* Common setup error, force a report. */ 2773 DEBUG(0, ("print_job_spool_file: " 2774 "insufficient permissions to open spool " 2775 "file %s.\n", pjob->filename)); 2776 } else { 2777 /* Normal case, report at level 3 and above. */ 2778 DEBUG(3, ("print_job_spool_file: " 2779 "can't open spool file %s\n", 2780 pjob->filename)); 2781 } 2782 return werr; 2783 } 2784 2785 return WERR_OK; 2390 2786 } 2391 2787 … … 2394 2790 ***************************************************************************/ 2395 2791 2396 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum, 2397 const char *jobname, NT_DEVICEMODE *nt_devmode ) 2398 { 2399 uint32 jobid; 2792 WERROR print_job_start(const struct auth_serversupplied_info *server_info, 2793 struct messaging_context *msg_ctx, 2794 const char *clientmachine, 2795 int snum, const char *docname, const char *filename, 2796 struct spoolss_DeviceMode *devmode, uint32_t *_jobid) 2797 { 2798 uint32_t jobid; 2400 2799 char *path; 2401 2800 struct printjob pjob; … … 2403 2802 struct tdb_print_db *pdb = get_print_db_byname(sharename); 2404 2803 int njobs; 2405 2406 errno = 0; 2407 2408 if (!pdb) 2409 return (uint32)-1; 2410 2411 if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) { 2412 DEBUG(3, ("print_job_start: job start denied by security descriptor\n")); 2804 WERROR werr; 2805 2806 if (!pdb) { 2807 return WERR_INTERNAL_DB_CORRUPTION; 2808 } 2809 2810 path = lp_pathname(snum); 2811 2812 werr = print_job_checks(server_info, msg_ctx, snum, &njobs); 2813 if (!W_ERROR_IS_OK(werr)) { 2413 2814 release_print_db(pdb); 2414 return (uint32)-1; 2415 } 2416 2417 if (!print_time_access_check(lp_servicename(snum))) { 2418 DEBUG(3, ("print_job_start: job start denied by time check\n")); 2419 release_print_db(pdb); 2420 return (uint32)-1; 2421 } 2422 2423 path = lp_pathname(snum); 2424 2425 /* see if we have sufficient disk space */ 2426 if (lp_minprintspace(snum)) { 2427 uint64_t dspace, dsize; 2428 if (sys_fsusage(path, &dspace, &dsize) == 0 && 2429 dspace < 2*(uint64_t)lp_minprintspace(snum)) { 2430 DEBUG(3, ("print_job_start: disk space check failed.\n")); 2431 release_print_db(pdb); 2432 errno = ENOSPC; 2433 return (uint32)-1; 2434 } 2435 } 2436 2437 /* for autoloaded printers, check that the printcap entry still exists */ 2438 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) { 2439 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) )); 2440 release_print_db(pdb); 2441 errno = ENOENT; 2442 return (uint32)-1; 2443 } 2444 2445 /* Insure the maximum queue size is not violated */ 2446 if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) { 2447 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n", 2448 sharename, njobs, lp_maxprintjobs(snum) )); 2449 release_print_db(pdb); 2450 errno = ENOSPC; 2451 return (uint32)-1; 2452 } 2453 2454 DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n", 2455 sharename, njobs, lp_maxprintjobs(snum) )); 2456 2457 if (!allocate_print_jobid(pdb, snum, sharename, &jobid)) 2815 return werr; 2816 } 2817 2818 DEBUG(10, ("print_job_start: " 2819 "Queue %s number of jobs (%d), max printjobs = %d\n", 2820 sharename, njobs, lp_maxprintjobs(snum))); 2821 2822 werr = allocate_print_jobid(pdb, snum, sharename, &jobid); 2823 if (!W_ERROR_IS_OK(werr)) { 2458 2824 goto fail; 2825 } 2459 2826 2460 2827 /* create the database entry */ … … 2470 2837 pjob.spooled = False; 2471 2838 pjob.smbjob = True; 2472 pjob.nt_devmode = nt_devmode; 2473 2474 fstrcpy(pjob.jobname, jobname); 2839 pjob.devmode = devmode; 2840 2841 fstrcpy(pjob.jobname, docname); 2842 2843 fstrcpy(pjob.clientmachine, clientmachine); 2475 2844 2476 2845 fstrcpy(pjob.user, lp_printjob_username(snum)); … … 2478 2847 path, server_info->utok.gid, 2479 2848 server_info->sanitized_username, 2480 pdb_get_domain(server_info->sam_account),2849 server_info->info3->base.domain.string, 2481 2850 pjob.user, sizeof(pjob.user)-1); 2482 2851 /* ensure NULL termination */ … … 2486 2855 2487 2856 /* we have a job entry - now create the spool file */ 2488 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 2489 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); 2490 pjob.fd = mkstemp(pjob.filename); 2491 2492 if (pjob.fd == -1) { 2493 if (errno == EACCES) { 2494 /* Common setup error, force a report. */ 2495 DEBUG(0, ("print_job_start: insufficient permissions \ 2496 to open spool file %s.\n", pjob.filename)); 2497 } else { 2498 /* Normal case, report at level 3 and above. */ 2499 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename)); 2500 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno))); 2501 } 2857 werr = print_job_spool_file(snum, jobid, filename, &pjob); 2858 if (!W_ERROR_IS_OK(werr)) { 2502 2859 goto fail; 2503 2860 } 2504 2861 2505 pjob_store(s harename, jobid, &pjob);2506 2507 /* Update the 'jobs changed' entry used by print_queue_status. */2508 add_to_jobs_ changed(pdb, jobid);2862 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob); 2863 2864 /* Update the 'jobs added' entry used by print_queue_status. */ 2865 add_to_jobs_added(pdb, jobid); 2509 2866 2510 2867 /* Ensure we keep a rough count of the number of total jobs... */ … … 2513 2870 release_print_db(pdb); 2514 2871 2515 return jobid; 2516 2517 fail: 2518 if (jobid != -1) 2519 pjob_delete(sharename, jobid); 2872 *_jobid = jobid; 2873 return WERR_OK; 2874 2875 fail: 2876 if (jobid != -1) { 2877 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2878 } 2520 2879 2521 2880 release_print_db(pdb); 2522 2881 2523 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) )); 2524 return (uint32)-1; 2882 DEBUG(3, ("print_job_start: returning fail. " 2883 "Error = %s\n", win_errstr(werr))); 2884 return werr; 2525 2885 } 2526 2886 … … 2529 2889 ****************************************************************************/ 2530 2890 2531 void print_job_endpage(int snum, uint32 jobid) 2891 void print_job_endpage(struct messaging_context *msg_ctx, 2892 int snum, uint32 jobid) 2532 2893 { 2533 2894 const char* sharename = lp_const_servicename(snum); … … 2542 2903 2543 2904 pjob->page_count++; 2544 pjob_store(s harename, jobid, pjob);2905 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2545 2906 } 2546 2907 … … 2551 2912 ****************************************************************************/ 2552 2913 2553 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) 2914 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum, 2915 uint32 jobid, enum file_close_type close_type) 2554 2916 { 2555 2917 const char* sharename = lp_const_servicename(snum); … … 2558 2920 SMB_STRUCT_STAT sbuf; 2559 2921 struct printif *current_printif = get_printer_fns( snum ); 2922 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 2560 2923 2561 2924 pjob = print_job_find(sharename, jobid); 2562 2925 2563 if (!pjob) 2564 return False; 2565 2566 if (pjob->spooled || pjob->pid != sys_getpid()) 2567 return False; 2568 2569 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && 2570 (sys_fstat(pjob->fd, &sbuf, false) == 0)) { 2926 if (!pjob) { 2927 return NT_STATUS_PRINT_CANCELLED; 2928 } 2929 2930 if (pjob->spooled || pjob->pid != sys_getpid()) { 2931 return NT_STATUS_ACCESS_DENIED; 2932 } 2933 2934 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) { 2935 if (pjob->status == PJOB_SMBD_SPOOLING) { 2936 /* take over the file now, smbd is done */ 2937 if (sys_stat(pjob->filename, &sbuf, false) != 0) { 2938 status = map_nt_error_from_unix(errno); 2939 DEBUG(3, ("print_job_end: " 2940 "stat file failed for jobid %d\n", 2941 jobid)); 2942 goto fail; 2943 } 2944 2945 pjob->status = LPQ_SPOOLING; 2946 2947 } else { 2948 2949 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) { 2950 status = map_nt_error_from_unix(errno); 2951 close(pjob->fd); 2952 DEBUG(3, ("print_job_end: " 2953 "stat file failed for jobid %d\n", 2954 jobid)); 2955 goto fail; 2956 } 2957 2958 close(pjob->fd); 2959 } 2960 2571 2961 pjob->size = sbuf.st_ex_size; 2572 close(pjob->fd);2573 pjob->fd = -1;2574 2962 } else { 2575 2963 2576 2964 /* 2577 * Not a normal close or we couldn't stat the job file, 2578 * so something has gone wrong. Cleanup. 2965 * Not a normal close, something has gone wrong. Cleanup. 2579 2966 */ 2580 close(pjob->fd);2581 pjob->fd = -1;2582 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));2967 if (pjob->fd != -1) { 2968 close(pjob->fd); 2969 } 2583 2970 goto fail; 2584 2971 } … … 2592 2979 pjob->filename, pjob->size ? "deleted" : "zero length" )); 2593 2980 unlink(pjob->filename); 2594 pjob_delete(s harename, jobid);2595 return True;2981 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 2982 return NT_STATUS_OK; 2596 2983 } 2597 2984 2598 2985 ret = (*(current_printif->job_submit))(snum, pjob); 2599 2986 2600 if (ret) 2987 if (ret) { 2988 status = NT_STATUS_PRINT_CANCELLED; 2601 2989 goto fail; 2990 } 2602 2991 2603 2992 /* The print job has been successfully handed over to the back-end */ … … 2605 2994 pjob->spooled = True; 2606 2995 pjob->status = LPQ_QUEUED; 2607 pjob_store(s harename, jobid, pjob);2996 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob); 2608 2997 2609 2998 /* make sure the database is up to date */ 2610 2999 if (print_cache_expired(lp_const_servicename(snum), True)) 2611 print_queue_update( snum, False);2612 2613 return True;3000 print_queue_update(msg_ctx, snum, False); 3001 3002 return NT_STATUS_OK; 2614 3003 2615 3004 fail: … … 2617 3006 /* The print job was not successfully started. Cleanup */ 2618 3007 /* Still need to add proper error return propagation! 010122:JRR */ 3008 pjob->fd = -1; 2619 3009 unlink(pjob->filename); 2620 pjob_delete(s harename, jobid);2621 return False;3010 pjob_delete(server_event_context(), msg_ctx, sharename, jobid); 3011 return status; 2622 3012 } 2623 3013 … … 2626 3016 ****************************************************************************/ 2627 3017 2628 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) 2629 { 2630 TDB_DATA data, cgdata; 3018 static bool get_stored_queue_info(struct messaging_context *msg_ctx, 3019 struct tdb_print_db *pdb, int snum, 3020 int *pcount, print_queue_struct **ppqueue) 3021 { 3022 TDB_DATA data, cgdata, jcdata; 2631 3023 print_queue_struct *queue = NULL; 2632 3024 uint32 qcount = 0; 2633 3025 uint32 extra_count = 0; 3026 uint32_t changed_count = 0; 2634 3027 int total_count = 0; 2635 3028 size_t len = 0; … … 2641 3034 /* make sure the database is up to date */ 2642 3035 if (print_cache_expired(lp_const_servicename(snum), True)) 2643 print_queue_update( snum, False);3036 print_queue_update(msg_ctx, snum, False); 2644 3037 2645 3038 *pcount = 0; … … 2655 3048 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); 2656 3049 2657 /* Get the changed jobs list. */2658 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_ changed"));3050 /* Get the added jobs list. */ 3051 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); 2659 3052 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) 2660 3053 extra_count = cgdata.dsize/4; 3054 3055 /* Get the changed jobs list. */ 3056 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); 3057 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0)) 3058 changed_count = jcdata.dsize / 4; 2661 3059 2662 3060 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count)); … … 2692 3090 total_count = qcount; 2693 3091 2694 /* Add in the changed jobids. */3092 /* Add new jobids to the queue. */ 2695 3093 for( i = 0; i < extra_count; i++) { 2696 3094 uint32 jobid; … … 2698 3096 2699 3097 jobid = IVAL(cgdata.dptr, i*4); 2700 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));3098 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid)); 2701 3099 pjob = print_job_find(lp_const_servicename(snum), jobid); 2702 3100 if (!pjob) { 2703 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));2704 remove_from_jobs_ changed(sharename, jobid);3101 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid)); 3102 remove_from_jobs_added(sharename, jobid); 2705 3103 continue; 2706 3104 } … … 2717 3115 } 2718 3116 3117 /* Update the changed jobids. */ 3118 for (i = 0; i < changed_count; i++) { 3119 uint32_t jobid = IVAL(jcdata.dptr, i * 4); 3120 uint32_t j; 3121 bool found = false; 3122 3123 for (j = 0; j < total_count; j++) { 3124 if (queue[j].job == jobid) { 3125 found = true; 3126 break; 3127 } 3128 } 3129 3130 if (found) { 3131 struct printjob *pjob; 3132 3133 DEBUG(5,("get_stored_queue_info: changed job: %u\n", 3134 (unsigned int) jobid)); 3135 3136 pjob = print_job_find(sharename, jobid); 3137 if (pjob == NULL) { 3138 DEBUG(5,("get_stored_queue_info: failed to find " 3139 "changed job = %u\n", 3140 (unsigned int) jobid)); 3141 remove_from_jobs_changed(sharename, jobid); 3142 continue; 3143 } 3144 3145 queue[j].job = jobid; 3146 queue[j].size = pjob->size; 3147 queue[j].page_count = pjob->page_count; 3148 queue[j].status = pjob->status; 3149 queue[j].priority = 1; 3150 queue[j].time = pjob->starttime; 3151 fstrcpy(queue[j].fs_user, pjob->user); 3152 fstrcpy(queue[j].fs_file, pjob->jobname); 3153 3154 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n", 3155 (unsigned int) j, (unsigned int) jobid, pjob->jobname)); 3156 } 3157 3158 remove_from_jobs_changed(sharename, jobid); 3159 } 3160 2719 3161 /* Sort the queue by submission time otherwise they are displayed 2720 3162 in hash order. */ 2721 3163 2722 qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));3164 TYPESAFE_QSORT(queue, total_count, printjob_comp); 2723 3165 2724 3166 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count)); … … 2744 3186 ****************************************************************************/ 2745 3187 2746 int print_queue_status( int snum,3188 int print_queue_status(struct messaging_context *msg_ctx, int snum, 2747 3189 print_queue_struct **ppqueue, 2748 3190 print_status_struct *status) … … 2757 3199 2758 3200 if (print_cache_expired(lp_const_servicename(snum), True)) 2759 print_queue_update( snum, False);3201 print_queue_update(msg_ctx, snum, False); 2760 3202 2761 3203 /* return if we are done */ … … 2794 3236 */ 2795 3237 2796 if (!get_stored_queue_info( pdb, snum, &count, ppqueue)) {3238 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) { 2797 3239 release_print_db(pdb); 2798 3240 return 0; … … 2807 3249 ****************************************************************************/ 2808 3250 2809 WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum) 3251 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info, 3252 struct messaging_context *msg_ctx, int snum) 2810 3253 { 2811 3254 int ret; 2812 3255 struct printif *current_printif = get_printer_fns( snum ); 2813 3256 2814 if (!print_access_check(server_info, snum,3257 if (!print_access_check(server_info, msg_ctx, snum, 2815 3258 PRINTER_ACCESS_ADMINISTER)) { 2816 3259 return WERR_ACCESS_DENIED; … … 2833 3276 /* Send a printer notify message */ 2834 3277 2835 notify_printer_status(snum, PRINTER_STATUS_PAUSED); 3278 notify_printer_status(server_event_context(), msg_ctx, snum, 3279 PRINTER_STATUS_PAUSED); 2836 3280 2837 3281 return WERR_OK; … … 2842 3286 ****************************************************************************/ 2843 3287 2844 WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum) 3288 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info, 3289 struct messaging_context *msg_ctx, int snum) 2845 3290 { 2846 3291 int ret; 2847 3292 struct printif *current_printif = get_printer_fns( snum ); 2848 3293 2849 if (!print_access_check(server_info, snum,3294 if (!print_access_check(server_info, msg_ctx, snum, 2850 3295 PRINTER_ACCESS_ADMINISTER)) { 2851 3296 return WERR_ACCESS_DENIED; … … 2864 3309 /* make sure the database is up to date */ 2865 3310 if (print_cache_expired(lp_const_servicename(snum), True)) 2866 print_queue_update( snum, True);3311 print_queue_update(msg_ctx, snum, True); 2867 3312 2868 3313 /* Send a printer notify message */ 2869 3314 2870 notify_printer_status(snum, PRINTER_STATUS_OK); 3315 notify_printer_status(server_event_context(), msg_ctx, snum, 3316 PRINTER_STATUS_OK); 2871 3317 2872 3318 return WERR_OK; … … 2877 3323 ****************************************************************************/ 2878 3324 2879 WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum) 3325 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info, 3326 struct messaging_context *msg_ctx, int snum) 2880 3327 { 2881 3328 print_queue_struct *queue; … … 2885 3332 2886 3333 /* Force and update so the count is accurate (i.e. not a cached count) */ 2887 print_queue_update(snum, True); 2888 2889 can_job_admin = print_access_check(server_info, snum, 3334 print_queue_update(msg_ctx, snum, True); 3335 3336 can_job_admin = print_access_check(server_info, 3337 msg_ctx, 3338 snum, 2890 3339 JOB_ACCESS_ADMINISTER); 2891 njobs = print_queue_status( snum, &queue, &status);3340 njobs = print_queue_status(msg_ctx, snum, &queue, &status); 2892 3341 2893 3342 if ( can_job_admin ) … … 2899 3348 2900 3349 if (owner || can_job_admin) { 2901 print_job_delete1(snum, queue[i].job); 3350 print_job_delete1(server_event_context(), msg_ctx, 3351 snum, queue[i].job); 2902 3352 } 2903 3353 } … … 2907 3357 2908 3358 /* update the cache */ 2909 print_queue_update( snum, True);3359 print_queue_update(msg_ctx, snum, True); 2910 3360 2911 3361 SAFE_FREE(queue); -
trunk/server/source3/printing/printing_db.c
r414 r745 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; -
trunk/server/source3/printing/tests/vlp.c
r414 r745 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.