Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source3/printing
Files:
17 added
1 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/printing/load.c

    r597 r740  
    1919
    2020#include "includes.h"
    21 
     21#include "printing/pcap.h"
     22#include "printing/load.h"
    2223
    2324/***************************************************************************
     
    5657load automatic printer services from pre-populated pcap cache
    5758***************************************************************************/
    58 void load_printers(void)
     59void load_printers(struct tevent_context *ev,
     60                   struct messaging_context *msg_ctx)
    5961{
     62        SMB_ASSERT(pcap_cache_loaded());
     63
    6064        add_auto_printers();
    6165
  • vendor/current/source3/printing/notify.c

    r414 r740  
    2222#include "includes.h"
    2323#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"
    2429
    2530static TALLOC_CTX *send_ctx;
     
    228233                                             void *private_data)
    229234{
     235        struct messaging_context *msg_ctx = talloc_get_type_abort(
     236                private_data, struct messaging_context);
    230237        /* Remove this timed event handler. */
    231238        TALLOC_FREE(notify_event);
    232239
    233240        change_to_root_user();
    234         print_notify_send_messages(smbd_messaging_context(), 0);
     241        print_notify_send_messages(msg_ctx, 0);
    235242}
    236243
     
    263270*******************************************************************/
    264271
    265 static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg)
     272static void send_spoolss_notify2_msg(struct tevent_context *ev,
     273                                     struct messaging_context *msg_ctx,
     274                                     SPOOLSS_NOTIFY_MSG *msg)
    266275{
    267276        struct notify_queue *pnqueue, *tmp_ptr;
     
    326335        num_messages++;
    327336
    328         if ((notify_event == NULL) && (smbd_event_context() != NULL)) {
     337        if ((notify_event == NULL) && (ev != NULL)) {
    329338                /* 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
     346static void send_notify_field_values(struct tevent_context *ev,
     347                                     struct messaging_context *msg_ctx,
     348                                     const char *sharename, uint32 type,
    338349                                     uint32 field, uint32 id, uint32 value1,
    339350                                     uint32 value2, uint32 flags)
     
    361372        msg->flags = flags;
    362373
    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
     377static void send_notify_field_buffer(struct tevent_context *ev,
     378                                     struct messaging_context *msg_ctx,
     379                                     const char *sharename, uint32 type,
    367380                                     uint32 field, uint32 id, uint32 len,
    368381                                     const char *buffer)
     
    389402        msg->notify.data = CONST_DISCARD(char *,buffer);
    390403
    391         send_spoolss_notify2_msg(msg);
     404        send_spoolss_notify2_msg(ev, msg_ctx, msg);
    392405}
    393406
    394407/* Send a message that the printer status has changed */
    395408
    396 void notify_printer_status_byname(const char *sharename, uint32 status)
     409void notify_printer_status_byname(struct tevent_context *ev,
     410                                  struct messaging_context *msg_ctx,
     411                                  const char *sharename, uint32 status)
    397412{
    398413        /* Printer status stored in value1 */
     
    400415        int snum = print_queue_snum(sharename);
    401416
    402         send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE,
     417        send_notify_field_values(ev, msg_ctx, sharename, PRINTER_NOTIFY_TYPE,
    403418                                 PRINTER_NOTIFY_FIELD_STATUS, snum,
    404419                                 status, 0, 0);
    405420}
    406421
    407 void notify_printer_status(int snum, uint32 status)
    408 {
    409         const char *sharename = SERVICE(snum);
     422void 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);
    410427
    411428        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
     432void notify_job_status_byname(struct tevent_context *ev,
     433                              struct messaging_context *msg_ctx,
     434                              const char *sharename, uint32 jobid,
     435                              uint32 status,
    416436                              uint32 flags)
    417437{
    418438        /* Job id stored in id field, status in value1 */
    419439
    420         send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
     440        send_notify_field_values(ev, msg_ctx,
     441                                 sharename, JOB_NOTIFY_TYPE,
    421442                                 JOB_NOTIFY_FIELD_STATUS, jobid,
    422443                                 status, 0, flags);
    423444}
    424445
    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,
     446void 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
     453void notify_job_total_bytes(struct tevent_context *ev,
     454                            struct messaging_context *msg_ctx,
     455                            const char *sharename, uint32 jobid,
    431456                            uint32 size)
    432457{
    433458        /* Job id stored in id field, status in value1 */
    434459
    435         send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
     460        send_notify_field_values(ev, msg_ctx,
     461                                 sharename, JOB_NOTIFY_TYPE,
    436462                                 JOB_NOTIFY_FIELD_TOTAL_BYTES, jobid,
    437463                                 size, 0, 0);
    438464}
    439465
    440 void notify_job_total_pages(const char *sharename, uint32 jobid,
     466void notify_job_total_pages(struct tevent_context *ev,
     467                            struct messaging_context *msg_ctx,
     468                            const char *sharename, uint32 jobid,
    441469                            uint32 pages)
    442470{
    443471        /* Job id stored in id field, status in value1 */
    444472
    445         send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
     473        send_notify_field_values(ev, msg_ctx,
     474                                 sharename, JOB_NOTIFY_TYPE,
    446475                                 JOB_NOTIFY_FIELD_TOTAL_PAGES, jobid,
    447476                                 pages, 0, 0);
    448477}
    449478
    450 void notify_job_username(const char *sharename, uint32 jobid, char *name)
    451 {
    452         send_notify_field_buffer(
     479void 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,
    453485                sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME,
    454486                jobid, strlen(name) + 1, name);
    455487}
    456488
    457 void notify_job_name(const char *sharename, uint32 jobid, char *name)
    458 {
    459         send_notify_field_buffer(
     489void 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,
    460495                sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT,
    461496                jobid, strlen(name) + 1, name);
    462497}
    463498
    464 void notify_job_submitted(const char *sharename, uint32 jobid,
     499void notify_job_submitted(struct tevent_context *ev,
     500                          struct messaging_context *msg_ctx,
     501                          const char *sharename, uint32 jobid,
    465502                          time_t submitted)
    466503{
    467504        send_notify_field_buffer(
     505                ev, msg_ctx,
    468506                sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED,
    469507                jobid, sizeof(submitted), (char *)&submitted);
    470508}
    471509
    472 void notify_printer_driver(int snum, char *driver_name)
    473 {
    474         const char *sharename = SERVICE(snum);
    475 
    476         send_notify_field_buffer(
     510void 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,
    477518                sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,
    478519                snum, strlen(driver_name) + 1, driver_name);
    479520}
    480521
    481 void notify_printer_comment(int snum, char *comment)
    482 {
    483         const char *sharename = SERVICE(snum);
    484 
    485         send_notify_field_buffer(
     522void 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,
    486530                sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,
    487531                snum, strlen(comment) + 1, comment);
    488532}
    489533
    490 void notify_printer_sharename(int snum, char *share_name)
    491 {
    492         const char *sharename = SERVICE(snum);
    493 
    494         send_notify_field_buffer(
     534void 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,
    495542                sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,
    496543                snum, strlen(share_name) + 1, share_name);
    497544}
    498545
    499 void notify_printer_printername(int snum, char *printername)
    500 {
    501         const char *sharename = SERVICE(snum);
    502 
    503         send_notify_field_buffer(
     546void 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,
    504554                sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,
    505555                snum, strlen(printername) + 1, printername);
    506556}
    507557
    508 void notify_printer_port(int snum, char *port_name)
    509 {
    510         const char *sharename = SERVICE(snum);
    511 
    512         send_notify_field_buffer(
     558void 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,
    513566                sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,
    514567                snum, strlen(port_name) + 1, port_name);
    515568}
    516569
    517 void notify_printer_location(int snum, char *location)
    518 {
    519         const char *sharename = SERVICE(snum);
    520 
    521         send_notify_field_buffer(
     570void 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,
    522578                sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,
    523579                snum, strlen(location) + 1, location);
    524580}
    525581
    526 void notify_printer_byname( const char *printername, uint32 change, const char *value )
     582void 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
     595void notify_printer_byname(struct tevent_context *ev,
     596                           struct messaging_context *msg_ctx,
     597                           const char *printername, uint32 change,
     598                           const char *value)
    527599{
    528600        int snum = print_queue_snum(printername);
     
    532604                return;
    533605               
    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 );
    535609}
    536610
  • vendor/current/source3/printing/nt_printing.c

    r597 r740  
    2121
    2222#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"
    4036
    4137/* Map generic permissions to printer object specific permissions */
     
    4844};
    4945
    50 const struct standard_mapping printer_std_mapping = {
    51         PRINTER_READ,
    52         PRINTER_WRITE,
    53         PRINTER_EXECUTE,
    54         PRINTER_ALL_ACCESS
    55 };
    56 
    5746/* Map generic permissions to print server object specific permissions */
    5847
     
    6453};
    6554
    66 const struct generic_mapping printserver_std_mapping = {
    67         SERVER_READ,
    68         SERVER_WRITE,
    69         SERVER_EXECUTE,
    70         SERVER_ALL_ACCESS
    71 };
    72 
    7355/* Map generic permissions to job object specific permissions */
    7456
     
    7860        JOB_EXECUTE,
    7961        JOB_ALL_ACCESS
    80 };
    81 
    82 /* We need one default form to support our default printer. Msoft adds the
    83 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
    84 array index). Letter is always first, so (for the current code) additions
    85 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}
    20562};
    20663
     
    21774};
    21875
    219 
    220 /****************************************************************************
    221  generate a new TDB_DATA key for storing a printer
    222 ****************************************************************************/
    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 descriptor
    241 ****************************************************************************/
    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 must
    323  use more than the generic bits that were previously used
    324  in <= 3.0.14a.  They must also have a owner and group SID assigned.
    325  Otherwise, any printers than have been migrated to a Windows
    326  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 must
    450  use more than the generic bits that were previously used
    451  in <= 3.0.14a.  They must also have a owner and group SID assigned.
    452  Otherwise, any printers than have been migrated to a Windows
    453  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 
    51576/****************************************************************************
    51677 Open the NT printing tdbs. Done once before fork().
     
    51980bool nt_printing_init(struct messaging_context *msg_ctx)
    52081{
    521         const char *vstring = "INFO/version";
    52282        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        }
    60287
    60388        /*
     
    60590         * drivers are installed
    60691         */
    607 
    60892        messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
    60993                           do_drv_upgrade_printer);
    61094
    611         /*
    612          * register callback to handle updating printer data
    613          * when a driver is initialized
    614          */
    615 
    616         messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,
    617                            reset_all_printerdata);
    618 
    61995        /* of course, none of the message callbacks matter if you don't
    62096           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() */
    62398
    62499        if ( lp_security() == SEC_ADS ) {
    625                 win_rc = check_published_printers();
     100                win_rc = check_published_printers(msg_ctx);
    626101                if (!W_ERROR_IS_OK(win_rc))
    627102                        DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
    628103        }
    629104
    630         return True;
     105        return true;
    631106}
    632107
     
    661136}
    662137
    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 initialized
    682  when the parent smbd starts with the number of existing printers. It
    683  is monotonically increased by the current number of printers *after*
    684  each add or delete printer RPC. Only Microsoft knows why... JRR020119
    685 ********************************************************************/
    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 count
    698          * otherwise, bump it by the current printer count
    699          */
    700         if (!initialize)
    701                 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
    702         else
    703                 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 struct
    744 ****************************************************************************/
    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 list
    809 ****************************************************************************/
    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 list
    857 ****************************************************************************/
    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 when
    865          * they are already in the base
    866          * only update the values if already present
    867          */
    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 
    1006138/****************************************************************************
    1007139 Function to do the mapping between the long architecture name and
     
    1013145        int i=-1;
    1014146
    1015         DEBUG(107,("Getting architecture dependant directory\n"));
     147        DEBUG(107,("Getting architecture dependent directory\n"));
    1016148        do {
    1017149                i++;
     
    1316448                INTERNAL_OPEN_ONLY,                     /* oplock_request */
    1317449                0,                                      /* allocation_size */
     450                0,                                      /* private_flags */
    1318451                NULL,                                   /* sd */
    1319452                NULL,                                   /* ea_list */
     
    1368501                INTERNAL_OPEN_ONLY,                     /* oplock_request */
    1369502                0,                                      /* allocation_size */
     503                0,                                      /* private_flags */
    1370504                NULL,                                   /* sd */
    1371505                NULL,                                   /* ea_list */
     
    1441575Determine the correct cVersion associated with an architecture and driver
    1442576****************************************************************************/
    1443 static uint32 get_correct_cversion(struct pipes_struct *p,
     577static uint32 get_correct_cversion(struct auth_serversupplied_info *session_info,
    1444578                                   const char *architecture,
    1445579                                   const char *driverpath_in,
    1446580                                   WERROR *perr)
    1447581{
    1448         int               cversion;
     582        int cversion = -1;
    1449583        NTSTATUS          nt_status;
    1450584        struct smb_filename *smb_fname = NULL;
     
    1452586        files_struct      *fsp = NULL;
    1453587        connection_struct *conn = NULL;
    1454         NTSTATUS status;
    1455588        char *oldcwd;
    1456         fstring printdollar;
     589        char *printdollar = NULL;
    1457590        int printdollar_snum;
    1458591
     
    1473606        }
    1474607
    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        }
    1478613        if (printdollar_snum == -1) {
    1479614                *perr = WERR_NO_SUCH_SHARE;
     
    1483618        nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
    1484619                                       lp_pathname(printdollar_snum),
    1485                                        p->server_info, &oldcwd);
     620                                       session_info, &oldcwd);
    1486621        if (!NT_STATUS_IS_OK(nt_status)) {
    1487622                DEBUG(0,("get_correct_cversion: create_conn_struct "
     
    1489624                *perr = ntstatus_to_werror(nt_status);
    1490625                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;
    1491639        }
    1492640
     
    1510658        nt_status = vfs_file_exist(conn, smb_fname);
    1511659        if (!NT_STATUS_IS_OK(nt_status)) {
     660                DEBUG(3,("get_correct_cversion: vfs_file_exist failed\n"));
    1512661                *perr = WERR_BADFILE;
    1513662                goto error_exit;
    1514663        }
    1515664
    1516         status = SMB_VFS_CREATE_FILE(
     665        nt_status = SMB_VFS_CREATE_FILE(
    1517666                conn,                                   /* conn */
    1518667                NULL,                                   /* req */
     
    1525674                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
    1526675                INTERNAL_OPEN_ONLY,                     /* oplock_request */
     676                0,                                      /* private_flags */
    1527677                0,                                      /* allocation_size */
    1528678                NULL,                                   /* sd */
     
    1531681                NULL);                                  /* pinfo */
    1532682
    1533         if (!NT_STATUS_IS_OK(status)) {
     683        if (!NT_STATUS_IS_OK(nt_status)) {
    1534684                DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
    1535685                         "%d\n", smb_fname_str_dbg(smb_fname), errno));
     
    1542692
    1543693                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) {
    1547698                        DEBUG(6,("get_correct_cversion: Version info not "
    1548699                                 "found [%s]\n",
    1549700                                 smb_fname_str_dbg(smb_fname)));
     701                        *perr = WERR_INVALID_PARAM;
    1550702                        goto error_exit;
    1551703                }
     
    1579731        DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
    1580732                  smb_fname_str_dbg(smb_fname), cversion));
    1581 
    1582         goto done;
     733        *perr = WERR_OK;
    1583734
    1584735 error_exit:
    1585         cversion = -1;
    1586  done:
     736        unbecome_user();
     737 error_free_conn:
    1587738        TALLOC_FREE(smb_fname);
    1588739        if (fsp != NULL) {
     
    1591742        if (conn != NULL) {
    1592743                vfs_ChDir(conn, oldcwd);
     744                SMB_VFS_DISCONNECT(conn);
    1593745                conn_free(conn);
    1594746        }
    1595         if (cversion != -1) {
    1596                 *perr = WERR_OK;
    1597         }
     747        if (!NT_STATUS_IS_OK(*perr)) {
     748                cversion = -1;
     749        }
     750
    1598751        return cversion;
    1599752}
     
    1610763
    1611764static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
    1612                                            struct pipes_struct *rpc_pipe,
     765                                           struct auth_serversupplied_info *session_info,
    1613766                                           const char *architecture,
    1614767                                           const char **driver_path,
     
    1617770                                           const char **help_file,
    1618771                                           struct spoolss_StringArray *dependent_files,
    1619                                            uint32_t *version)
     772                                           enum spoolss_DriverOSVersion *version)
    1620773{
    1621774        const char *short_architecture;
     
    1670823         */
    1671824
    1672         *version = get_correct_cversion(rpc_pipe, short_architecture,
     825        *version = get_correct_cversion(session_info, short_architecture,
    1673826                                        *driver_path, &err);
    1674827        if (*version == -1) {
     
    1682835****************************************************************************/
    1683836
    1684 WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
     837WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
     838                              struct auth_serversupplied_info *session_info,
    1685839                              struct spoolss_AddDriverInfoCtr *r)
    1686840{
    1687841        switch (r->level) {
    1688842        case 3:
    1689                 return clean_up_driver_struct_level(r, rpc_pipe,
     843                return clean_up_driver_struct_level(mem_ctx, session_info,
    1690844                                                    r->info.info3->architecture,
    1691845                                                    &r->info.info3->driver_path,
     
    1696850                                                    &r->info.info3->version);
    1697851        case 6:
    1698                 return clean_up_driver_struct_level(r, rpc_pipe,
     852                return clean_up_driver_struct_level(mem_ctx, session_info,
    1699853                                                    r->info.info6->architecture,
    1700854                                                    &r->info.info6->driver_path,
     
    1731885
    1732886/****************************************************************************
    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 /****************************************************************************
    1759887****************************************************************************/
    1760888
     
    1827955}
    1828956
    1829 WERROR move_driver_to_download_area(struct pipes_struct *p,
    1830                                     struct spoolss_AddDriverInfoCtr *r,
    1831                                     WERROR *perr)
     957WERROR move_driver_to_download_area(struct auth_serversupplied_info *session_info,
     958                                    struct spoolss_AddDriverInfoCtr *r)
    1832959{
    1833960        struct spoolss_AddDriverInfo3 *driver;
     
    1842969        int ver = 0;
    1843970        char *oldcwd;
    1844         fstring printdollar;
     971        char *printdollar = NULL;
    1845972        int printdollar_snum;
    1846 
    1847         *perr = WERR_OK;
     973        WERROR err = WERR_OK;
    1848974
    1849975        switch (r->level) {
     
    1865991        }
    1866992
    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        }
    1870997        if (printdollar_snum == -1) {
    1871                 *perr = WERR_NO_SUCH_SHARE;
    1872998                return WERR_NO_SUCH_SHARE;
    1873999        }
     
    18751001        nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
    18761002                                       lp_pathname(printdollar_snum),
    1877                                        p->server_info, &oldcwd);
     1003                                       session_info, &oldcwd);
    18781004        if (!NT_STATUS_IS_OK(nt_status)) {
    18791005                DEBUG(0,("move_driver_to_download_area: create_conn_struct "
    18801006                         "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;
    18831022        }
    18841023
     
    18881027                                driver->version);
    18891028        if (!new_dir) {
    1890                 *perr = WERR_NOMEM;
     1029                err = WERR_NOMEM;
    18911030                goto err_exit;
    18921031        }
    18931032        nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
    18941033        if (!NT_STATUS_IS_OK(nt_status)) {
    1895                 *perr = WERR_NOMEM;
     1034                err = WERR_NOMEM;
    18961035                goto err_exit;
    18971036        }
     
    18991038        DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
    19001039
    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        }
    19021048
    19031049        /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
     
    19221068        if (driver->driver_path && strlen(driver->driver_path)) {
    19231069
    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)) {
    19341077                        goto err_exit;
    19351078                }
     
    19391082                if (!strequal(driver->data_file, driver->driver_path)) {
    19401083
    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)) {
    19511091                                goto err_exit;
    19521092                        }
     
    19581098                    !strequal(driver->config_file, driver->data_file)) {
    19591099
    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)) {
    19701107                                goto err_exit;
    19711108                        }
     
    19781115                    !strequal(driver->help_file, driver->config_file)) {
    19791116
    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)) {
    19901124                                goto err_exit;
    19911125                        }
     
    20061140                                }
    20071141
    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)) {
    20181149                                        goto err_exit;
    20191150                                }
     
    20231154        }
    20241155
    2025   err_exit:
     1156        err = WERR_OK;
     1157 err_exit:
     1158        unbecome_user();
     1159 err_free_conn:
    20261160        TALLOC_FREE(smb_dname);
    20271161
    20281162        if (conn != NULL) {
    20291163                vfs_ChDir(conn, oldcwd);
     1164                SMB_VFS_DISCONNECT(conn);
    20301165                conn_free(conn);
    20311166        }
    20321167
    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", &regval_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}
    48121170
    48131171/****************************************************************************
     
    48161174****************************************************************************/
    48171175
    4818 bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r)
     1176bool 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)
    48191180{
    48201181        int snum;
    48211182        int n_services = lp_numservices();
    4822         NT_PRINTER_INFO_LEVEL *printer = NULL;
    48231183        bool in_use = False;
     1184        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
     1185        WERROR result;
     1186        struct dcerpc_binding_handle *b = NULL;
    48241187
    48251188        if (!r) {
     
    48321195
    48331196        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)) {
    48351198                        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)) {
    48411219                        in_use = True;
    4842 
    4843                 free_a_printer( &printer, 2 );
     1220                }
     1221
     1222                TALLOC_FREE(pinfo2);
    48441223        }
    48451224
     
    48471226
    48481227        if ( in_use ) {
    4849                 struct spoolss_DriverInfo8 *d;
     1228                struct spoolss_DriverInfo8 *driver;
    48501229                WERROR werr;
    48511230
     
    48561235
    48571236                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;
    48741257                }
    48751258
     
    48791262                        /* it's ok to remove the driver, we have other architctures left */
    48801263                        in_use = False;
    4881                         free_a_printer_driver(d);
     1264                        talloc_free(driver);
    48821265                }
    48831266        }
     
    50311414
    50321415bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
     1416                                 const struct auth_serversupplied_info *session_info,
     1417                                 struct messaging_context *msg_ctx,
    50331418                                 struct spoolss_DriverInfo8 *info)
    50341419{
    50351420        int                             i;
    5036         int                             ndrivers;
    50371421        uint32                          version;
    5038         fstring                         *list = NULL;
    50391422        struct spoolss_DriverInfo8      *driver;
    50401423        bool in_use = false;
     1424        uint32_t num_drivers;
     1425        const char **drivers;
     1426        WERROR result;
     1427        struct dcerpc_binding_handle *b;
    50411428
    50421429        if ( !info )
     
    50471434        /* loop over all driver versions */
    50481435
    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"));
    50501437
    50511438        /* get the list of drivers */
    50521439
    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));
    50581457
    50591458        /* check each driver for overlap in files */
    50601459
    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]));
    50631462
    50641463                driver = NULL;
    50651464
    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);
    50681470                        return True;
    50691471                }
     
    50811483                }
    50821484
    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"));
    50891491
    50901492        return in_use;
     
    51151517****************************************************************************/
    51161518
    5117 static bool delete_driver_files(struct pipes_struct *rpc_pipe,
    5118                                 const struct spoolss_DriverInfo8 *r)
     1519bool delete_driver_files(const struct auth_serversupplied_info *session_info,
     1520                         const struct spoolss_DriverInfo8 *r)
    51191521{
    51201522        int i = 0;
     
    51241526        NTSTATUS nt_status;
    51251527        char *oldcwd;
    5126         fstring printdollar;
     1528        char *printdollar = NULL;
    51271529        int printdollar_snum;
    51281530        bool ret = false;
     
    51351537                r->driver_name, r->version));
    51361538
    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        }
    51401543        if (printdollar_snum == -1) {
    51411544                return false;
     
    51441547        nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
    51451548                                       lp_pathname(printdollar_snum),
    5146                                        rpc_pipe->server_info, &oldcwd);
     1549                                       session_info, &oldcwd);
    51471550        if (!NT_STATUS_IS_OK(nt_status)) {
    51481551                DEBUG(0,("delete_driver_files: create_conn_struct "
     
    51511554        }
    51521555
     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
    51531569        if ( !CAN_WRITE(conn) ) {
    51541570                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;
    51561573        }
    51571574
     
    52091626        }
    52101627
    5211         goto done;
    5212  fail:
    5213         ret = false;
    5214  done:
     1628        ret = true;
     1629 err_out:
     1630        unbecome_user();
     1631 err_free_conn:
    52151632        if (conn != NULL) {
    52161633                vfs_ChDir(conn, oldcwd);
     1634                SMB_VFS_DISCONNECT(conn);
    52171635                conn_free(conn);
    52181636        }
    52191637        return ret;
    5220 }
    5221 
    5222 /****************************************************************************
    5223  Remove a printer driver from the TDB.  This assumes that the the driver was
    5224  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 == True
    5270          * even if this part failes, we return succes because the
    5271          * driver doesn not exist any more
    5272          */
    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 not
    5303            present when new ACEs are added or removed by changing printer
    5304            permissions through NT.  If they are NULL in the new security
    5305            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 one
    5447            created by NT when setting ACE entries in printer
    5448            descriptors.  NT4 complains about the property being edited by a
    5449            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 was
    5519            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;
    55771638}
    55781639
     
    56171678   NT5 the object specific ones. */
    56181679
    5619 void map_printer_permissions(SEC_DESC *sd)
     1680void map_printer_permissions(struct security_descriptor *sd)
    56201681{
    56211682        int i;
     
    56271688}
    56281689
    5629 void map_job_permissions(SEC_DESC *sd)
     1690void map_job_permissions(struct security_descriptor *sd)
    56301691{
    56311692        int i;
     
    56611722
    56621723 ****************************************************************************/
    5663 bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
     1724bool print_access_check(const struct auth_serversupplied_info *session_info,
     1725                        struct messaging_context *msg_ctx, int snum,
    56641726                        int access_type)
    56651727{
    5666         SEC_DESC_BUF *secdesc = NULL;
     1728        struct spoolss_security_descriptor *secdesc = NULL;
    56671729        uint32 access_granted;
     1730        size_t sd_size;
    56681731        NTSTATUS status;
     1732        WERROR result;
    56691733        const char *pname;
    56701734        TALLOC_CTX *mem_ctx = NULL;
    5671         SE_PRIV se_printop = SE_PRINT_OPERATOR;
    56721735
    56731736        /* If user is NULL then use the current_user structure */
     
    56751738        /* Always allow root or SE_PRINT_OPERATROR to do anything */
    56761739
    5677         if (server_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)) {
    56791742                return True;
    56801743        }
     
    56821745        /* Get printer name */
    56831746
    5684         pname = PRINTERNAME(snum);
     1747        pname = lp_printername(snum);
    56851748
    56861749        if (!pname || !*pname) {
     
    56961759        }
    56971760
    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)) {
    56991767                talloc_destroy(mem_ctx);
    57001768                errno = ENOMEM;
     
    57031771
    57041772        if (access_type == JOB_ACCESS_ADMINISTER) {
    5705                 SEC_DESC_BUF *parent_secdesc = secdesc;
     1773                struct spoolss_security_descriptor *parent_secdesc = secdesc;
    57061774
    57071775                /* Create a child security descriptor to check permissions
    57081776                   against.  This is because print jobs are child objects
    57091777                   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);
    57131785                if (!NT_STATUS_IS_OK(status)) {
    57141786                        talloc_destroy(mem_ctx);
     
    57171789                }
    57181790
    5719                 map_job_permissions(secdesc->sd);
     1791                map_job_permissions(secdesc);
    57201792        } else {
    5721                 map_printer_permissions(secdesc->sd);
     1793                map_printer_permissions(secdesc);
    57221794        }
    57231795
    57241796        /* 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,
    57261798                                 &access_granted);
    57271799
     
    57311803
    57321804        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,
    57371808                                         lp_printer_admin(snum)))) {
    57381809                talloc_destroy(mem_ctx);
     
    57531824*****************************************************************************/
    57541825
    5755 bool print_time_access_check(const char *servicename)
    5756 {
    5757         NT_PRINTER_INFO_LEVEL *printer = NULL;
     1826bool 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;
    57581832        bool ok = False;
    57591833        time_t now = time(NULL);
     
    57611835        uint32 mins;
    57621836
    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)) {
    57641840                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) {
    57671844                ok = True;
     1845        }
    57681846
    57691847        t = gmtime(&now);
    57701848        mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
    57711849
    5772         if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
     1850        if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) {
    57731851                ok = True;
    5774 
    5775         free_a_printer(&printer, 2);
    5776 
    5777         if (!ok)
     1852        }
     1853
     1854        TALLOC_FREE(pinfo2);
     1855
     1856        if (!ok) {
    57781857                errno = EACCES;
     1858        }
    57791859
    57801860        return ok;
    57811861}
    57821862
    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 
     1863void nt_printer_remove(TALLOC_CTX *mem_ctx,
     1864                        const struct auth_serversupplied_info *session_info,
     1865                        struct messaging_context *msg_ctx,
     1866                        const char *printer)
     1867{
     1868        WERROR result;
     1869
     1870        result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx,
     1871                                           printer, "");
     1872        if (!W_ERROR_IS_OK(result)) {
     1873                DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s",
     1874                          printer));
     1875        }
     1876}
  • vendor/current/source3/printing/pcap.c

    r597 r740  
    2727
    2828/*
    29  *  This module contains code to parse and cache printcap data, possibly
    30  *  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 NIS
    34  *  databases etc).
    35  *
    36  *  There are assumed to be one or more printer names per record, held
    37  *  as a set of sub-fields separated by vertical bar symbols ('|') in the
    38  *  first field of the record. The field separator is assumed to be a colon
    39  *  ':' and the record separator a newline.
    40  *
    41  *  Lines ending with a backspace '\' are assumed to flag that the following
    42  *  line is a continuation line so that a set of lines can be read as one
    43  *  printcap entry.
    44  *
    45  *  A line stating with a hash '#' is assumed to be a comment and is ignored
    46  *  Comments are discarded before the record is strung together from the
    47  *  set of continuation lines.
    48  *
    49  *  Opening a pipe for "lpc status" and reading that would probably
    50  *  be pretty effective. Code to do this already exists in the freely
    51  *  distributable PCNFS server code.
    52  *
    5329 *  Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
    5430 *  in smb.conf under Solaris.
     
    6238
    6339#include "includes.h"
    64 
     40#include "printing/pcap.h"
     41#include "printer_list.h"
    6542
    6643struct pcap_cache {
    6744        char *name;
    6845        char *comment;
     46        char *location;
    6947        struct pcap_cache *next;
    7048};
    7149
    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)
     50bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location)
    7651{
    7752        struct pcap_cache *p;
     
    8257        p->name = SMB_STRDUP(name);
    8358        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 : ""));
    8764
    8865        p->next = *ppcache;
     
    10178                SAFE_FREE(p->name);
    10279                SAFE_FREE(p->comment);
     80                SAFE_FREE(p->location);
    10381                SAFE_FREE(p);
    10482        }
     
    10684}
    10785
    108 bool pcap_cache_add(const char *name, const char *comment)
    109 {
    110         return pcap_cache_add_specific(&pcap_cache, name, comment);
     86bool 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);
    11193}
    11294
    11395bool pcap_cache_loaded(void)
    11496{
    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
     104bool pcap_cache_replace(const struct pcap_cache *pcache)
    119105{
    120106        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
    123115        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
     128void 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 *))
    129132{
    130133        const char *pcap_name = lp_printcapname();
    131134        bool pcap_reloaded = False;
    132         struct pcap_cache *tmp_cache = NULL;
    133         XFILE *pcap_file;
    134         char *pcap_line;
     135        NTSTATUS status;
    135136        bool post_cache_fill_fn_handled = false;
    136137
     
    143144        }
    144145
    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        }
    147151
    148152#ifdef HAVE_CUPS
    149153        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);
    151156                /*
    152157                 * cups_cache_reload() is async and calls post_cache_fill_fn()
     
    179184#endif
    180185
    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);
    247187
    248188done:
    249189        DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
    250190
    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"));
    256198                }
    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                }
    260202        }
    261203
     
    266208bool pcap_printername_ok(const char *printername)
    267209{
    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);
    275214}
    276215
     
    280219
    281220void 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 *),
    283222                        void *pdata)
    284223{
     
    286225
    287226        for (p = pc; p != NULL; p = p->next)
    288                 fn(p->name, p->comment, pdata);
     227                fn(p->name, p->comment, p->location, pdata);
    289228
    290229        return;
    291230}
    292231
    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 }
     232void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata)
     233{
     234        NTSTATUS status;
     235
     236        status = printer_list_run_fn(fn, pdata);
     237        if (!NT_STATUS_IS_OK(status)) {
     238                DEBUG(3, ("Failed to run fn for all printers!\n"));
     239        }
     240        return;
     241}
  • vendor/current/source3/printing/print_aix.c

    r414 r740  
    2626
    2727#include "includes.h"
     28#include "system/filesys.h"
     29#include "printing/pcap.h"
    2830
    2931#ifdef AIX
     
    8587                                /* probably a good printer ???          */
    8688                                iEtat = 0;
    87                                 if (!pcap_cache_add(name, NULL)) {
     89                                if (!pcap_cache_add(name, NULL, NULL)) {
    8890                                        SAFE_FREE(line);
    8991                                        x_fclose(pfile);
     
    100102                                /* it's a good virtual printer */
    101103                                iEtat = 0;
    102                                 if (!pcap_cache_add(name, NULL)) {
     104                                if (!pcap_cache_add(name, NULL, NULL)) {
    103105                                        SAFE_FREE(line);
    104106                                        x_fclose(pfile);
  • vendor/current/source3/printing/print_cups.c

    r597 r740  
    2525#include "includes.h"
    2626#include "printing.h"
     27#include "printing/pcap.h"
    2728#include "librpc/gen_ndr/ndr_printcap.h"
    2829
     
    3738****************************************************************/
    3839
    39 static void gotalarm_sig(void)
     40static void gotalarm_sig(int signum)
    4041{
    4142        gotalarm = 1;
     
    9192
    9293        if (timeout) {
    93                 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
     94                CatchSignal(SIGALRM, gotalarm_sig);
    9495                alarm(timeout);
    9596        }
     
    102103
    103104
    104         CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
     105        CatchSignal(SIGALRM, SIG_IGN);
    105106        alarm(0);
    106107
     
    127128        }
    128129
    129         DEBUG(10, ("successfully sent blob of len %ld\n", (int64_t)ret));
     130        DEBUG(10, ("successfully sent blob of len %d\n", (int)ret));
    130131        return true;
    131132}
     
    152153        }
    153154
    154         DEBUG(10, ("successfully recvd blob of len %ld\n", (int64_t)ret));
     155        DEBUG(10, ("successfully recvd blob of len %d\n", (int)ret));
    155156        return true;
    156157}
     
    163164        char *name;
    164165        char *info;
     166        char *location = NULL;
    165167        struct pcap_printer *printer;
    166168        bool ret_ok = false;
     
    200202                                if (!pull_utf8_talloc(mem_ctx,
    201203                                                &info,
     204                                                attr->values[0].string.text,
     205                                                &size)) {
     206                                        goto err_out;
     207                                }
     208                        }
     209
     210                        if (strcmp(attr->name, "printer-location") == 0 &&
     211                            attr->value_tag == IPP_TAG_TEXT) {
     212                                if (!pull_utf8_talloc(mem_ctx,
     213                                                &location,
    202214                                                attr->values[0].string.text,
    203215                                                &size)) {
     
    229241                pcap_data->printers[pcap_data->count].name = name;
    230242                pcap_data->printers[pcap_data->count].info = info;
     243                pcap_data->printers[pcap_data->count].location = location;
    231244                pcap_data->count++;
    232245        }
     
    252265                        {
    253266                          "printer-name",
    254                           "printer-info"
     267                          "printer-info",
     268                          "printer-location"
    255269                        };
    256270        bool ret = False;
     
    364378
    365379        ret = false;
    366         ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, NULL, &pcap_data,
     380        ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, &pcap_data,
    367381                                       (ndr_push_flags_fn_t)ndr_push_pcap_data);
    368382        if (ndr_ret == NDR_ERR_SUCCESS) {
     
    374388}
    375389
    376 static struct pcap_cache *local_pcap_copy;
    377 struct fd_event *cache_fd_event;
    378 
    379 static bool cups_pcap_load_async(int *pfd)
     390static struct fd_event *cache_fd_event;
     391
     392static bool cups_pcap_load_async(struct tevent_context *ev,
     393                                 struct messaging_context *msg_ctx,
     394                                 int *pfd)
    380395{
    381396        int fds[2];
    382397        pid_t pid;
     398        NTSTATUS status;
    383399
    384400        *pfd = -1;
     
    418434        close_all_print_db();
    419435
    420         if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
    421                                                smbd_event_context(), true))) {
     436        status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
     437        if (!NT_STATUS_IS_OK(status)) {
    422438                DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n"));
    423439                smb_panic("cups_pcap_load_async: reinit_after_fork() failed");
     
    432448struct cups_async_cb_args {
    433449        int pipe_fd;
    434         void (*post_cache_fill_fn)(void);
     450        struct event_context *event_ctx;
     451        struct messaging_context *msg_ctx;
     452        void (*post_cache_fill_fn)(struct event_context *,
     453                                   struct messaging_context *);
    435454};
    436455
     
    458477        }
    459478
    460         ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, NULL, &pcap_data,
     479        ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, &pcap_data,
    461480                                       (ndr_pull_flags_fn_t)ndr_pull_pcap_data);
    462481        if (ndr_ret != NDR_ERR_SUCCESS) {
     
    473492                ret_ok = pcap_cache_add_specific(&tmp_pcap_cache,
    474493                                                 pcap_data.printers[i].name,
    475                                                  pcap_data.printers[i].info);
     494                                                 pcap_data.printers[i].info,
     495                                                 pcap_data.printers[i].location);
    476496                if (!ret_ok) {
    477497                        DEBUG(0, ("failed to add to tmp pcap cache\n"));
    478                         break;
     498                        goto err_out;
    479499                }
    480500        }
    481501
     502        /* replace the system-wide pcap cache with a (possibly empty) new one */
     503        ret_ok = pcap_cache_replace(tmp_pcap_cache);
    482504        if (!ret_ok) {
    483                 DEBUG(0,("failed to read a new printer list\n"));
    484                 pcap_cache_destroy_specific(&tmp_pcap_cache);
    485         } else {
    486                 /* We got a possibly empty namelist, replace our local cache. */
    487                 pcap_cache_destroy_specific(&local_pcap_copy);
    488                 local_pcap_copy = tmp_pcap_cache;
    489 
    490                 /* And the systemwide pcap cache. */
    491                 pcap_cache_replace(local_pcap_copy);
    492 
    493                 /* Caller may have requested post cache fill callback */
    494                 if (cb_args->post_cache_fill_fn) {
    495                         cb_args->post_cache_fill_fn();
    496                 }
     505                DEBUG(0, ("failed to replace pcap cache\n"));
     506        } else if (cb_args->post_cache_fill_fn != NULL) {
     507                /* Caller requested post cache fill callback */
     508                cb_args->post_cache_fill_fn(cb_args->event_ctx,
     509                                            cb_args->msg_ctx);
    497510        }
    498511err_out:
     512        pcap_cache_destroy_specific(&tmp_pcap_cache);
    499513        TALLOC_FREE(frame);
    500514        close(cb_args->pipe_fd);
     
    503517}
    504518
    505 bool cups_cache_reload(void (*post_cache_fill_fn)(void))
     519bool cups_cache_reload(struct tevent_context *ev,
     520                       struct messaging_context *msg_ctx,
     521                       void (*post_cache_fill_fn)(struct tevent_context *,
     522                                                  struct messaging_context *))
    506523{
    507524        struct cups_async_cb_args *cb_args;
     
    509526
    510527        cb_args = TALLOC_P(NULL, struct cups_async_cb_args);
    511         if (!cb_args) {
     528        if (cb_args == NULL) {
    512529                return false;
    513530        }
     531
    514532        cb_args->post_cache_fill_fn = post_cache_fill_fn;
     533        cb_args->event_ctx = ev;
     534        cb_args->msg_ctx = msg_ctx;
    515535        p_pipe_fd = &cb_args->pipe_fd;
    516536        *p_pipe_fd = -1;
    517537
    518538        /* Set up an async refresh. */
    519         if (!cups_pcap_load_async(p_pipe_fd)) {
     539        if (!cups_pcap_load_async(ev, msg_ctx, p_pipe_fd)) {
    520540                talloc_free(cb_args);
    521541                return false;
    522542        }
    523         if (!local_pcap_copy) {
    524                 /* We have no local cache, wait directly for
    525                  * async refresh to complete.
    526                  */
    527                 DEBUG(10,("cups_cache_reload: sync read on fd %d\n",
    528                         *p_pipe_fd ));
    529 
    530                 cups_async_callback(smbd_event_context(),
    531                                         NULL,
    532                                         EVENT_FD_READ,
    533                                         (void *)cb_args);
    534                 if (!local_pcap_copy) {
    535                         return false;
    536                 }
    537         } else {
    538                 /* Replace the system cache with our
    539                  * local copy. */
    540                 pcap_cache_replace(local_pcap_copy);
    541 
    542                 DEBUG(10,("cups_cache_reload: async read on fd %d\n",
    543                         *p_pipe_fd ));
    544 
    545                 /* Trigger an event when the pipe can be read. */
    546                 cache_fd_event = event_add_fd(smbd_event_context(),
    547                                         NULL, *p_pipe_fd,
    548                                         EVENT_FD_READ,
    549                                         cups_async_callback,
    550                                         (void *)cb_args);
    551                 if (!cache_fd_event) {
    552                         close(*p_pipe_fd);
    553                         talloc_free(cb_args);
    554                         return false;
    555                 }
    556         }
     543
     544        DEBUG(10,("cups_cache_reload: async read on fd %d\n",
     545                *p_pipe_fd ));
     546
     547        /* Trigger an event when the pipe can be read. */
     548        cache_fd_event = event_add_fd(ev,
     549                                NULL, *p_pipe_fd,
     550                                EVENT_FD_READ,
     551                                cups_async_callback,
     552                                (void *)cb_args);
     553        if (!cache_fd_event) {
     554                close(*p_pipe_fd);
     555                TALLOC_FREE(cb_args);
     556                return false;
     557        }
     558
    557559        return true;
    558560}
     
    861863        cups_lang_t     *language = NULL;       /* Default language */
    862864        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
    863         const char      *clientname = NULL;     /* hostname of client for job-originating-host attribute */
    864865        char *new_jobname = NULL;
    865866        int             num_options = 0;
     
    872873        size_t size;
    873874        uint32_t jobid = (uint32_t)-1;
    874         char addr[INET6_ADDRSTRLEN];
    875875
    876876        DEBUG(5,("cups_job_submit(%d, %p)\n", snum, pjob));
     
    914914                     "attributes-natural-language", NULL, language->language);
    915915
    916         if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
     916        if (!push_utf8_talloc(frame, &printername, lp_printername(snum),
     917                              &size)) {
    917918                goto out;
    918919        }
     
    929930                     NULL, user);
    930931
    931         clientname = client_name(get_client_fd());
    932         if (strcmp(clientname, "UNKNOWN") == 0) {
    933                 clientname = client_addr(get_client_fd(),addr,sizeof(addr));
    934         }
    935 
    936932        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
    937933                     "job-originating-host-name", NULL,
    938                       clientname);
     934                     pjob->clientmachine);
    939935
    940936        /* Get the jobid from the filename. */
     
    985981        if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
    986982                if (response->request.status.status_code >= IPP_OK_CONFLICT) {
    987                         DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
     983                        DEBUG(0,("Unable to print file to %s - %s\n",
     984                                 lp_printername(snum),
    988985                                 ippErrorString(cupsLastError())));
    989986                } else {
     
    998995                }
    999996        } else {
    1000                 DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
     997                DEBUG(0,("Unable to print file to `%s' - %s\n",
     998                         lp_printername(snum),
    1001999                         ippErrorString(cupsLastError())));
    10021000        }
     
    14231421                     "attributes-natural-language", NULL, language->language);
    14241422
    1425         if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
     1423        if (!push_utf8_talloc(frame, &printername, lp_printername(snum),
     1424                              &size)) {
    14261425                goto out;
    14271426        }
     
    14431442        if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
    14441443                if (response->request.status.status_code >= IPP_OK_CONFLICT) {
    1445                         DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
     1444                        DEBUG(0,("Unable to pause printer %s - %s\n",
     1445                                 lp_printername(snum),
    14461446                                ippErrorString(cupsLastError())));
    14471447                } else {
     
    14491449                }
    14501450        } else {
    1451                 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
     1451                DEBUG(0,("Unable to pause printer %s - %s\n",
     1452                         lp_printername(snum),
    14521453                        ippErrorString(cupsLastError())));
    14531454        }
     
    15241525                     "attributes-natural-language", NULL, language->language);
    15251526
    1526         if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
     1527        if (!push_utf8_talloc(frame, &printername, lp_printername(snum),
     1528                              &size)) {
    15271529                goto out;
    15281530        }
     
    15441546        if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
    15451547                if (response->request.status.status_code >= IPP_OK_CONFLICT) {
    1546                         DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
     1548                        DEBUG(0,("Unable to resume printer %s - %s\n",
     1549                                 lp_printername(snum),
    15471550                                ippErrorString(cupsLastError())));
    15481551                } else {
     
    15501553                }
    15511554        } else {
    1552                 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
     1555                DEBUG(0,("Unable to resume printer %s - %s\n",
     1556                         lp_printername(snum),
    15531557                        ippErrorString(cupsLastError())));
    15541558        }
     
    15841588};
    15851589
    1586 bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
    1587 {
    1588         TALLOC_CTX *frame = talloc_stackframe();
    1589         http_t          *http = NULL;           /* HTTP connection to server */
    1590         ipp_t           *request = NULL,        /* IPP Request */
    1591                         *response = NULL;       /* IPP Response */
    1592         ipp_attribute_t *attr;          /* Current attribute */
    1593         cups_lang_t     *language = NULL;       /* Default language */
    1594         char            uri[HTTP_MAX_URI];
    1595         char *sharename = NULL;
    1596         char *name = NULL;
    1597         static const char *requested[] =/* Requested attributes */
    1598                         {
    1599                           "printer-name",
    1600                           "printer-info",
    1601                           "printer-location"
    1602                         };
    1603         bool ret = False;
    1604         size_t size;
    1605 
    1606         DEBUG(5, ("pulling %s location\n", printer->sharename));
    1607 
    1608         /*
    1609          * Make sure we don't ask for passwords...
    1610          */
    1611 
    1612         cupsSetPasswordCB(cups_passwd_cb);
    1613 
    1614         /*
    1615          * Try to connect to the server...
    1616          */
    1617 
    1618         if ((http = cups_connect(frame)) == NULL) {
    1619                 goto out;
    1620         }
    1621 
    1622         request = ippNew();
    1623 
    1624         request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
    1625         request->request.op.request_id   = 1;
    1626 
    1627         language = cupsLangDefault();
    1628 
    1629         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
    1630                      "attributes-charset", NULL, "utf-8");
    1631 
    1632         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
    1633                      "attributes-natural-language", NULL, language->language);
    1634 
    1635         if (!push_utf8_talloc(frame, &sharename, printer->sharename, &size)) {
    1636                 goto out;
    1637         }
    1638         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
    1639                  sharename);
    1640 
    1641         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
    1642                      "printer-uri", NULL, uri);
    1643 
    1644         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
    1645                       "requested-attributes",
    1646                       (sizeof(requested) / sizeof(requested[0])),
    1647                       NULL, requested);
    1648 
    1649         /*
    1650          * Do the request and get back a response...
    1651          */
    1652 
    1653         if ((response = cupsDoRequest(http, request, "/")) == NULL) {
    1654                 DEBUG(0,("Unable to get printer attributes - %s\n",
    1655                          ippErrorString(cupsLastError())));
    1656                 goto out;
    1657         }
    1658 
    1659         for (attr = response->attrs; attr != NULL;) {
    1660                 /*
    1661                  * Skip leading attributes until we hit a printer...
    1662                  */
    1663 
    1664                 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
    1665                         attr = attr->next;
    1666 
    1667                 if (attr == NULL)
    1668                         break;
    1669 
    1670                 /*
    1671                  * Pull the needed attributes from this printer...
    1672                  */
    1673 
    1674                 while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {
    1675                         if (strcmp(attr->name, "printer-name") == 0 &&
    1676                             attr->value_tag == IPP_TAG_NAME) {
    1677                                 if (!pull_utf8_talloc(frame,
    1678                                                 &name,
    1679                                                 attr->values[0].string.text,
    1680                                                 &size)) {
    1681                                         goto out;
    1682                                 }
    1683                         }
    1684 
    1685                         /* Grab the comment if we don't have one */
    1686                         if ( (strcmp(attr->name, "printer-info") == 0)
    1687                              && (attr->value_tag == IPP_TAG_TEXT)
    1688                              && !strlen(printer->comment) )
    1689                         {
    1690                                 char *comment = NULL;
    1691                                 if (!pull_utf8_talloc(frame,
    1692                                                 &comment,
    1693                                                 attr->values[0].string.text,
    1694                                                 &size)) {
    1695                                         goto out;
    1696                                 }
    1697                                 DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",
    1698                                          comment));
    1699                                 strlcpy(printer->comment,
    1700                                         comment,
    1701                                         sizeof(printer->comment));
    1702                         }
    1703 
    1704                         /* Grab the location if we don't have one */
    1705                         if ( (strcmp(attr->name, "printer-location") == 0)
    1706                              && (attr->value_tag == IPP_TAG_TEXT)
    1707                              && !strlen(printer->location) )
    1708                         {
    1709                                 char *location = NULL;
    1710                                 if (!pull_utf8_talloc(frame,
    1711                                                 &location,
    1712                                                 attr->values[0].string.text,
    1713                                                 &size)) {
    1714                                         goto out;
    1715                                 }
    1716                                 DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",
    1717                                          location));
    1718                                 strlcpy(printer->location,
    1719                                         location,
    1720                                         sizeof(printer->location));
    1721                         }
    1722 
    1723                         attr = attr->next;
    1724                 }
    1725 
    1726                 /*
    1727                  * We have everything needed...
    1728                  */
    1729 
    1730                 if (name != NULL)
    1731                         break;
    1732         }
    1733 
    1734         ret = True;
    1735 
    1736  out:
    1737         if (response)
    1738                 ippDelete(response);
    1739 
    1740         if (language)
    1741                 cupsLangFree(language);
    1742 
    1743         if (http)
    1744                 httpClose(http);
    1745 
    1746         TALLOC_FREE(frame);
    1747         return ret;
    1748 }
    1749 
    17501590#else
    17511591 /* this keeps fussy compilers happy */
  • vendor/current/source3/printing/print_generic.c

    r414 r740  
    118118        /* need to pause the spooled entry */
    119119        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,
    121121                                 lp_lppausecommand(snum), NULL,
    122122                                 "%j", jobstr,
     
    133133        /* need to pause the spooled entry */
    134134        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,
    136136                                 lp_lpresumecommand(snum), NULL,
    137137                                 "%j", jobstr,
     
    195195
    196196        /* 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,
    198198                        lp_printcommand(snum), NULL,
    199199                        "%s", p,
     
    275275static int generic_queue_pause(int snum)
    276276{
    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);
    278279}
    279280
     
    283284static int generic_queue_resume(int snum)
    284285{
    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);
    286288}
    287289
  • vendor/current/source3/printing/print_iprint.c

    r414 r740  
    2222#include "includes.h"
    2323#include "printing.h"
     24#include "printing/pcap.h"
    2425
    2526#ifdef HAVE_IPRINT
     
    297298
    298299                if (name != NULL && !secure && smb_enabled)
    299                         pcap_cache_add(name, info);
     300                        pcap_cache_add(name, info, NULL);
    300301        }
    301302
     
    575576                     "attributes-natural-language", NULL, language->language);
    576577
    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));
    578580
    579581        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
     
    588590        */
    589591
    590         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
     592        slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
     593                 lp_printername(snum));
    591594
    592595        if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
     
    673676                     "attributes-natural-language", NULL, language->language);
    674677
    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));
    676680
    677681        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
     
    686690        */
    687691
    688         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
     692        slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
     693                 lp_printername(snum));
    689694
    690695        if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
     
    727732        cups_lang_t     *language = NULL;       /* Default language */
    728733        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];
    731734
    732735        DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
     
    772775                     "attributes-natural-language", NULL, language->language);
    773776
    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));
    775779
    776780        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
     
    780784                     NULL, pjob->user);
    781785
    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        
    787786        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
    788787                     "job-originating-host-name", NULL,
    789                      clientname);
     788                     pjob->clientmachine);
    790789
    791790        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
     
    796795        */
    797796
    798         slprintf(uri, sizeof(uri) - 1, "/ipp/%s", PRINTERNAME(snum));
     797        slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(snum));
    799798
    800799        if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
    801800                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),
    803803                                 ippErrorString(cupsLastError())));
    804804                } else {
     
    806806                }
    807807        } 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),
    809810                         ippErrorString(cupsLastError())));
    810811        }
  • vendor/current/source3/printing/print_svid.c

    r414 r740  
    3333
    3434#include "includes.h"
     35#include "printing/pcap.h"
    3536
    3637#if defined(SYSV) || defined(HPUX)
     
    111112               
    112113                /* add it to the cache */
    113                 if (!pcap_cache_add(name, NULL)) {
     114                if (!pcap_cache_add(name, NULL, NULL)) {
    114115                        TALLOC_FREE(lines);
    115116                        return False;
  • vendor/current/source3/printing/printing.c

    r478 r740  
    2121
    2222#include "includes.h"
     23#include "system/syslog.h"
     24#include "system/filesys.h"
    2325#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"
    2436
    2537extern struct current_user current_user;
     
    2739
    2840/* Current printer interface */
    29 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
     41static bool remove_from_jobs_added(const char* sharename, uint32 jobid);
    3042
    3143/*
     
    134146}
    135147
    136 static void rap_jobid_delete(const char* sharename, uint32 jobid)
     148void rap_jobid_delete(const char* sharename, uint32 jobid)
    137149{
    138150        TDB_DATA key, data;
     
    275287}
    276288
     289/****************************************************************************
     290 Pack the devicemode to store it in a tdb.
     291****************************************************************************/
     292static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
     293{
     294        enum ndr_err_code ndr_err;
     295        DATA_BLOB blob;
     296        int len = 0;
     297
     298        if (devmode) {
     299                ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
     300                                               devmode,
     301                                               (ndr_push_flags_fn_t)
     302                                               ndr_push_spoolss_DeviceMode);
     303                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     304                        DEBUG(10, ("pack_devicemode: "
     305                                   "error encoding spoolss_DeviceMode\n"));
     306                        goto done;
     307                }
     308        } else {
     309                ZERO_STRUCT(blob);
     310        }
     311
     312        len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
     313
     314        if (devmode) {
     315                DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
     316        }
     317
     318done:
     319        return len;
     320}
     321
     322/****************************************************************************
     323 Unpack the devicemode to store it in a tdb.
     324****************************************************************************/
     325static int unpack_devicemode(TALLOC_CTX *mem_ctx,
     326                      const uint8 *buf, int buflen,
     327                      struct spoolss_DeviceMode **devmode)
     328{
     329        struct spoolss_DeviceMode *dm;
     330        enum ndr_err_code ndr_err;
     331        char *data = NULL;
     332        int data_len = 0;
     333        DATA_BLOB blob;
     334        int len = 0;
     335
     336        *devmode = NULL;
     337
     338        len = tdb_unpack(buf, buflen, "B", &data_len, &data);
     339        if (!data) {
     340                return len;
     341        }
     342
     343        dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
     344        if (!dm) {
     345                goto done;
     346        }
     347
     348        blob = data_blob_const(data, data_len);
     349
     350        ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
     351                        (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
     352        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     353                DEBUG(10, ("unpack_devicemode: "
     354                           "error parsing spoolss_DeviceMode\n"));
     355                goto done;
     356        }
     357
     358        DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
     359                  dm->devicename, dm->formname));
     360        if (dm->driverextra_data.data) {
     361                DEBUG(8, ("with a private section of %d bytes\n",
     362                          dm->__driverextra_length));
     363        }
     364
     365        *devmode = dm;
     366
     367done:
     368        SAFE_FREE(data);
     369        return len;
     370}
     371
    277372/***********************************************************************
    278373 unpack a pjob from a tdb buffer
    279374***********************************************************************/
    280375
    281 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
     376static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
    282377{
    283378        int     len = 0;
     
    289384                return -1;
    290385
    291         len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
     386        len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff",
    292387                                &pjpid,
    293388                                &pjsysjob,
     
    302397                                pjob->jobname,
    303398                                pjob->user,
     399                                pjob->clientmachine,
    304400                                pjob->queuename);
    305401
     
    307403                return -1;
    308404
    309         if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
     405        used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
     406        if (used == -1) {
    310407                return -1;
     408        }
    311409
    312410        len += used;
     
    352450        }
    353451
    354         if ( pjob.nt_devmode ) {
    355                 free_nt_devicemode( &pjob.nt_devmode );
    356         }
     452        talloc_free(pjob.devmode);
    357453
    358454        ZERO_STRUCT( pjob );
     
    438534
    439535static const struct {
    440         uint32 lpq_status;
    441         uint32 spoolss_status;
     536        uint32_t lpq_status;
     537        uint32_t spoolss_status;
    442538} lpq_to_spoolss_status_map[] = {
    443539        { LPQ_QUEUED, JOB_STATUS_QUEUED },
     
    452548        { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
    453549        { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
    454         { -1, 0 }
     550        { (uint32_t)-1, 0 }
    455551};
    456552
     
    471567}
    472568
    473 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
    474                               struct printjob *new_data)
    475 {
    476         bool new_job = False;
    477 
    478         if (!old_data)
    479                 new_job = True;
    480 
    481         /* Job attributes that can't be changed.  We only send
    482            notification for these on a new job. */
     569/***************************************************************************
     570 Append a jobid to the 'jobs changed' list.
     571***************************************************************************/
     572
     573static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
     574{
     575        TDB_DATA data;
     576        uint32_t store_jobid;
     577
     578        SIVAL(&store_jobid, 0, jobid);
     579        data.dptr = (uint8 *) &store_jobid;
     580        data.dsize = 4;
     581
     582        DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
     583
     584        return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
     585                           data) == 0);
     586}
     587
     588/***************************************************************************
     589 Remove a jobid from the 'jobs changed' list.
     590***************************************************************************/
     591
     592static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
     593{
     594        struct tdb_print_db *pdb = get_print_db_byname(sharename);
     595        TDB_DATA data, key;
     596        size_t job_count, i;
     597        bool ret = False;
     598        bool gotlock = False;
     599
     600        if (!pdb) {
     601                return False;
     602        }
     603
     604        ZERO_STRUCT(data);
     605
     606        key = string_tdb_data("INFO/jobs_changed");
     607
     608        if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
     609                goto out;
     610
     611        gotlock = True;
     612
     613        data = tdb_fetch(pdb->tdb, key);
     614
     615        if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
     616                goto out;
     617
     618        job_count = data.dsize / 4;
     619        for (i = 0; i < job_count; i++) {
     620                uint32 ch_jobid;
     621
     622                ch_jobid = IVAL(data.dptr, i*4);
     623                if (ch_jobid == jobid) {
     624                        if (i < job_count -1 )
     625                                memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
     626                        data.dsize -= 4;
     627                        if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
     628                                goto out;
     629                        break;
     630                }
     631        }
     632
     633        ret = True;
     634  out:
     635
     636        if (gotlock)
     637                tdb_chainunlock(pdb->tdb, key);
     638        SAFE_FREE(data.dptr);
     639        release_print_db(pdb);
     640        if (ret)
     641                DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
     642        else
     643                DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
     644        return ret;
     645}
     646
     647static void pjob_store_notify(struct tevent_context *ev,
     648                              struct messaging_context *msg_ctx,
     649                              const char* sharename, uint32 jobid,
     650                              struct printjob *old_data,
     651                              struct printjob *new_data,
     652                              bool *pchanged)
     653{
     654        bool new_job = false;
     655        bool changed = false;
     656
     657        if (old_data == NULL) {
     658                new_job = true;
     659        }
    483660
    484661        /* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the
     
    490667
    491668        if (new_job) {
    492                 notify_job_submitted(sharename, jobid, new_data->starttime);
    493                 notify_job_username(sharename, jobid, new_data->user);
    494         }
    495 
    496         if (new_job || !strequal(old_data->jobname, new_data->jobname))
    497                 notify_job_name(sharename, jobid, new_data->jobname);
    498 
    499         /* Job attributes of a new job or attributes that can be
    500            modified. */
    501 
    502         if (new_job || !strequal(old_data->jobname, new_data->jobname))
    503                 notify_job_name(sharename, jobid, new_data->jobname);
    504 
    505         if (new_job || old_data->status != new_data->status)
    506                 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
    507 
    508         if (new_job || old_data->size != new_data->size)
    509                 notify_job_total_bytes(sharename, jobid, new_data->size);
    510 
    511         if (new_job || old_data->page_count != new_data->page_count)
    512                 notify_job_total_pages(sharename, jobid, new_data->page_count);
     669                notify_job_submitted(ev, msg_ctx,
     670                                     sharename, jobid, new_data->starttime);
     671                notify_job_username(ev, msg_ctx,
     672                                    sharename, jobid, new_data->user);
     673                notify_job_name(ev, msg_ctx,
     674                                sharename, jobid, new_data->jobname);
     675                notify_job_status(ev, msg_ctx,
     676                                  sharename, jobid, map_to_spoolss_status(new_data->status));
     677                notify_job_total_bytes(ev, msg_ctx,
     678                                       sharename, jobid, new_data->size);
     679                notify_job_total_pages(ev, msg_ctx,
     680                                       sharename, jobid, new_data->page_count);
     681        } else {
     682                if (!strequal(old_data->jobname, new_data->jobname)) {
     683                        notify_job_name(ev, msg_ctx, sharename,
     684                                        jobid, new_data->jobname);
     685                        changed = true;
     686                }
     687
     688                if (old_data->status != new_data->status) {
     689                        notify_job_status(ev, msg_ctx,
     690                                          sharename, jobid,
     691                                          map_to_spoolss_status(new_data->status));
     692                }
     693
     694                if (old_data->size != new_data->size) {
     695                        notify_job_total_bytes(ev, msg_ctx,
     696                                               sharename, jobid, new_data->size);
     697                }
     698
     699                if (old_data->page_count != new_data->page_count) {
     700                        notify_job_total_pages(ev, msg_ctx,
     701                                               sharename, jobid,
     702                                               new_data->page_count);
     703                }
     704        }
     705
     706        *pchanged = changed;
    513707}
    514708
     
    517711****************************************************************************/
    518712
    519 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
     713static bool pjob_store(struct tevent_context *ev,
     714                       struct messaging_context *msg_ctx,
     715                       const char* sharename, uint32 jobid,
     716                       struct printjob *pjob)
    520717{
    521718        uint32_t tmp;
     
    541738                len = 0;
    542739                buflen = newlen;
    543                 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
     740                len += tdb_pack(buf+len, buflen-len, "dddddddddfffff",
    544741                                (uint32)pjob->pid,
    545742                                (uint32)pjob->sysjob,
     
    554751                                pjob->jobname,
    555752                                pjob->user,
     753                                pjob->clientmachine,
    556754                                pjob->queuename);
    557755
    558                 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
     756                len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
    559757
    560758                if (buflen != len) {
     
    576774                         TDB_REPLACE) == 0);
    577775
    578         release_print_db(pdb);
    579 
    580776        /* Send notify updates for what has changed */
    581777
    582778        if ( ret ) {
     779                bool changed = false;
    583780                struct printjob old_pjob;
    584781
     
    587784                        if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
    588785                        {
    589                                 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
    590                                 free_nt_devicemode( &old_pjob.nt_devmode );
     786                                pjob_store_notify(server_event_context(),
     787                                                  msg_ctx,
     788                                                  sharename, jobid, &old_pjob,
     789                                                  pjob,
     790                                                  &changed);
     791                                talloc_free(old_pjob.devmode);
     792
     793                                if (changed) {
     794                                        add_to_jobs_changed(pdb, jobid);
     795                                }
    591796                        }
     797
    592798                }
    593799                else {
    594800                        /* new job */
    595                         pjob_store_notify( sharename, jobid, NULL, pjob );
    596                 }
    597         }
    598 
     801                        pjob_store_notify(server_event_context(), msg_ctx,
     802                                          sharename, jobid, NULL, pjob,
     803                                          &changed);
     804                }
     805        }
     806
     807        release_print_db(pdb);
    599808done:
    600809        SAFE_FREE( old_data.dptr );
     
    608817****************************************************************************/
    609818
    610 void pjob_delete(const char* sharename, uint32 jobid)
     819static void pjob_delete(struct tevent_context *ev,
     820                        struct messaging_context *msg_ctx,
     821                        const char* sharename, uint32 jobid)
    611822{
    612823        uint32_t tmp;
     
    634845
    635846        job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
    636         notify_job_status(sharename, jobid, job_status);
     847        notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
    637848
    638849        /* Remove from printing.tdb */
    639850
    640851        tdb_delete(pdb->tdb, print_key(jobid, &tmp));
    641         remove_from_jobs_changed(sharename, jobid);
     852        remove_from_jobs_added(sharename, jobid);
    642853        release_print_db( pdb );
    643854        rap_jobid_delete(sharename, jobid);
     
    648859****************************************************************************/
    649860
    650 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
     861static void print_unix_job(struct tevent_context *ev,
     862                           struct messaging_context *msg_ctx,
     863                           const char *sharename, print_queue_struct *q,
     864                           uint32 jobid)
    651865{
    652866        struct printjob pj, *old_pj;
     
    679893        fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
    680894
    681         pjob_store(sharename, jobid, &pj);
     895        pjob_store(ev, msg_ctx, sharename, jobid, &pj);
    682896}
    683897
     
    690904        const char *lprm_command;
    691905        struct printif *print_if;
     906        struct tevent_context *ev;
     907        struct messaging_context *msg_ctx;
    692908};
    693909
     
    709925        if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
    710926                return 0;
    711         free_nt_devicemode( &pjob.nt_devmode );
     927        talloc_free(pjob.devmode);
    712928
    713929
     
    723939                        DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
    724940                                                (unsigned int)jobid ));
    725                         pjob_delete(ts->sharename, jobid);
     941                        pjob_delete(ts->ev, ts->msg_ctx,
     942                                    ts->sharename, jobid);
    726943                        return 0;
    727944                }
     
    739956                        DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
    740957                                                (unsigned int)jobid, (unsigned int)pjob.pid ));
    741                         pjob_delete(ts->sharename, jobid);
     958                        pjob_delete(ts->ev, ts->msg_ctx,
     959                                    ts->sharename, jobid);
    742960                } else
    743961                        ts->total_jobs++;
     
    769987                                                /* if we can't delete, then reset the job status */
    770988                                                pjob.status = LPQ_QUEUED;
    771                                                 pjob_store(ts->sharename, jobid, &pjob);
     989                                                pjob_store(ts->ev, ts->msg_ctx,
     990                                                           ts->sharename, jobid, &pjob);
    772991                                        }
    773992                                        else {
    774993                                                /* if we deleted the job, the remove the tdb record */
    775                                                 pjob_delete(ts->sharename, jobid);
     994                                                pjob_delete(ts->ev,
     995                                                            ts->msg_ctx,
     996                                                            ts->sharename, jobid);
    776997                                                pjob.status = LPQ_DELETED;
    777998                                        }
     
    8011022                                                (unsigned int)pjob.starttime,
    8021023                                                (unsigned int)ts->lpq_time ));
    803                         pjob_delete(ts->sharename, jobid);
     1024                        pjob_delete(ts->ev, ts->msg_ctx,
     1025                                    ts->sharename, jobid);
    8041026                } else
    8051027                        ts->total_jobs++;
     
    9981220}
    9991221
    1000 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
     1222static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
    10011223{
    10021224        TDB_DATA data;
     
    10041226        ZERO_STRUCT(data);
    10051227
    1006         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
     1228        data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
    10071229        if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
    10081230                SAFE_FREE(data.dptr);
     
    10131235}
    10141236
    1015 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
     1237static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
    10161238{
    10171239        unsigned int i;
     
    10231245                ch_jobid = IVAL(data.dptr, i*4);
    10241246                if (ch_jobid == jobid)
    1025                         remove_from_jobs_changed(sharename, jobid);
     1247                        remove_from_jobs_added(sharename, jobid);
    10261248        }
    10271249}
     
    10931315
    10941316/****************************************************************************
    1095  main work for updating the lpq cahe for a printer queue
    1096 ****************************************************************************/
    1097 
    1098 static void print_queue_update_internal( const char *sharename,
     1317 main work for updating the lpq cache for a printer queue
     1318****************************************************************************/
     1319
     1320static void print_queue_update_internal( struct tevent_context *ev,
     1321                                         struct messaging_context *msg_ctx,
     1322                                         const char *sharename,
    10991323                                         struct printif *current_printif,
    11001324                                         char *lpq_command, char *lprm_command )
     
    11401364           in hash order. */
    11411365
    1142         qsort(queue, qcount, sizeof(print_queue_struct),
    1143                 QSORT_CAST(printjob_comp));
     1366        TYPESAFE_QSORT(queue, qcount, printjob_comp);
    11441367
    11451368        /*
     
    11541377        */
    11551378
    1156         jcdata = get_jobs_changed_data(pdb);
     1379        jcdata = get_jobs_added_data(pdb);
    11571380
    11581381        for (i=0; i<qcount; i++) {
     
    11611384                if (jobid == (uint32)-1) {
    11621385                        /* assume its a unix print job */
    1163                         print_unix_job(sharename, &queue[i], jobid);
     1386                        print_unix_job(ev, msg_ctx,
     1387                                       sharename, &queue[i], jobid);
    11641388                        continue;
    11651389                }
     
    11711395                           with jobs in the queue. All we can do is treat them
    11721396                           like unix jobs. Pity. */
    1173                         print_unix_job(sharename, &queue[i], jobid);
     1397                        print_unix_job(ev, msg_ctx,
     1398                                       sharename, &queue[i], jobid);
    11741399                        continue;
    11751400                }
     
    11821407                        pjob->status = queue[i].status;
    11831408
    1184                 pjob_store(sharename, jobid, pjob);
    1185 
    1186                 check_job_changed(sharename, jcdata, jobid);
     1409                pjob_store(ev, msg_ctx, sharename, jobid, pjob);
     1410
     1411                check_job_added(sharename, jcdata, jobid);
    11871412        }
    11881413
     
    11991424        tstruct.lprm_command = lprm_command;
    12001425        tstruct.print_if = current_printif;
     1426        tstruct.ev = ev;
     1427        tstruct.msg_ctx = msg_ctx;
    12011428
    12021429        tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
     
    12561483****************************************************************************/
    12571484
    1258 static void print_queue_update_with_lock( const char *sharename,
     1485static void print_queue_update_with_lock( struct tevent_context *ev,
     1486                                          struct messaging_context *msg_ctx,
     1487                                          const char *sharename,
    12591488                                          struct printif *current_printif,
    12601489                                          char *lpq_command, char *lprm_command )
     
    13251554        /* do the main work now */
    13261555
    1327         print_queue_update_internal( sharename, current_printif,
    1328                 lpq_command, lprm_command );
     1556        print_queue_update_internal(ev, msg_ctx,
     1557                                    sharename, current_printif,
     1558                                    lpq_command, lprm_command);
    13291559
    13301560        /* Delete our pid from the db. */
     
    13361566this is the receive function of the background lpq updater
    13371567****************************************************************************/
    1338 static void print_queue_receive(struct messaging_context *msg,
     1568void print_queue_receive(struct messaging_context *msg,
    13391569                                void *private_data,
    13401570                                uint32_t msg_type,
     
    13601590        }
    13611591
    1362         print_queue_update_with_lock(sharename,
     1592        print_queue_update_with_lock(server_event_context(), msg, sharename,
    13631593                get_printer_fns_from_type((enum printing_types)printing_type),
    13641594                lpqcommand, lprmcommand );
     
    13811611}
    13821612
     1613extern struct child_pid *children;
     1614extern int num_children;
     1615
    13831616static void add_child_pid(pid_t pid)
    13841617{
    1385         extern struct child_pid *children;
    13861618        struct child_pid *child;
    1387         extern int num_children;
    13881619
    13891620        child = SMB_MALLOC_P(struct child_pid);
     
    14021633main thread of the background lpq updater
    14031634****************************************************************************/
    1404 void start_background_queue(void)
     1635void start_background_queue(struct tevent_context *ev,
     1636                            struct messaging_context *msg_ctx)
    14051637{
    14061638        /* Use local variables for this as we don't
     
    14301662                struct tevent_fd *fde;
    14311663                int ret;
     1664                NTSTATUS status;
    14321665
    14331666                /* Child. */
     
    14371670                pause_pipe[0] = -1;
    14381671
    1439                 if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
    1440                                                        smbd_event_context(),
    1441                                                        true))) {
     1672                status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
     1673
     1674                if (!NT_STATUS_IS_OK(status)) {
    14421675                        DEBUG(0,("reinit_after_fork() failed\n"));
    14431676                        smb_panic("reinit_after_fork() failed");
     
    14451678
    14461679                smbd_setup_sig_term_handler();
    1447                 smbd_setup_sig_hup_handler();
    1448 
    1449                 claim_connection( NULL, "smbd lpq backend",
    1450                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
     1680                smbd_setup_sig_hup_handler(ev, msg_ctx);
     1681
     1682                if (!serverid_register(procid_self(),
     1683                                       FLAG_MSG_GENERAL|FLAG_MSG_SMBD
     1684                                       |FLAG_MSG_PRINT_GENERAL)) {
     1685                        exit(1);
     1686                }
    14511687
    14521688                if (!locking_init()) {
     
    14541690                }
    14551691
    1456                 messaging_register(smbd_messaging_context(), NULL,
    1457                                    MSG_PRINTER_UPDATE, print_queue_receive);
    1458 
    1459                 fde = tevent_add_fd(smbd_event_context(), smbd_event_context(),
    1460                                     pause_pipe[1], TEVENT_FD_READ,
     1692                messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
     1693                                   print_queue_receive);
     1694
     1695                fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
    14611696                                    printing_pause_fd_handler,
    14621697                                    NULL);
     
    14671702
    14681703                DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
    1469                 ret = tevent_loop_wait(smbd_event_context());
     1704                ret = tevent_loop_wait(ev);
    14701705                /* should not be reached */
    14711706                DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
     
    14811716****************************************************************************/
    14821717
    1483 static void print_queue_update(int snum, bool force)
     1718static void print_queue_update(struct messaging_context *msg_ctx,
     1719                               int snum, bool force)
    14841720{
    14851721        fstring key;
     
    15021738                        lp_lpqcommand(snum),
    15031739                        "%p",
    1504                         PRINTERNAME(snum),
     1740                        lp_printername(snum),
    15051741                        false, false, false);
    15061742        if (!lpqcommand) {
     
    15221758                        lp_lprmcommand(snum),
    15231759                        "%p",
    1524                         PRINTERNAME(snum),
     1760                        lp_printername(snum),
    15251761                        false, false, false);
    15261762        if (!lprmcommand) {
     
    15471783                DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
    15481784                current_printif = get_printer_fns( snum );
    1549                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
     1785                print_queue_update_with_lock(server_event_context(), msg_ctx,
     1786                                             sharename, current_printif,
     1787                                             lpqcommand, lprmcommand);
    15501788
    15511789                return;
     
    16001838        /* finally send the message */
    16011839
    1602         messaging_send_buf(smbd_messaging_context(),
    1603                            pid_to_procid(background_lpq_updater_pid),
     1840        messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
    16041841                           MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
    16051842
     
    18082045
    18092046/****************************************************************************
    1810  Give the fd used for a jobid.
    1811 ****************************************************************************/
    1812 
    1813 int print_job_fd(const char* sharename, uint32 jobid)
    1814 {
    1815         struct printjob *pjob = print_job_find(sharename, jobid);
    1816         if (!pjob)
    1817                 return -1;
    1818         /* don't allow another process to get this info - it is meaningless */
    1819         if (pjob->pid != sys_getpid())
    1820                 return -1;
    1821         return pjob->fd;
    1822 }
    1823 
    1824 /****************************************************************************
    18252047 Give the filename used for a jobid.
    18262048 Only valid for the process doing the spooling and when the job
     
    18432065****************************************************************************/
    18442066
    1845 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
     2067struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
    18462068{
    18472069        struct printjob *pjob = print_job_find(sharename, jobid);
     
    18502072                return NULL;
    18512073
    1852         return pjob->nt_devmode;
    1853 }
    1854 
    1855 /****************************************************************************
    1856  Set the place in the queue for a job.
    1857 ****************************************************************************/
    1858 
    1859 bool print_job_set_place(const char *sharename, uint32 jobid, int place)
    1860 {
    1861         DEBUG(2,("print_job_set_place not implemented yet\n"));
    1862         return False;
     2074        return pjob->devmode;
    18632075}
    18642076
     
    18672079****************************************************************************/
    18682080
    1869 bool print_job_set_name(const char *sharename, uint32 jobid, char *name)
     2081bool print_job_set_name(struct tevent_context *ev,
     2082                        struct messaging_context *msg_ctx,
     2083                        const char *sharename, uint32 jobid, const char *name)
    18702084{
    18712085        struct printjob *pjob;
     
    18762090
    18772091        fstrcpy(pjob->jobname, name);
    1878         return pjob_store(sharename, jobid, pjob);
    1879 }
     2092        return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
     2093}
     2094
     2095/****************************************************************************
     2096 Get the name of a job. Only possible for owner.
     2097****************************************************************************/
     2098
     2099bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
     2100{
     2101        struct printjob *pjob;
     2102
     2103        pjob = print_job_find(sharename, jobid);
     2104        if (!pjob || pjob->pid != sys_getpid()) {
     2105                return false;
     2106        }
     2107
     2108        *name = talloc_strdup(mem_ctx, pjob->jobname);
     2109        if (!*name) {
     2110                return false;
     2111        }
     2112
     2113        return true;
     2114}
     2115
    18802116
    18812117/***************************************************************************
    1882  Remove a jobid from the 'jobs changed' list.
     2118 Remove a jobid from the 'jobs added' list.
    18832119***************************************************************************/
    18842120
    1885 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
     2121static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
    18862122{
    18872123        struct tdb_print_db *pdb = get_print_db_byname(sharename);
     
    18972133        ZERO_STRUCT(data);
    18982134
    1899         key = string_tdb_data("INFO/jobs_changed");
     2135        key = string_tdb_data("INFO/jobs_added");
    19002136
    19012137        if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
     
    19322168        release_print_db(pdb);
    19332169        if (ret)
    1934                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
     2170                DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
    19352171        else
    1936                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
     2172                DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
    19372173        return ret;
    19382174}
     
    19422178****************************************************************************/
    19432179
    1944 static bool print_job_delete1(int snum, uint32 jobid)
     2180static bool print_job_delete1(struct tevent_context *ev,
     2181                              struct messaging_context *msg_ctx,
     2182                              int snum, uint32 jobid)
    19452183{
    19462184        const char* sharename = lp_const_servicename(snum);
     
    19712209
    19722210        pjob->status = LPQ_DELETING;
    1973         pjob_store(sharename, jobid, pjob);
     2211        pjob_store(ev, msg_ctx, sharename, jobid, pjob);
    19742212
    19752213        if (pjob->spooled && pjob->sysjob != -1)
    19762214        {
    19772215                result = (*(current_printif->job_delete))(
    1978                         PRINTERNAME(snum),
     2216                        lp_printername(snum),
    19792217                        lp_lprmcommand(snum),
    19802218                        pjob);
     
    19892227                        if (!pdb)
    19902228                                return False;
    1991                         pjob_delete(sharename, jobid);
     2229                        pjob_delete(ev, msg_ctx, sharename, jobid);
    19922230                        /* Ensure we keep a rough count of the number of total jobs... */
    19932231                        tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
     
    19962234        }
    19972235
    1998         remove_from_jobs_changed( sharename, jobid );
     2236        remove_from_jobs_added( sharename, jobid );
    19992237
    20002238        return (result == 0);
     
    20052243****************************************************************************/
    20062244
    2007 static bool is_owner(struct auth_serversupplied_info *server_info,
     2245static bool is_owner(const struct auth_serversupplied_info *server_info,
    20082246                     const char *servicename,
    20092247                     uint32 jobid)
     
    20212259****************************************************************************/
    20222260
    2023 bool print_job_delete(struct auth_serversupplied_info *server_info, int snum,
    2024                       uint32 jobid, WERROR *errcode)
    2025 {
    2026         const char* sharename = lp_const_servicename( snum );
     2261WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
     2262                        struct messaging_context *msg_ctx,
     2263                        int snum, uint32_t jobid)
     2264{
     2265        const char* sharename = lp_const_servicename(snum);
    20272266        struct printjob *pjob;
    20282267        bool    owner;
    20292268        char    *fname;
    20302269
    2031         *errcode = WERR_OK;
    2032 
    20332270        owner = is_owner(server_info, lp_const_servicename(snum), jobid);
    20342271
     
    20372274
    20382275        if (!owner &&
    2039             !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
     2276            !print_access_check(server_info, msg_ctx, snum,
     2277                                JOB_ACCESS_ADMINISTER)) {
    20402278                DEBUG(3, ("delete denied by security descriptor\n"));
    2041                 *errcode = WERR_ACCESS_DENIED;
    20422279
    20432280                /* BEGIN_ADMIN_LOG */
     
    20462283pause, or resume print job. User name: %s. Printer name: %s.",
    20472284                              uidtoname(server_info->utok.uid),
    2048                               PRINTERNAME(snum) );
     2285                              lp_printername(snum) );
    20492286                /* END_ADMIN_LOG */
    20502287
    2051                 return False;
     2288                return WERR_ACCESS_DENIED;
    20522289        }
    20532290
     
    20592296         */
    20602297
    2061         if ( (fname = print_job_fname( sharename, jobid )) != NULL )
    2062         {
     2298        fname = print_job_fname(sharename, jobid);
     2299        if (fname != NULL) {
    20632300                /* remove the spool file */
    2064                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
    2065                 if ( unlink( fname ) == -1 ) {
    2066                         *errcode = map_werror_from_unix(errno);
    2067                         return False;
    2068                 }
    2069         }
    2070 
    2071         if (!print_job_delete1(snum, jobid)) {
    2072                 *errcode = WERR_ACCESS_DENIED;
    2073                 return False;
     2301                DEBUG(10, ("print_job_delete: "
     2302                           "Removing spool file [%s]\n", fname));
     2303                if (unlink(fname) == -1) {
     2304                        return map_werror_from_unix(errno);
     2305                }
     2306        }
     2307
     2308        if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
     2309                return WERR_ACCESS_DENIED;
    20742310        }
    20752311
     
    20772313           job still exists */
    20782314
    2079         print_queue_update(snum, True);
     2315        print_queue_update(msg_ctx, snum, True);
    20802316
    20812317        pjob = print_job_find(sharename, jobid);
    2082         if ( pjob && (pjob->status != LPQ_DELETING) )
    2083                 *errcode = WERR_ACCESS_DENIED;
    2084 
    2085         return (pjob == NULL );
     2318        if (pjob && (pjob->status != LPQ_DELETING)) {
     2319                return WERR_ACCESS_DENIED;
     2320        }
     2321
     2322        return WERR_PRINTER_HAS_JOBS_QUEUED;
    20862323}
    20872324
     
    20902327****************************************************************************/
    20912328
    2092 bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
    2093                      uint32 jobid, WERROR *errcode)
     2329bool print_job_pause(const struct auth_serversupplied_info *server_info,
     2330                     struct messaging_context *msg_ctx,
     2331                     int snum, uint32 jobid, WERROR *errcode)
    20942332{
    20952333        const char* sharename = lp_const_servicename(snum);
     
    21132351
    21142352        if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
    2115             !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
     2353            !print_access_check(server_info, msg_ctx, snum,
     2354                                JOB_ACCESS_ADMINISTER)) {
    21162355                DEBUG(3, ("pause denied by security descriptor\n"));
    21172356
     
    21212360pause, or resume print job. User name: %s. Printer name: %s.",
    21222361                              uidtoname(server_info->utok.uid),
    2123                               PRINTERNAME(snum) );
     2362                              lp_printername(snum) );
    21242363                /* END_ADMIN_LOG */
    21252364
     
    21412380        /* Send a printer notify message */
    21422381
    2143         notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
     2382        notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
     2383                          JOB_STATUS_PAUSED);
    21442384
    21452385        /* how do we tell if this succeeded? */
     
    21522392****************************************************************************/
    21532393
    2154 bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
    2155                       uint32 jobid, WERROR *errcode)
     2394bool print_job_resume(const struct auth_serversupplied_info *server_info,
     2395                      struct messaging_context *msg_ctx,
     2396                      int snum, uint32 jobid, WERROR *errcode)
    21562397{
    21572398        const char *sharename = lp_const_servicename(snum);
     
    21752416
    21762417        if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
    2177             !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
     2418            !print_access_check(server_info, msg_ctx, snum,
     2419                                JOB_ACCESS_ADMINISTER)) {
    21782420                DEBUG(3, ("resume denied by security descriptor\n"));
    21792421                *errcode = WERR_ACCESS_DENIED;
     
    21842426pause, or resume print job. User name: %s. Printer name: %s.",
    21852427                              uidtoname(server_info->utok.uid),
    2186                               PRINTERNAME(snum) );
     2428                              lp_printername(snum) );
    21872429                /* END_ADMIN_LOG */
    21882430                return False;
     
    22012443        /* Send a printer notify message */
    22022444
    2203         notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
     2445        notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
     2446                          JOB_STATUS_QUEUED);
    22042447
    22052448        return True;
     
    22102453****************************************************************************/
    22112454
    2212 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
     2455ssize_t print_job_write(struct tevent_context *ev,
     2456                        struct messaging_context *msg_ctx,
     2457                        int snum, uint32 jobid, const char *buf, size_t size)
    22132458{
    22142459        const char* sharename = lp_const_servicename(snum);
    2215         int return_code;
     2460        ssize_t return_code;
    22162461        struct printjob *pjob;
    22172462
     
    22242469                return -1;
    22252470
    2226         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
     2471        /* if SMBD is spooling this can't be allowed */
     2472        if (pjob->status == PJOB_SMBD_SPOOLING) {
     2473                return -1;
     2474        }
     2475
     2476        return_code = write_data(pjob->fd, buf, size);
    22272477
    22282478        if (return_code>0) {
    22292479                pjob->size += size;
    2230                 pjob_store(sharename, jobid, pjob);
     2480                pjob_store(ev, msg_ctx, sharename, jobid, pjob);
    22312481        }
    22322482        return return_code;
     
    22712521****************************************************************************/
    22722522
    2273 int print_queue_length(int snum, print_status_struct *pstatus)
     2523int print_queue_length(struct messaging_context *msg_ctx, int snum,
     2524                       print_status_struct *pstatus)
    22742525{
    22752526        const char* sharename = lp_const_servicename( snum );
     
    22812532        /* make sure the database is up to date */
    22822533        if (print_cache_expired(lp_const_servicename(snum), True))
    2283                 print_queue_update(snum, False);
     2534                print_queue_update(msg_ctx, snum, False);
    22842535
    22852536        /* also fetch the queue status */
     
    22972548***************************************************************************/
    22982549
    2299 static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
     2550static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
     2551                                   const char *sharename, uint32 *pjobid)
    23002552{
    23012553        int i;
    23022554        uint32 jobid;
     2555        enum TDB_ERROR terr;
     2556        int ret;
    23032557
    23042558        *pjobid = (uint32)-1;
     
    23062560        for (i = 0; i < 3; i++) {
    23072561                /* Lock the database - only wait 20 seconds. */
    2308                 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
    2309                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
    2310                         return False;
     2562                ret = tdb_lock_bystring_with_timeout(pdb->tdb,
     2563                                                     "INFO/nextjob", 20);
     2564                if (ret == -1) {
     2565                        DEBUG(0, ("allocate_print_jobid: "
     2566                                  "Failed to lock printing database %s\n",
     2567                                  sharename));
     2568                        terr = tdb_error(pdb->tdb);
     2569                        return ntstatus_to_werror(map_nt_error_from_tdb(terr));
    23112570                }
    23122571
    23132572                if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
    2314                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
    2315                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
    2316                                         sharename));
     2573                        terr = tdb_error(pdb->tdb);
     2574                        if (terr != TDB_ERR_NOEXIST) {
     2575                                DEBUG(0, ("allocate_print_jobid: "
     2576                                          "Failed to fetch INFO/nextjob "
     2577                                          "for print queue %s\n", sharename));
    23172578                                tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
    2318                                 return False;
     2579                                return ntstatus_to_werror(map_nt_error_from_tdb(terr));
    23192580                        }
    2320                         DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename));
     2581                        DEBUG(10, ("allocate_print_jobid: "
     2582                                   "No existing jobid in %s\n", sharename));
    23212583                        jobid = 0;
    23222584                }
    23232585
    2324                 DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename));
     2586                DEBUG(10, ("allocate_print_jobid: "
     2587                           "Read jobid %u from %s\n", jobid, sharename));
    23252588
    23262589                jobid = NEXT_JOBID(jobid);
    23272590
    2328                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
    2329                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
     2591                ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
     2592                if (ret == -1) {
     2593                        terr = tdb_error(pdb->tdb);
     2594                        DEBUG(3, ("allocate_print_jobid: "
     2595                                  "Failed to store INFO/nextjob.\n"));
    23302596                        tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
    2331                         return False;
     2597                        return ntstatus_to_werror(map_nt_error_from_tdb(terr));
    23322598                }
    23332599
     
    23382604                        break;
    23392605                }
    2340                 DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename));
     2606                DEBUG(10, ("allocate_print_jobid: "
     2607                           "Found jobid %u in %s\n", jobid, sharename));
    23412608        }
    23422609
    23432610        if (i > 2) {
    2344                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
    2345                         sharename));
     2611                DEBUG(0, ("allocate_print_jobid: "
     2612                          "Failed to allocate a print job for queue %s\n",
     2613                          sharename));
    23462614                /* Probably full... */
    2347                 errno = ENOSPC;
    2348                 return False;
     2615                return WERR_NO_SPOOL_SPACE;
    23492616        }
    23502617
     
    23572624                if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
    23582625                              TDB_INSERT) == -1) {
    2359                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
    2360                                 jobid ));
    2361                         return False;
     2626                        DEBUG(3, ("allocate_print_jobid: "
     2627                                  "jobid (%d) failed to store placeholder.\n",
     2628                                  jobid ));
     2629                        terr = tdb_error(pdb->tdb);
     2630                        return ntstatus_to_werror(map_nt_error_from_tdb(terr));
    23622631                }
    23632632        }
    23642633
    23652634        *pjobid = jobid;
    2366         return True;
     2635        return WERR_OK;
    23672636}
    23682637
    23692638/***************************************************************************
    2370  Append a jobid to the 'jobs changed' list.
     2639 Append a jobid to the 'jobs added' list.
    23712640***************************************************************************/
    23722641
    2373 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
     2642static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
    23742643{
    23752644        TDB_DATA data;
     
    23802649        data.dsize = 4;
    23812650
    2382         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
    2383 
    2384         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
     2651        DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
     2652
     2653        return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
    23852654                           data) == 0);
     2655}
     2656
     2657
     2658/***************************************************************************
     2659 Do all checks needed to determine if we can start a job.
     2660***************************************************************************/
     2661
     2662static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
     2663                               struct messaging_context *msg_ctx,
     2664                               int snum, int *njobs)
     2665{
     2666        const char *sharename = lp_const_servicename(snum);
     2667        uint64_t dspace, dsize;
     2668        uint64_t minspace;
     2669        int ret;
     2670
     2671        if (!print_access_check(server_info, msg_ctx, snum,
     2672                                PRINTER_ACCESS_USE)) {
     2673                DEBUG(3, ("print_job_checks: "
     2674                          "job start denied by security descriptor\n"));
     2675                return WERR_ACCESS_DENIED;
     2676        }
     2677
     2678        if (!print_time_access_check(server_info, msg_ctx, sharename)) {
     2679                DEBUG(3, ("print_job_checks: "
     2680                          "job start denied by time check\n"));
     2681                return WERR_ACCESS_DENIED;
     2682        }
     2683
     2684        /* see if we have sufficient disk space */
     2685        if (lp_minprintspace(snum)) {
     2686                minspace = lp_minprintspace(snum);
     2687                ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
     2688                if (ret == 0 && dspace < 2*minspace) {
     2689                        DEBUG(3, ("print_job_checks: "
     2690                                  "disk space check failed.\n"));
     2691                        return WERR_NO_SPOOL_SPACE;
     2692                }
     2693        }
     2694
     2695        /* for autoloaded printers, check that the printcap entry still exists */
     2696        if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
     2697                DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
     2698                          sharename));
     2699                return WERR_ACCESS_DENIED;
     2700        }
     2701
     2702        /* Insure the maximum queue size is not violated */
     2703        *njobs = print_queue_length(msg_ctx, snum, NULL);
     2704        if (*njobs > lp_maxprintjobs(snum)) {
     2705                DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
     2706                          "larger than max printjobs per queue (%d).\n",
     2707                          sharename, *njobs, lp_maxprintjobs(snum)));
     2708                return WERR_NO_SPOOL_SPACE;
     2709        }
     2710
     2711        return WERR_OK;
     2712}
     2713
     2714/***************************************************************************
     2715 Create a job file.
     2716***************************************************************************/
     2717
     2718static WERROR print_job_spool_file(int snum, uint32_t jobid,
     2719                                   const char *output_file,
     2720                                   struct printjob *pjob)
     2721{
     2722        WERROR werr;
     2723        SMB_STRUCT_STAT st;
     2724        const char *path;
     2725        int len;
     2726
     2727        /* if this file is within the printer path, it means that smbd
     2728         * is spooling it and will pass us control when it is finished.
     2729         * Verify that the file name is ok, within path, and it is
     2730         * already already there */
     2731        if (output_file) {
     2732                path = lp_pathname(snum);
     2733                len = strlen(path);
     2734                if (strncmp(output_file, path, len) == 0 &&
     2735                    (output_file[len - 1] == '/' || output_file[len] == '/')) {
     2736
     2737                        /* verify path is not too long */
     2738                        if (strlen(output_file) >= sizeof(pjob->filename)) {
     2739                                return WERR_INVALID_NAME;
     2740                        }
     2741
     2742                        /* verify that the file exists */
     2743                        if (sys_stat(output_file, &st, false) != 0) {
     2744                                return WERR_INVALID_NAME;
     2745                        }
     2746
     2747                        fstrcpy(pjob->filename, output_file);
     2748
     2749                        DEBUG(3, ("print_job_spool_file:"
     2750                                  "External spooling activated"));
     2751
     2752                        /* we do not open the file until spooling is done */
     2753                        pjob->fd = -1;
     2754                        pjob->status = PJOB_SMBD_SPOOLING;
     2755
     2756                        return WERR_OK;
     2757                }
     2758        }
     2759
     2760        slprintf(pjob->filename, sizeof(pjob->filename)-1,
     2761                 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
     2762                 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
     2763        pjob->fd = mkstemp(pjob->filename);
     2764
     2765        if (pjob->fd == -1) {
     2766                werr = map_werror_from_unix(errno);
     2767                if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
     2768                        /* Common setup error, force a report. */
     2769                        DEBUG(0, ("print_job_spool_file: "
     2770                                  "insufficient permissions to open spool "
     2771                                  "file %s.\n", pjob->filename));
     2772                } else {
     2773                        /* Normal case, report at level 3 and above. */
     2774                        DEBUG(3, ("print_job_spool_file: "
     2775                                  "can't open spool file %s\n",
     2776                                  pjob->filename));
     2777                }
     2778                return werr;
     2779        }
     2780
     2781        return WERR_OK;
    23862782}
    23872783
     
    23902786***************************************************************************/
    23912787
    2392 uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum,
    2393                        const char *jobname, NT_DEVICEMODE *nt_devmode )
    2394 {
    2395         uint32 jobid;
     2788WERROR print_job_start(const struct auth_serversupplied_info *server_info,
     2789                       struct messaging_context *msg_ctx,
     2790                       const char *clientmachine,
     2791                       int snum, const char *docname, const char *filename,
     2792                       struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
     2793{
     2794        uint32_t jobid;
    23962795        char *path;
    23972796        struct printjob pjob;
     
    23992798        struct tdb_print_db *pdb = get_print_db_byname(sharename);
    24002799        int njobs;
    2401 
    2402         errno = 0;
    2403 
    2404         if (!pdb)
    2405                 return (uint32)-1;
    2406 
    2407         if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) {
    2408                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
     2800        WERROR werr;
     2801
     2802        if (!pdb) {
     2803                return WERR_INTERNAL_DB_CORRUPTION;
     2804        }
     2805
     2806        path = lp_pathname(snum);
     2807
     2808        werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
     2809        if (!W_ERROR_IS_OK(werr)) {
    24092810                release_print_db(pdb);
    2410                 return (uint32)-1;
    2411         }
    2412 
    2413         if (!print_time_access_check(lp_servicename(snum))) {
    2414                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
    2415                 release_print_db(pdb);
    2416                 return (uint32)-1;
    2417         }
    2418 
    2419         path = lp_pathname(snum);
    2420 
    2421         /* see if we have sufficient disk space */
    2422         if (lp_minprintspace(snum)) {
    2423                 uint64_t dspace, dsize;
    2424                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
    2425                     dspace < 2*(uint64_t)lp_minprintspace(snum)) {
    2426                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
    2427                         release_print_db(pdb);
    2428                         errno = ENOSPC;
    2429                         return (uint32)-1;
    2430                 }
    2431         }
    2432 
    2433         /* for autoloaded printers, check that the printcap entry still exists */
    2434         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
    2435                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
    2436                 release_print_db(pdb);
    2437                 errno = ENOENT;
    2438                 return (uint32)-1;
    2439         }
    2440 
    2441         /* Insure the maximum queue size is not violated */
    2442         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
    2443                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
    2444                         sharename, njobs, lp_maxprintjobs(snum) ));
    2445                 release_print_db(pdb);
    2446                 errno = ENOSPC;
    2447                 return (uint32)-1;
    2448         }
    2449 
    2450         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
    2451                 sharename, njobs, lp_maxprintjobs(snum) ));
    2452 
    2453         if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
     2811                return werr;
     2812        }
     2813
     2814        DEBUG(10, ("print_job_start: "
     2815                   "Queue %s number of jobs (%d), max printjobs = %d\n",
     2816                   sharename, njobs, lp_maxprintjobs(snum)));
     2817
     2818        werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
     2819        if (!W_ERROR_IS_OK(werr)) {
    24542820                goto fail;
     2821        }
    24552822
    24562823        /* create the database entry */
     
    24662833        pjob.spooled = False;
    24672834        pjob.smbjob = True;
    2468         pjob.nt_devmode = nt_devmode;
    2469 
    2470         fstrcpy(pjob.jobname, jobname);
     2835        pjob.devmode = devmode;
     2836
     2837        fstrcpy(pjob.jobname, docname);
     2838
     2839        fstrcpy(pjob.clientmachine, clientmachine);
    24712840
    24722841        fstrcpy(pjob.user, lp_printjob_username(snum));
     
    24742843                              path, server_info->utok.gid,
    24752844                              server_info->sanitized_username,
    2476                               pdb_get_domain(server_info->sam_account),
     2845                              server_info->info3->base.domain.string,
    24772846                              pjob.user, sizeof(pjob.user)-1);
    24782847        /* ensure NULL termination */
     
    24822851
    24832852        /* we have a job entry - now create the spool file */
    2484         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
    2485                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
    2486         pjob.fd = mkstemp(pjob.filename);
    2487 
    2488         if (pjob.fd == -1) {
    2489                 if (errno == EACCES) {
    2490                         /* Common setup error, force a report. */
    2491                         DEBUG(0, ("print_job_start: insufficient permissions \
    2492 to open spool file %s.\n", pjob.filename));
    2493                 } else {
    2494                         /* Normal case, report at level 3 and above. */
    2495                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
    2496                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
    2497                 }
     2853        werr = print_job_spool_file(snum, jobid, filename, &pjob);
     2854        if (!W_ERROR_IS_OK(werr)) {
    24982855                goto fail;
    24992856        }
    25002857
    2501         pjob_store(sharename, jobid, &pjob);
    2502 
    2503         /* Update the 'jobs changed' entry used by print_queue_status. */
    2504         add_to_jobs_changed(pdb, jobid);
     2858        pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
     2859
     2860        /* Update the 'jobs added' entry used by print_queue_status. */
     2861        add_to_jobs_added(pdb, jobid);
    25052862
    25062863        /* Ensure we keep a rough count of the number of total jobs... */
     
    25092866        release_print_db(pdb);
    25102867
    2511         return jobid;
    2512 
    2513  fail:
    2514         if (jobid != -1)
    2515                 pjob_delete(sharename, jobid);
     2868        *_jobid = jobid;
     2869        return WERR_OK;
     2870
     2871fail:
     2872        if (jobid != -1) {
     2873                pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
     2874        }
    25162875
    25172876        release_print_db(pdb);
    25182877
    2519         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
    2520         return (uint32)-1;
     2878        DEBUG(3, ("print_job_start: returning fail. "
     2879                  "Error = %s\n", win_errstr(werr)));
     2880        return werr;
    25212881}
    25222882
     
    25252885****************************************************************************/
    25262886
    2527 void print_job_endpage(int snum, uint32 jobid)
     2887void print_job_endpage(struct messaging_context *msg_ctx,
     2888                       int snum, uint32 jobid)
    25282889{
    25292890        const char* sharename = lp_const_servicename(snum);
     
    25382899
    25392900        pjob->page_count++;
    2540         pjob_store(sharename, jobid, pjob);
     2901        pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
    25412902}
    25422903
     
    25472908****************************************************************************/
    25482909
    2549 bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
     2910NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
     2911                       uint32 jobid, enum file_close_type close_type)
    25502912{
    25512913        const char* sharename = lp_const_servicename(snum);
     
    25542916        SMB_STRUCT_STAT sbuf;
    25552917        struct printif *current_printif = get_printer_fns( snum );
     2918        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    25562919
    25572920        pjob = print_job_find(sharename, jobid);
    25582921
    2559         if (!pjob)
    2560                 return False;
    2561 
    2562         if (pjob->spooled || pjob->pid != sys_getpid())
    2563                 return False;
    2564 
    2565         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
    2566             (sys_fstat(pjob->fd, &sbuf, false) == 0)) {
     2922        if (!pjob) {
     2923                return NT_STATUS_PRINT_CANCELLED;
     2924        }
     2925
     2926        if (pjob->spooled || pjob->pid != sys_getpid()) {
     2927                return NT_STATUS_ACCESS_DENIED;
     2928        }
     2929
     2930        if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
     2931                if (pjob->status == PJOB_SMBD_SPOOLING) {
     2932                        /* take over the file now, smbd is done */
     2933                        if (sys_stat(pjob->filename, &sbuf, false) != 0) {
     2934                                status = map_nt_error_from_unix(errno);
     2935                                DEBUG(3, ("print_job_end: "
     2936                                          "stat file failed for jobid %d\n",
     2937                                          jobid));
     2938                                goto fail;
     2939                        }
     2940
     2941                        pjob->status = LPQ_SPOOLING;
     2942
     2943                } else {
     2944
     2945                        if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
     2946                                status = map_nt_error_from_unix(errno);
     2947                                close(pjob->fd);
     2948                                DEBUG(3, ("print_job_end: "
     2949                                          "stat file failed for jobid %d\n",
     2950                                          jobid));
     2951                                goto fail;
     2952                        }
     2953
     2954                        close(pjob->fd);
     2955                }
     2956
    25672957                pjob->size = sbuf.st_ex_size;
    2568                 close(pjob->fd);
    2569                 pjob->fd = -1;
    25702958        } else {
    25712959
    25722960                /*
    2573                  * Not a normal close or we couldn't stat the job file,
    2574                  * so something has gone wrong. Cleanup.
     2961                 * Not a normal close, something has gone wrong. Cleanup.
    25752962                 */
    2576                 close(pjob->fd);
    2577                 pjob->fd = -1;
    2578                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
     2963                if (pjob->fd != -1) {
     2964                        close(pjob->fd);
     2965                }
    25792966                goto fail;
    25802967        }
     
    25882975                        pjob->filename, pjob->size ? "deleted" : "zero length" ));
    25892976                unlink(pjob->filename);
    2590                 pjob_delete(sharename, jobid);
    2591                 return True;
     2977                pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
     2978                return NT_STATUS_OK;
    25922979        }
    25932980
    25942981        ret = (*(current_printif->job_submit))(snum, pjob);
    25952982
    2596         if (ret)
     2983        if (ret) {
     2984                status = NT_STATUS_PRINT_CANCELLED;
    25972985                goto fail;
     2986        }
    25982987
    25992988        /* The print job has been successfully handed over to the back-end */
     
    26012990        pjob->spooled = True;
    26022991        pjob->status = LPQ_QUEUED;
    2603         pjob_store(sharename, jobid, pjob);
     2992        pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
    26042993
    26052994        /* make sure the database is up to date */
    26062995        if (print_cache_expired(lp_const_servicename(snum), True))
    2607                 print_queue_update(snum, False);
    2608 
    2609         return True;
     2996                print_queue_update(msg_ctx, snum, False);
     2997
     2998        return NT_STATUS_OK;
    26102999
    26113000fail:
     
    26133002        /* The print job was not successfully started. Cleanup */
    26143003        /* Still need to add proper error return propagation! 010122:JRR */
     3004        pjob->fd = -1;
    26153005        unlink(pjob->filename);
    2616         pjob_delete(sharename, jobid);
    2617         return False;
     3006        pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
     3007        return status;
    26183008}
    26193009
     
    26223012****************************************************************************/
    26233013
    2624 static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
    2625 {
    2626         TDB_DATA data, cgdata;
     3014static bool get_stored_queue_info(struct messaging_context *msg_ctx,
     3015                                  struct tdb_print_db *pdb, int snum,
     3016                                  int *pcount, print_queue_struct **ppqueue)
     3017{
     3018        TDB_DATA data, cgdata, jcdata;
    26273019        print_queue_struct *queue = NULL;
    26283020        uint32 qcount = 0;
    26293021        uint32 extra_count = 0;
     3022        uint32_t changed_count = 0;
    26303023        int total_count = 0;
    26313024        size_t len = 0;
     
    26373030        /* make sure the database is up to date */
    26383031        if (print_cache_expired(lp_const_servicename(snum), True))
    2639                 print_queue_update(snum, False);
     3032                print_queue_update(msg_ctx, snum, False);
    26403033
    26413034        *pcount = 0;
     
    26513044                len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
    26523045
    2653         /* Get the changed jobs list. */
    2654         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
     3046        /* Get the added jobs list. */
     3047        cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
    26553048        if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
    26563049                extra_count = cgdata.dsize/4;
     3050
     3051        /* Get the changed jobs list. */
     3052        jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
     3053        if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
     3054                changed_count = jcdata.dsize / 4;
    26573055
    26583056        DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
     
    26883086        total_count = qcount;
    26893087
    2690         /* Add in the changed jobids. */
     3088        /* Add new jobids to the queue. */
    26913089        for( i  = 0; i < extra_count; i++) {
    26923090                uint32 jobid;
     
    26943092
    26953093                jobid = IVAL(cgdata.dptr, i*4);
    2696                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
     3094                DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
    26973095                pjob = print_job_find(lp_const_servicename(snum), jobid);
    26983096                if (!pjob) {
    2699                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
    2700                         remove_from_jobs_changed(sharename, jobid);
     3097                        DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
     3098                        remove_from_jobs_added(sharename, jobid);
    27013099                        continue;
    27023100                }
     
    27133111        }
    27143112
     3113        /* Update the changed jobids. */
     3114        for (i = 0; i < changed_count; i++) {
     3115                uint32_t jobid = IVAL(jcdata.dptr, i * 4);
     3116                uint32_t j;
     3117                bool found = false;
     3118
     3119                for (j = 0; j < total_count; j++) {
     3120                        if (queue[j].job == jobid) {
     3121                                found = true;
     3122                                break;
     3123                        }
     3124                }
     3125
     3126                if (found) {
     3127                        struct printjob *pjob;
     3128
     3129                        DEBUG(5,("get_stored_queue_info: changed job: %u\n",
     3130                                 (unsigned int) jobid));
     3131
     3132                        pjob = print_job_find(sharename, jobid);
     3133                        if (pjob == NULL) {
     3134                                DEBUG(5,("get_stored_queue_info: failed to find "
     3135                                         "changed job = %u\n",
     3136                                         (unsigned int) jobid));
     3137                                remove_from_jobs_changed(sharename, jobid);
     3138                                continue;
     3139                        }
     3140
     3141                        queue[j].job = jobid;
     3142                        queue[j].size = pjob->size;
     3143                        queue[j].page_count = pjob->page_count;
     3144                        queue[j].status = pjob->status;
     3145                        queue[j].priority = 1;
     3146                        queue[j].time = pjob->starttime;
     3147                        fstrcpy(queue[j].fs_user, pjob->user);
     3148                        fstrcpy(queue[j].fs_file, pjob->jobname);
     3149
     3150                        DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
     3151                                 (unsigned int) j, (unsigned int) jobid, pjob->jobname));
     3152                }
     3153
     3154                remove_from_jobs_changed(sharename, jobid);
     3155        }
     3156
    27153157        /* Sort the queue by submission time otherwise they are displayed
    27163158           in hash order. */
    27173159
    2718         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
     3160        TYPESAFE_QSORT(queue, total_count, printjob_comp);
    27193161
    27203162        DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
     
    27403182****************************************************************************/
    27413183
    2742 int print_queue_status(int snum,
     3184int print_queue_status(struct messaging_context *msg_ctx, int snum,
    27433185                       print_queue_struct **ppqueue,
    27443186                       print_status_struct *status)
     
    27533195
    27543196        if (print_cache_expired(lp_const_servicename(snum), True))
    2755                 print_queue_update(snum, False);
     3197                print_queue_update(msg_ctx, snum, False);
    27563198
    27573199        /* return if we are done */
     
    27903232         */
    27913233
    2792         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
     3234        if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
    27933235                release_print_db(pdb);
    27943236                return 0;
     
    28033245****************************************************************************/
    28043246
    2805 WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
     3247WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
     3248                         struct messaging_context *msg_ctx, int snum)
    28063249{
    28073250        int ret;
    28083251        struct printif *current_printif = get_printer_fns( snum );
    28093252
    2810         if (!print_access_check(server_info, snum,
     3253        if (!print_access_check(server_info, msg_ctx, snum,
    28113254                                PRINTER_ACCESS_ADMINISTER)) {
    28123255                return WERR_ACCESS_DENIED;
     
    28293272        /* Send a printer notify message */
    28303273
    2831         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
     3274        notify_printer_status(server_event_context(), msg_ctx, snum,
     3275                              PRINTER_STATUS_PAUSED);
    28323276
    28333277        return WERR_OK;
     
    28383282****************************************************************************/
    28393283
    2840 WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum)
     3284WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
     3285                          struct messaging_context *msg_ctx, int snum)
    28413286{
    28423287        int ret;
    28433288        struct printif *current_printif = get_printer_fns( snum );
    28443289
    2845         if (!print_access_check(server_info, snum,
     3290        if (!print_access_check(server_info, msg_ctx, snum,
    28463291                                PRINTER_ACCESS_ADMINISTER)) {
    28473292                return WERR_ACCESS_DENIED;
     
    28603305        /* make sure the database is up to date */
    28613306        if (print_cache_expired(lp_const_servicename(snum), True))
    2862                 print_queue_update(snum, True);
     3307                print_queue_update(msg_ctx, snum, True);
    28633308
    28643309        /* Send a printer notify message */
    28653310
    2866         notify_printer_status(snum, PRINTER_STATUS_OK);
     3311        notify_printer_status(server_event_context(), msg_ctx, snum,
     3312                              PRINTER_STATUS_OK);
    28673313
    28683314        return WERR_OK;
     
    28733319****************************************************************************/
    28743320
    2875 WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
     3321WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
     3322                         struct messaging_context *msg_ctx, int snum)
    28763323{
    28773324        print_queue_struct *queue;
     
    28813328
    28823329        /* Force and update so the count is accurate (i.e. not a cached count) */
    2883         print_queue_update(snum, True);
    2884 
    2885         can_job_admin = print_access_check(server_info, snum,
     3330        print_queue_update(msg_ctx, snum, True);
     3331
     3332        can_job_admin = print_access_check(server_info,
     3333                                           msg_ctx,
     3334                                           snum,
    28863335                                           JOB_ACCESS_ADMINISTER);
    2887         njobs = print_queue_status(snum, &queue, &status);
     3336        njobs = print_queue_status(msg_ctx, snum, &queue, &status);
    28883337
    28893338        if ( can_job_admin )
     
    28953344
    28963345                if (owner || can_job_admin) {
    2897                         print_job_delete1(snum, queue[i].job);
     3346                        print_job_delete1(server_event_context(), msg_ctx,
     3347                                          snum, queue[i].job);
    28983348                }
    28993349        }
     
    29033353
    29043354        /* update the cache */
    2905         print_queue_update( snum, True );
     3355        print_queue_update(msg_ctx, snum, True);
    29063356
    29073357        SAFE_FREE(queue);
  • vendor/current/source3/printing/printing_db.c

    r414 r740  
    2121
    2222#include "includes.h"
     23#include "system/filesys.h"
    2324#include "printing.h"
     25#include "util_tdb.h"
    2426
    2527static struct tdb_print_db *print_db_head;
     
    99101        }
    100102
    101         if (geteuid() != 0) {
     103        if (geteuid() != sec_initial_uid()) {
    102104                become_root();
    103105                done_become_root = True;
     
    159161****************************************************************************/
    160162
    161 TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, bool cleanlist)
     163struct TDB_DATA get_printer_notify_pid_list(struct tdb_context *tdb, const char *printer_name, bool cleanlist)
    162164{
    163165        TDB_DATA data;
  • vendor/current/source3/printing/tests/vlp.c

    r414 r740  
    2121
    2222#include "includes.h"
     23#include "system/passwd.h"
     24#include "system/filesys.h"
     25#include "printing.h"
     26#include "util_tdb.h"
    2327
    2428#ifdef malloc
Note: See TracChangeset for help on using the changeset viewer.