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

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified 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}
Note: See TracChangeset for help on using the changeset viewer.