s3-secrets: only include secrets.h when needed.
[amitay/samba.git] / source3 / printing / nt_printing.c
index 2cb2ce690a0909435b4e14841a43859f8a06d553..9ead42df5b6b11b148fc02621305adbc77d241de 100644 (file)
 #include "includes.h"
 #include "librpc/gen_ndr/messaging.h"
 #include "printing/pcap.h"
+#include "printing/nt_printing_tdb.h"
+#include "printing/nt_printing_migrate.h"
 #include "registry.h"
 #include "registry/reg_objects.h"
 #include "../librpc/gen_ndr/ndr_security.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
 #include "rpc_server/srv_spoolss_util.h"
-
-#include "../rpc_server/srv_spoolss_util.h"
-
-static TDB_CONTEXT *tdb_forms; /* used for forms files */
-static TDB_CONTEXT *tdb_drivers; /* used for driver files */
-static TDB_CONTEXT *tdb_printers; /* used for printers files */
-
-#define FORMS_PREFIX "FORMS/"
-#define DRIVERS_PREFIX "DRIVERS/"
-#define PRINTERS_PREFIX "PRINTERS/"
-#define SECDESC_PREFIX "SECDESC/"
-#define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
-
-#define NTDRIVERS_DATABASE_VERSION_1 1
-#define NTDRIVERS_DATABASE_VERSION_2 2
-#define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
-#define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */
-#define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */
+#include "nt_printing.h"
+#include "secrets.h"
 
 /* Map generic permissions to printer object specific permissions */
 
@@ -54,13 +41,6 @@ const struct generic_mapping printer_generic_mapping = {
        PRINTER_ALL_ACCESS
 };
 
-const struct standard_mapping printer_std_mapping = {
-       PRINTER_READ,
-       PRINTER_WRITE,
-       PRINTER_EXECUTE,
-       PRINTER_ALL_ACCESS
-};
-
 /* Map generic permissions to print server object specific permissions */
 
 const struct generic_mapping printserver_generic_mapping = {
@@ -70,13 +50,6 @@ const struct generic_mapping printserver_generic_mapping = {
        SERVER_ALL_ACCESS
 };
 
-const struct generic_mapping printserver_std_mapping = {
-       SERVER_READ,
-       SERVER_WRITE,
-       SERVER_EXECUTE,
-       SERVER_ALL_ACCESS
-};
-
 /* Map generic permissions to job object specific permissions */
 
 const struct generic_mapping job_generic_mapping = {
@@ -86,133 +59,6 @@ const struct generic_mapping job_generic_mapping = {
        JOB_ALL_ACCESS
 };
 
-/* We need one default form to support our default printer. Msoft adds the
-forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
-array index). Letter is always first, so (for the current code) additions
-always put things in the correct order. */
-static const nt_forms_struct default_forms[] = {
-       {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
-       {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
-       {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
-       {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
-       {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
-       {"A0",0x1,0xcd528,0x122488,0x0,0x0,0xcd528,0x122488},
-       {"A1",0x1,0x91050,0xcd528,0x0,0x0,0x91050,0xcd528},
-       {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
-       {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
-       {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
-       {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
-       {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
-       {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
-       {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
-       {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
-       {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
-       {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
-       {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
-       {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
-       {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
-       {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
-       {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
-       {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
-       {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
-       {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
-       {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
-       {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
-       {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
-       {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
-       {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
-       {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
-       {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
-       {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
-       {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
-       {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
-       {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
-       {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
-       {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
-       {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
-       {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
-       {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
-       {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
-       {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
-       {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
-       {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
-       {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
-       {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
-       {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
-       {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
-       {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
-       {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
-       {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
-       {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
-       {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
-       {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
-       {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
-       {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
-       {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
-       {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
-       {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
-       {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
-       {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
-       {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
-       {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
-       {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
-       {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
-       {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
-       {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
-       {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
-       {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
-       {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
-       {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
-       {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
-       {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
-       {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
-       {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
-       {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
-       {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
-       {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
-       {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
-       {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
-       {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
-       {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
-       {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
-       {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
-       {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
-       {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
-       {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
-       {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
-       {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
-       {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
-       {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
-       {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
-       {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
-       {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
-       {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
-       {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
-       {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
-       {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
-       {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
-       {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
-       {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
-       {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
-       {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
-       {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
-       {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
-       {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
-       {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
-       {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
-       {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
-       {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
-       {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
-       {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
-       {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
-       {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
-       {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
-       {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
-};
-
 static const struct print_architecture_table_node archi_table[]= {
 
        {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
@@ -225,393 +71,22 @@ static const struct print_architecture_table_node archi_table[]= {
        {NULL,                   "",            -1 }
 };
 
-
-/****************************************************************************
- generate a new TDB_DATA key for storing a printer
-****************************************************************************/
-
-static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
-{
-       fstring share;
-       char *keystr = NULL;
-       TDB_DATA key;
-
-       fstrcpy(share, sharename);
-       strlower_m(share);
-
-       keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
-       key = string_term_tdb_data(keystr ? keystr : "");
-
-       return key;
-}
-
-/****************************************************************************
- generate a new TDB_DATA key for storing a printer security descriptor
-****************************************************************************/
-
-static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
-                                       const char* sharename  )
-{
-       fstring share;
-       char *keystr = NULL;
-       TDB_DATA key;
-
-       fstrcpy(share, sharename );
-       strlower_m(share);
-
-       keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
-       key = string_term_tdb_data(keystr ? keystr : "");
-
-       return key;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool upgrade_to_version_3(void)
-{
-       TDB_DATA kbuf, newkey, dbuf;
-
-       DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
-
-       for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
-                       newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
-
-               dbuf = tdb_fetch(tdb_drivers, kbuf);
-
-               if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
-                       DEBUG(0,("upgrade_to_version_3:moving form\n"));
-                       if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
-                               return False;
-                       }
-                       if (tdb_delete(tdb_drivers, kbuf) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
-                               return False;
-                       }
-               }
-
-               if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
-                       DEBUG(0,("upgrade_to_version_3:moving printer\n"));
-                       if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
-                               return False;
-                       }
-                       if (tdb_delete(tdb_drivers, kbuf) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
-                               return False;
-                       }
-               }
-
-               if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
-                       DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
-                       if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
-                               return False;
-                       }
-                       if (tdb_delete(tdb_drivers, kbuf) != 0) {
-                               SAFE_FREE(dbuf.dptr);
-                               DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
-                               return False;
-                       }
-               }
-
-               SAFE_FREE(dbuf.dptr);
-       }
-
-       return True;
-}
-
-/*******************************************************************
- Fix an issue with security descriptors.  Printer sec_desc must
- use more than the generic bits that were previously used
- in <= 3.0.14a.  They must also have a owner and group SID assigned.
- Otherwise, any printers than have been migrated to a Windows
- host using printmig.exe will not be accessible.
-*******************************************************************/
-
-static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
-                            TDB_DATA data, void *state )
-{
-       NTSTATUS status;
-       struct sec_desc_buf *sd_orig = NULL;
-       struct sec_desc_buf *sd_new, *sd_store;
-       struct security_descriptor *sec, *new_sec;
-       TALLOC_CTX *ctx = state;
-       int result, i;
-       uint32 sd_size;
-       size_t size_new_sec;
-
-       if (!data.dptr || data.dsize == 0) {
-               return 0;
-       }
-
-       if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
-               return 0;
-       }
-
-       /* upgrade the security descriptor */
-
-       status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
-       if (!NT_STATUS_IS_OK(status)) {
-               /* delete bad entries */
-               DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si.  Deleting....\n",
-                       (const char *)key.dptr ));
-               tdb_delete( tdb_printers, key );
-               return 0;
-       }
-
-       if (!sd_orig) {
-               return 0;
-       }
-       sec = sd_orig->sd;
-
-       /* is this even valid? */
-
-       if ( !sec->dacl ) {
-               return 0;
-       }
-
-       /* update access masks */
-
-       for ( i=0; i<sec->dacl->num_aces; i++ ) {
-               switch ( sec->dacl->aces[i].access_mask ) {
-                       case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
-                               sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
-                               break;
-
-                       case GENERIC_ALL_ACCESS:
-                               sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
-                               break;
-
-                       case READ_CONTROL_ACCESS:
-                               sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
-
-                       default:        /* no change */
-                               break;
-               }
-       }
-
-       /* create a new struct security_descriptor with the appropriate owner and group SIDs */
-
-       new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
-                                &global_sid_Builtin_Administrators,
-                                &global_sid_Builtin_Administrators,
-                                NULL, NULL, &size_new_sec );
-       if (!new_sec) {
-               return 0;
-       }
-       sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
-       if (!sd_new) {
-               return 0;
-       }
-
-       if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
-               DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
-               return 0;
-       }
-
-       /* store it back */
-
-       sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
-               + sizeof(struct sec_desc_buf);
-
-       status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
-               return 0;
-       }
-
-       result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
-
-       /* 0 to continue and non-zero to stop traversal */
-
-       return (result == -1);
-}
-
-/*******************************************************************
-*******************************************************************/
-
-static bool upgrade_to_version_4(void)
-{
-       TALLOC_CTX *ctx;
-       int result;
-
-       DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
-
-       if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
-               return False;
-
-       result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
-
-       talloc_destroy( ctx );
-
-       return ( result != -1 );
-}
-
-/*******************************************************************
- Fix an issue with security descriptors.  Printer sec_desc must
- use more than the generic bits that were previously used
- in <= 3.0.14a.  They must also have a owner and group SID assigned.
- Otherwise, any printers than have been migrated to a Windows
- host using printmig.exe will not be accessible.
-*******************************************************************/
-
-static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
-                                  TDB_DATA data, void *state )
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       TDB_DATA new_key;
-
-       if (!data.dptr || data.dsize == 0)
-               return 0;
-
-       /* upgrade printer records and security descriptors */
-
-       if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
-               new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
-       }
-       else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
-               new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
-       }
-       else {
-               /* ignore this record */
-               return 0;
-       }
-
-       /* delete the original record and store under the normalized key */
-
-       if ( tdb_delete( the_tdb, key ) != 0 ) {
-               DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
-                       key.dptr));
-               return 1;
-       }
-
-       if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
-               DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
-                       key.dptr));
-               return 1;
-       }
-
-       return 0;
-}
-
-/*******************************************************************
-*******************************************************************/
-
-static bool upgrade_to_version_5(void)
-{
-       TALLOC_CTX *ctx;
-       int result;
-
-       DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
-
-       if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
-               return False;
-
-       result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
-
-       talloc_destroy( ctx );
-
-       return ( result != -1 );
-}
-
 /****************************************************************************
  Open the NT printing tdbs. Done once before fork().
 ****************************************************************************/
 
 bool nt_printing_init(struct messaging_context *msg_ctx)
 {
-       const char *vstring = "INFO/version";
        WERROR win_rc;
-       int32 vers_id;
-
-       if ( tdb_drivers && tdb_printers && tdb_forms )
-               return True;
-
-       if (tdb_drivers)
-               tdb_close(tdb_drivers);
-       tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       if (!tdb_drivers) {
-               DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
-                       state_path("ntdrivers.tdb"), strerror(errno) ));
-               return False;
-       }
-
-       if (tdb_printers)
-               tdb_close(tdb_printers);
-       tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       if (!tdb_printers) {
-               DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
-                       state_path("ntprinters.tdb"), strerror(errno) ));
-               return False;
-       }
 
-       if (tdb_forms)
-               tdb_close(tdb_forms);
-       tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-       if (!tdb_forms) {
-               DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
-                       state_path("ntforms.tdb"), strerror(errno) ));
-               return False;
-       }
-
-       /* handle a Samba upgrade */
-
-       vers_id = tdb_fetch_int32(tdb_drivers, vstring);
-       if (vers_id == -1) {
-               DEBUG(10, ("Fresh database\n"));
-               tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 );
-               vers_id = NTDRIVERS_DATABASE_VERSION_5;
-       }
-
-       if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
-
-               if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
-                       if (!upgrade_to_version_3())
-                               return False;
-                       tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
-                       vers_id = NTDRIVERS_DATABASE_VERSION_3;
-               }
-
-               if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
-                       /* Written on a bigendian machine with old fetch_int code. Save as le. */
-                       /* The only upgrade between V2 and V3 is to save the version in little-endian. */
-                       tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
-                       vers_id = NTDRIVERS_DATABASE_VERSION_3;
-               }
-
-               if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) {
-                       if ( !upgrade_to_version_4() )
-                               return False;
-                       tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
-                       vers_id = NTDRIVERS_DATABASE_VERSION_4;
-               }
-
-               if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
-                       if ( !upgrade_to_version_5() )
-                               return False;
-                       tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
-                       vers_id = NTDRIVERS_DATABASE_VERSION_5;
-               }
-
-
-               if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
-                       DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
-                       return False;
-               }
+       if (!nt_printing_tdb_upgrade()) {
+               return false;
        }
 
        /*
         * register callback to handle updating printers as new
         * drivers are installed
         */
-
        messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
                           do_drv_upgrade_printer);
 
@@ -619,14 +94,13 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
           tell messages.c that you interested in receiving PRINT_GENERAL
           msgs.  This is done in serverid_register() */
 
-
        if ( lp_security() == SEC_ADS ) {
                win_rc = check_published_printers();
                if (!W_ERROR_IS_OK(win_rc))
                        DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
        }
 
-       return True;
+       return true;
 }
 
 /*******************************************************************
@@ -659,367 +133,66 @@ static NTSTATUS driver_unix_convert(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
-/*******************************************************************
- tdb traversal function for counting printers.
-********************************************************************/
-
-static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
-                                      TDB_DATA data, void *context)
-{
-       int *printer_count = (int*)context;
-
-       if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
-               (*printer_count)++;
-               DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
-       }
-
-       return 0;
-}
-
-/*******************************************************************
- Update the spooler global c_setprinter. This variable is initialized
- when the parent smbd starts with the number of existing printers. It
- is monotonically increased by the current number of printers *after*
- each add or delete printer RPC. Only Microsoft knows why... JRR020119
-********************************************************************/
+/****************************************************************************
+ Function to do the mapping between the long architecture name and
+ the short one.
+****************************************************************************/
 
-uint32 update_c_setprinter(bool initialize)
+const char *get_short_archi(const char *long_archi)
 {
-       int32 c_setprinter;
-       int32 printer_count = 0;
-
-       tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
-
-       /* Traverse the tdb, counting the printers */
-       tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
-
-       /* If initializing, set c_setprinter to current printers count
-        * otherwise, bump it by the current printer count
-        */
-       if (!initialize)
-               c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
-       else
-               c_setprinter = printer_count;
-
-       DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
-       tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
-
-       tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
-
-       return (uint32)c_setprinter;
-}
+        int i=-1;
 
-/*******************************************************************
- Get the spooler global c_setprinter, accounting for initialization.
-********************************************************************/
+        DEBUG(107,("Getting architecture dependant directory\n"));
+        do {
+                i++;
+        } while ( (archi_table[i].long_archi!=NULL ) &&
+                  StrCaseCmp(long_archi, archi_table[i].long_archi) );
 
-uint32 get_c_setprinter(void)
-{
-       int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
+        if (archi_table[i].long_archi==NULL) {
+                DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
+                return NULL;
+        }
 
-       if (c_setprinter == (int32)-1)
-               c_setprinter = update_c_setprinter(True);
+       /* this might be client code - but shouldn't this be an fstrcpy etc? */
 
-       DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
+        DEBUGADD(108,("index: [%d]\n", i));
+        DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
+        DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
 
-       return (uint32)c_setprinter;
+       return archi_table[i].short_archi;
 }
 
 /****************************************************************************
- Get builtin form struct list.
+ Version information in Microsoft files is held in a VS_VERSION_INFO structure.
+ There are two case to be covered here: PE (Portable Executable) and NE (New
+ Executable) files. Both files support the same INFO structure, but PE files
+ store the signature in unicode, and NE files store it as !unicode.
+ returns -1 on error, 1 on version info found, and 0 on no version info found.
 ****************************************************************************/
 
-int get_builtin_ntforms(nt_forms_struct **list)
+static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
 {
-       *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
-       if (!*list) {
-               return 0;
+       int     i;
+       char    *buf = NULL;
+       ssize_t byte_count;
+
+       if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
+               DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
+                               fname, DOS_HEADER_SIZE));
+               goto error_exit;
        }
-       return ARRAY_SIZE(default_forms);
-}
 
-/****************************************************************************
- get a builtin form struct
-****************************************************************************/
+       if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
+               DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
+                        fname, (unsigned long)byte_count));
+               goto no_version_info;
+       }
 
-bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
-{
-       int i;
-       DEBUGADD(6,("Looking for builtin form %s \n", form_name));
-       for (i=0; i<ARRAY_SIZE(default_forms); i++) {
-               if (strequal(form_name,default_forms[i].name)) {
-                       DEBUGADD(6,("Found builtin form %s \n", form_name));
-                       memcpy(form,&default_forms[i],sizeof(*form));
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-/****************************************************************************
- get a form struct list.
-****************************************************************************/
-
-int get_ntforms(nt_forms_struct **list)
-{
-       TDB_DATA kbuf, newkey, dbuf;
-       nt_forms_struct form;
-       int ret;
-       int i;
-       int n = 0;
-
-       *list = NULL;
-
-       for (kbuf = tdb_firstkey(tdb_forms);
-            kbuf.dptr;
-            newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)
-       {
-               if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
-                       continue;
-
-               dbuf = tdb_fetch(tdb_forms, kbuf);
-               if (!dbuf.dptr)
-                       continue;
-
-               fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
-               ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
-                                &i, &form.flag, &form.width, &form.length, &form.left,
-                                &form.top, &form.right, &form.bottom);
-               SAFE_FREE(dbuf.dptr);
-               if (ret != dbuf.dsize)
-                       continue;
-
-               *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
-               if (!*list) {
-                       DEBUG(0,("get_ntforms: Realloc fail.\n"));
-                       return 0;
-               }
-               (*list)[n] = form;
-               n++;
-       }
-
-
-       return n;
-}
-
-/****************************************************************************
-write a form struct list
-****************************************************************************/
-
-int write_ntforms(nt_forms_struct **list, int number)
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       char *buf = NULL;
-       char *key = NULL;
-       int len;
-       TDB_DATA dbuf;
-       int i;
-
-       for (i=0;i<number;i++) {
-               /* save index, so list is rebuilt in correct order */
-               len = tdb_pack(NULL, 0, "dddddddd",
-                              i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
-                              (*list)[i].left, (*list)[i].top, (*list)[i].right,
-                              (*list)[i].bottom);
-               if (!len) {
-                       continue;
-               }
-               buf = TALLOC_ARRAY(ctx, char, len);
-               if (!buf) {
-                       return 0;
-               }
-               len = tdb_pack((uint8 *)buf, len, "dddddddd",
-                              i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
-                              (*list)[i].left, (*list)[i].top, (*list)[i].right,
-                              (*list)[i].bottom);
-               key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);
-               if (!key) {
-                       return 0;
-               }
-               dbuf.dsize = len;
-               dbuf.dptr = (uint8 *)buf;
-               if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {
-                       TALLOC_FREE(key);
-                       TALLOC_FREE(buf);
-                       break;
-               }
-               TALLOC_FREE(key);
-               TALLOC_FREE(buf);
-       }
-
-       return i;
-}
-
-/****************************************************************************
-add a form struct at the end of the list
-****************************************************************************/
-bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)
-{
-       int n=0;
-       bool update;
-
-       /*
-        * NT tries to add forms even when
-        * they are already in the base
-        * only update the values if already present
-        */
-
-       update=False;
-
-       for (n=0; n<*count; n++) {
-               if ( strequal((*list)[n].name, form->form_name) ) {
-                       update=True;
-                       break;
-               }
-       }
-
-       if (update==False) {
-               if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
-                       DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
-                       return False;
-               }
-               fstrcpy((*list)[n].name, form->form_name);
-               (*count)++;
-       }
-
-       (*list)[n].flag         = form->flags;
-       (*list)[n].width        = form->size.width;
-       (*list)[n].length       = form->size.height;
-       (*list)[n].left         = form->area.left;
-       (*list)[n].top          = form->area.top;
-       (*list)[n].right        = form->area.right;
-       (*list)[n].bottom       = form->area.bottom;
-
-       DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
-               update ? "updated" : "added", form->form_name));
-
-       return True;
-}
-
-/****************************************************************************
- Delete a named form struct.
-****************************************************************************/
-
-bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)
-{
-       char *key = NULL;
-       int n=0;
-
-       *ret = WERR_OK;
-
-       for (n=0; n<*count; n++) {
-               if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {
-                       DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));
-                       break;
-               }
-       }
-
-       if (n == *count) {
-               DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
-               *ret = WERR_INVALID_FORM_NAME;
-               return False;
-       }
-
-       if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {
-               *ret = WERR_NOMEM;
-               return false;
-       }
-       if (tdb_delete_bystring(tdb_forms, key) != 0) {
-               SAFE_FREE(key);
-               *ret = WERR_NOMEM;
-               return False;
-       }
-       SAFE_FREE(key);
-       return true;
-}
-
-/****************************************************************************
- Update a form struct.
-****************************************************************************/
-
-void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)
-{
-       int n=0;
-
-       DEBUG(106, ("[%s]\n", form->form_name));
-       for (n=0; n<count; n++) {
-               DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
-               if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))
-                       break;
-       }
-
-       if (n==count) return;
-
-       (*list)[n].flag         = form->flags;
-       (*list)[n].width        = form->size.width;
-       (*list)[n].length       = form->size.height;
-       (*list)[n].left         = form->area.left;
-       (*list)[n].top          = form->area.top;
-       (*list)[n].right        = form->area.right;
-       (*list)[n].bottom       = form->area.bottom;
-}
-
-/****************************************************************************
- Function to do the mapping between the long architecture name and
- the short one.
-****************************************************************************/
-
-const char *get_short_archi(const char *long_archi)
-{
-        int i=-1;
-
-        DEBUG(107,("Getting architecture dependant directory\n"));
-        do {
-                i++;
-        } while ( (archi_table[i].long_archi!=NULL ) &&
-                  StrCaseCmp(long_archi, archi_table[i].long_archi) );
-
-        if (archi_table[i].long_archi==NULL) {
-                DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
-                return NULL;
-        }
-
-       /* this might be client code - but shouldn't this be an fstrcpy etc? */
-
-        DEBUGADD(108,("index: [%d]\n", i));
-        DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
-        DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
-
-       return archi_table[i].short_archi;
-}
-
-/****************************************************************************
- Version information in Microsoft files is held in a VS_VERSION_INFO structure.
- There are two case to be covered here: PE (Portable Executable) and NE (New
- Executable) files. Both files support the same INFO structure, but PE files
- store the signature in unicode, and NE files store it as !unicode.
- returns -1 on error, 1 on version info found, and 0 on no version info found.
-****************************************************************************/
-
-static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
-{
-       int     i;
-       char    *buf = NULL;
-       ssize_t byte_count;
-
-       if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
-               DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
-                               fname, DOS_HEADER_SIZE));
-               goto error_exit;
-       }
-
-       if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
-               DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
-                        fname, (unsigned long)byte_count));
-               goto no_version_info;
-       }
-
-       /* Is this really a DOS header? */
-       if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
-               DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
-                               fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
-               goto no_version_info;
+       /* Is this really a DOS header? */
+       if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
+               DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
+                               fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
+               goto no_version_info;
        }
 
        /* Skip OEM header (if any) and the DOS stub to start of Windows header */
@@ -1968,256 +1141,6 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
        return (*perr);
 }
 
-/****************************************************************************
-****************************************************************************/
-int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
-{
-       enum ndr_err_code ndr_err;
-       DATA_BLOB blob;
-       int len = 0;
-
-       if (devmode) {
-               ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
-                                              devmode,
-                                              (ndr_push_flags_fn_t)
-                                              ndr_push_spoolss_DeviceMode);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       DEBUG(10, ("pack_devicemode: "
-                                  "error encoding spoolss_DeviceMode\n"));
-                       goto done;
-               }
-       } else {
-               ZERO_STRUCT(blob);
-       }
-
-       len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
-
-       if (devmode) {
-               DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
-       }
-
-done:
-       return len;
-}
-
-/****************************************************************************
-****************************************************************************/
-int unpack_devicemode(TALLOC_CTX *mem_ctx,
-                     const uint8 *buf, int buflen,
-                     struct spoolss_DeviceMode **devmode)
-{
-       struct spoolss_DeviceMode *dm;
-       enum ndr_err_code ndr_err;
-       char *data = NULL;
-       int data_len = 0;
-       DATA_BLOB blob;
-       int len = 0;
-
-       *devmode = NULL;
-
-       len = tdb_unpack(buf, buflen, "B", &data_len, &data);
-       if (!data) {
-               return len;
-       }
-
-       dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
-       if (!dm) {
-               goto done;
-       }
-
-       blob = data_blob_const(data, data_len);
-
-       ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
-                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DEBUG(10, ("unpack_devicemode: "
-                          "error parsing spoolss_DeviceMode\n"));
-               goto done;
-       }
-
-       DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
-                 dm->devicename, dm->formname));
-       if (dm->driverextra_data.data) {
-               DEBUG(8, ("with a private section of %d bytes\n",
-                         dm->__driverextra_length));
-       }
-
-       *devmode = dm;
-
-done:
-       SAFE_FREE(data);
-       return len;
-}
-
-/****************************************************************************
- Pack all values in all printer keys
- ***************************************************************************/
-
-static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
-{
-       int             len = 0;
-       int             i, j;
-       struct regval_blob      *val;
-       struct regval_ctr       *val_ctr;
-       char *path = NULL;
-       int             num_values;
-
-       if ( !data )
-               return 0;
-
-       /* loop over all keys */
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               val_ctr = data->keys[i].values;
-               num_values = regval_ctr_numvals( val_ctr );
-
-               /* pack the keyname followed by a empty value */
-
-               len += tdb_pack(buf+len, buflen-len, "pPdB",
-                               &data->keys[i].name,
-                               data->keys[i].name,
-                               REG_NONE,
-                               0,
-                               NULL);
-
-               /* now loop over all values */
-
-               for ( j=0; j<num_values; j++ ) {
-                       /* pathname should be stored as <key>\<value> */
-
-                       val = regval_ctr_specific_value( val_ctr, j );
-                       if (asprintf(&path, "%s\\%s",
-                                       data->keys[i].name,
-                                       regval_name(val)) < 0) {
-                               return -1;
-                       }
-
-                       len += tdb_pack(buf+len, buflen-len, "pPdB",
-                                       val,
-                                       path,
-                                       regval_type(val),
-                                       regval_size(val),
-                                       regval_data_p(val) );
-
-                       DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
-                       SAFE_FREE(path);
-               }
-
-       }
-
-       /* terminator */
-
-       len += tdb_pack(buf+len, buflen-len, "p", NULL);
-
-       return len;
-}
-
-
-/****************************************************************************
-****************************************************************************/
-static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
-       uint8 *buf;
-       int buflen, len;
-       int retlen;
-       WERROR ret;
-       TDB_DATA kbuf, dbuf;
-
-       /*
-        * in addprinter: no servername and the printer is the name
-        * in setprinter: servername is \\server
-        *                and printer is \\server\\printer
-        *
-        * Samba manages only local printers.
-        * we currently don't support things like i
-        * path=\\other_server\printer
-        *
-        * We only store the printername, not \\server\printername
-        */
-
-       if ( info->servername[0] != '\0' ) {
-               trim_string(info->printername, info->servername, NULL);
-               trim_char(info->printername, '\\', '\0');
-               info->servername[0]='\0';
-       }
-
-       /*
-        * JFM: one day I'll forget.
-        * below that's info->portname because that's the SAMBA sharename
-        * and I made NT 'thinks' it's the portname
-        * the info->sharename is the thing you can name when you add a printer
-        * that's the short-name when you create shared printer for 95/98
-        * So I've made a limitation in SAMBA: you can only have 1 printer model
-        * behind a SAMBA share.
-        */
-
-       buf = NULL;
-       buflen = 0;
-
- again:
-       len = 0;
-       len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
-                       info->attributes,
-                       info->priority,
-                       info->default_priority,
-                       info->starttime,
-                       info->untiltime,
-                       info->status,
-                       info->cjobs,
-                       info->averageppm,
-                       info->changeid,
-                       info->c_setprinter,
-                       info->setuptime,
-                       info->servername,
-                       info->printername,
-                       info->sharename,
-                       info->portname,
-                       info->drivername,
-                       info->comment,
-                       info->location,
-                       info->sepfile,
-                       info->printprocessor,
-                       info->datatype,
-                       info->parameters);
-
-       len += pack_devicemode(info->devmode, buf+len, buflen-len);
-       retlen = pack_values( info->data, buf+len, buflen-len );
-       if (retlen == -1) {
-               ret = WERR_NOMEM;
-               goto done;
-       }
-       len += retlen;
-
-       if (buflen != len) {
-               buf = (uint8 *)SMB_REALLOC(buf, len);
-               if (!buf) {
-                       DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
-                       ret = WERR_NOMEM;
-                       goto done;
-               }
-               buflen = len;
-               goto again;
-       }
-
-       kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
-
-       dbuf.dptr = buf;
-       dbuf.dsize = len;
-
-       ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
-
-done:
-       if (!W_ERROR_IS_OK(ret))
-               DEBUG(8, ("error updating printer to tdb on disk\n"));
-
-       SAFE_FREE(buf);
-
-       DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
-                info->sharename, info->drivername, info->portname, len));
-
-       return ret;
-}
-
 /****************************************************************************
  Create and allocate a default devicemode.
 ****************************************************************************/
@@ -2351,977 +1274,43 @@ WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
 
        /* add BUILTIN\Print Operators as FULL CONTROL */
 
-       sa = PRINTER_ACE_FULL_CONTROL;
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-               SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED,
-               sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* Make the security descriptor owned by the BUILTIN\Administrators */
-
-       /* The ACL revision number in rpc_secdesc.h differs from the one
-          created by NT when setting ACE entries in printer
-          descriptors.  NT4 complains about the property being edited by a
-          NT5 machine. */
-
-       if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
-               psd = make_sec_desc(mem_ctx,
-                                   SD_REVISION,
-                                   SEC_DESC_SELF_RELATIVE,
-                                   &global_sid_Builtin_Administrators,
-                                   &global_sid_Builtin_Administrators,
-                                   NULL,
-                                   psa,
-                                   &sd_size);
-       }
-
-       if (psd == NULL) {
-               DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
-               return WERR_NOMEM;
-       }
-
-       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
-                (unsigned int)sd_size));
-
-       *secdesc = psd;
-
-       return WERR_OK;
-}
-
-/****************************************************************************
- Allocate and initialize a new slot.
-***************************************************************************/
-
-int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
-{
-       NT_PRINTER_KEY  *d;
-       int             key_index;
-       WERROR werr;
-
-       if ( !name || !data )
-               return -1;
-
-       /* allocate another slot in the NT_PRINTER_KEY array */
-
-       if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
-               DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
-               return -1;
-       }
-
-       data->keys = d;
-
-       key_index = data->num_keys;
-
-       /* initialze new key */
-
-       data->keys[key_index].name = talloc_strdup( data, name );
-
-       werr = regval_ctr_init(data, &(data->keys[key_index].values));
-       if (!W_ERROR_IS_OK(werr)) {
-               return -1;
-       }
-
-       data->num_keys++;
-
-       DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
-
-       return key_index;
-}
-
-/****************************************************************************
- search for a registry key name in the existing printer data
- ***************************************************************************/
-
-int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
-{
-       int i;
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( strequal( data->keys[i].name, name ) ) {
-
-                       /* cleanup memory */
-
-                       TALLOC_FREE( data->keys[i].name );
-                       TALLOC_FREE( data->keys[i].values );
-
-                       /* if not the end of the array, move remaining elements down one slot */
-
-                       data->num_keys--;
-                       if ( data->num_keys && (i < data->num_keys) )
-                               memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
-
-                       break;
-               }
-       }
-
-
-       return data->num_keys;
-}
-
-/****************************************************************************
- search for a registry key name in the existing printer data
- ***************************************************************************/
-
-int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
-{
-       int             key_index = -1;
-       int             i;
-
-       if ( !data || !name )
-               return -1;
-
-       DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
-
-       /* loop over all existing keys */
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( strequal(data->keys[i].name, name) ) {
-                       DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
-                       key_index = i;
-                       break;
-
-               }
-       }
-
-       return key_index;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
-{
-       int     i, j;
-       int     key_len;
-       int     num_subkeys = 0;
-       char    *p;
-       fstring *subkeys_ptr = NULL;
-       fstring subkeyname;
-
-       *subkeys = NULL;
-
-       if ( !data )
-               return 0;
-
-       if ( !key )
-               return -1;
-
-       /* special case of asking for the top level printer data registry key names */
-
-       if ( strlen(key) == 0 ) {
-               for ( i=0; i<data->num_keys; i++ ) {
-
-                       /* found a match, so allocate space and copy the name */
-
-                       if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
-                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
-                                       num_subkeys+1));
-                               return -1;
-                       }
-
-                       fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
-                       num_subkeys++;
-               }
-
-               goto done;
-       }
-
-       /* asking for the subkeys of some key */
-       /* subkey paths are stored in the key name using '\' as the delimiter */
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
-
-                       /* if we found the exact key, then break */
-                       key_len = strlen( key );
-                       if ( strlen(data->keys[i].name) == key_len )
-                               break;
-
-                       /* get subkey path */
-
-                       p = data->keys[i].name + key_len;
-                       if ( *p == '\\' )
-                               p++;
-                       fstrcpy( subkeyname, p );
-                       if ( (p = strchr( subkeyname, '\\' )) )
-                               *p = '\0';
-
-                       /* don't add a key more than once */
-
-                       for ( j=0; j<num_subkeys; j++ ) {
-                               if ( strequal( subkeys_ptr[j], subkeyname ) )
-                                       break;
-                       }
-
-                       if ( j != num_subkeys )
-                               continue;
-
-                       /* found a match, so allocate space and copy the name */
-
-                       if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
-                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
-                                       num_subkeys+1));
-                               return 0;
-                       }
-
-                       fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
-                       num_subkeys++;
-               }
-
-       }
-
-       /* return error if the key was not found */
-
-       if ( i == data->num_keys ) {
-               SAFE_FREE(subkeys_ptr);
-               return -1;
-       }
-
-done:
-       /* tag off the end */
-
-       if (num_subkeys)
-               fstrcpy(subkeys_ptr[num_subkeys], "" );
-
-       *subkeys = subkeys_ptr;
-
-       return num_subkeys;
-}
-
-#ifdef HAVE_ADS
-static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
-                           const char *sz)
-{
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue_sz(ctr, val_name, sz);
-}
-
-static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
-                              uint32 dword)
-{
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_DWORD,
-                           (uint8 *) &dword, sizeof(dword));
-}
-
-static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
-                             bool b)
-{
-       uint8 bin_bool = (b ? 1 : 0);
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_BINARY,
-                           (uint8 *) &bin_bool, sizeof(bin_bool));
-}
-
-static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
-                                        const char *multi_sz)
-{
-       const char *a[2];
-
-       a[0] = multi_sz;
-       a[1] = NULL;
-
-       regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue_multi_sz(ctr, val_name, a);
-}
-
-/****************************************************************************
- * Map spoolss_PrinterInfo2 data into DsSpooler keys for publishing.
- *
- * @param mem_ctx  allocation context
- * @param info2    spoolss_PrinterInfo2 describing printer
- * @param pdata    the talloced printer data
- * @return bool    indicating success or failure
- ***************************************************************************/
-
-static bool map_nt_printer_info2_to_dsspooler(TALLOC_CTX *mem_ctx,
-                                             struct spoolss_PrinterInfo2 *info2,
-                                             NT_PRINTER_DATA **pdata)
-{
-       NT_PRINTER_DATA *data;
-       struct regval_ctr *ctr = NULL;
-       fstring longname;
-       const char *dnssuffix;
-       char *allocated_string = NULL;
-        const char *ascii_str;
-       int i;
-
-       data = talloc_zero(mem_ctx, NT_PRINTER_DATA);
-       if (!data) return false;
-
-       /* init data */
-       i = add_new_printer_key(data, SPOOL_DSSPOOLER_KEY);
-       ctr = data->keys[i].values;
-
-       map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
-       map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
-
-       /* we make the assumption that the netbios name is the same
-          as the DNS name sinc ethe former will be what we used to
-          join the domain */
-
-       dnssuffix = get_mydnsdomname(talloc_tos());
-       if (dnssuffix && *dnssuffix) {
-               fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
-       } else {
-               fstrcpy( longname, global_myname() );
-       }
-
-       map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
-
-       if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) {
-               talloc_free(data);
-               return false;
-       }
-       map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
-       SAFE_FREE(allocated_string);
-
-       map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
-       map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
-       map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
-       map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
-       map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
-       map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
-       map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
-       map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
-       map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
-
-       map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
-                         (info2->attributes &
-                          PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
-
-       switch (info2->attributes & 0x3) {
-       case 0:
-               ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
-               break;
-       case 1:
-               ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
-               break;
-       case 2:
-               ascii_str = SPOOL_REGVAL_PRINTDIRECT;
-               break;
-       default:
-               ascii_str = "unknown";
-       }
-       map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
-
-       *pdata = data;
-       return true;
-}
-
-/*****************************************************************
- ****************************************************************/
-
-static void store_printer_guid(const char *printer, struct GUID guid)
-{
-       TALLOC_CTX *tmp_ctx;
-       struct auth_serversupplied_info *server_info = NULL;
-       const char *guid_str;
-       DATA_BLOB blob;
-       NTSTATUS status;
-       WERROR result;
-
-       tmp_ctx = talloc_new(NULL);
-       if (!tmp_ctx) {
-               DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
-               return;
-       }
-
-       status = make_server_info_system(tmp_ctx, &server_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("store_printer_guid: "
-                         "Could not create system server_info\n"));
-               goto done;
-       }
-
-       guid_str = GUID_string(tmp_ctx, &guid);
-       if (!guid_str) {
-               DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
-               goto done;
-       }
-
-       /* We used to store this as a REG_BINARY but that causes
-          Vista to whine */
-
-       if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
-               DEBUG(0, ("store_printer_guid: "
-                         "Could not marshall string %s for objectGUID\n",
-                         guid_str));
-               goto done;
-       }
-
-       result = winreg_set_printer_dataex(tmp_ctx, server_info, printer,
-                                          SPOOL_DSSPOOLER_KEY, "objectGUID",
-                                          REG_SZ, blob.data, blob.length);
-       if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("store_printer_guid: "
-                         "Failed to store GUID for printer %s\n", printer));
-       }
-
-done:
-       talloc_free(tmp_ctx);
-}
-
-static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
-                                    struct spoolss_PrinterInfo2 *pinfo2)
-{
-       ADS_STATUS ads_rc;
-       LDAPMessage *res;
-       char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
-       char *srv_dn_utf8, **srv_cn_utf8;
-       TALLOC_CTX *ctx;
-       ADS_MODLIST mods;
-       const char *attrs[] = {"objectGUID", NULL};
-       struct GUID guid;
-       WERROR win_rc = WERR_OK;
-       size_t converted_size;
-       NT_PRINTER_DATA *pdata;
-       const char *printer = pinfo2->sharename;
-
-       /* build the ads mods */
-       ctx = talloc_init("nt_printer_publish_ads");
-       if (ctx == NULL) {
-               return WERR_NOMEM;
-       }
-
-       DEBUG(5, ("publishing printer %s\n", printer));
-
-       if (!map_nt_printer_info2_to_dsspooler(ctx, pinfo2, &pdata)) {
-               TALLOC_FREE(ctx);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-
-       /* figure out where to publish */
-       ads_find_machine_acct(ads, &res, global_myname());
-
-       /* We use ldap_get_dn here as we need the answer
-        * in utf8 to call ldap_explode_dn(). JRA. */
-
-       srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
-       if (!srv_dn_utf8) {
-               TALLOC_FREE(ctx);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       ads_msgfree(ads, res);
-       srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
-       if (!srv_cn_utf8) {
-               TALLOC_FREE(ctx);
-               ldap_memfree(srv_dn_utf8);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       /* Now convert to CH_UNIX. */
-       if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
-               TALLOC_FREE(ctx);
-               ldap_memfree(srv_dn_utf8);
-               ldap_memfree(srv_cn_utf8);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
-               TALLOC_FREE(ctx);
-               ldap_memfree(srv_dn_utf8);
-               ldap_memfree(srv_cn_utf8);
-               TALLOC_FREE(srv_dn);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-
-       ldap_memfree(srv_dn_utf8);
-       ldap_memfree(srv_cn_utf8);
-
-       srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
-       if (!srv_cn_escaped) {
-               TALLOC_FREE(ctx);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       sharename_escaped = escape_rdn_val_string_alloc(printer);
-       if (!sharename_escaped) {
-               SAFE_FREE(srv_cn_escaped);
-               TALLOC_FREE(ctx);
-               return WERR_SERVER_UNAVAILABLE;
-       }
-
-       prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
-
-       SAFE_FREE(srv_cn_escaped);
-       SAFE_FREE(sharename_escaped);
-
-       mods = ads_init_mods(ctx);
-
-       if (mods == NULL) {
-               SAFE_FREE(prt_dn);
-               TALLOC_FREE(ctx);
-               return WERR_NOMEM;
-       }
-
-       get_local_printer_publishing_data(ctx, &mods, pdata);
-       ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer);
-
-       /* publish it */
-       ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
-       if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
-               int i;
-               for (i=0; mods[i] != 0; i++)
-                       ;
-               mods[i] = (LDAPMod *)-1;
-               ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
-       }
-
-       if (!ADS_ERR_OK(ads_rc)) {
-               DEBUG(3, ("error publishing %s: %s\n",
-                         printer, ads_errstr(ads_rc)));
-       }
-
-       /* retreive the guid and store it locally */
-       if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
-               ZERO_STRUCT(guid);
-               ads_pull_guid(ads, res, &guid);
-               ads_msgfree(ads, res);
-               store_printer_guid(printer, guid);
-       }
-       TALLOC_FREE(ctx);
-
-       return win_rc;
-}
-
-static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
-                                       const char *printer)
-{
-       ADS_STATUS ads_rc;
-       LDAPMessage *res = NULL;
-       char *prt_dn = NULL;
-
-       DEBUG(5, ("unpublishing printer %s\n", printer));
-
-       /* remove the printer from the directory */
-       ads_rc = ads_find_printer_on_server(ads, &res,
-                                           printer, global_myname());
-
-       if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
-               prt_dn = ads_get_dn(ads, talloc_tos(), res);
-               if (!prt_dn) {
-                       ads_msgfree(ads, res);
-                       return WERR_NOMEM;
-               }
-               ads_rc = ads_del_dn(ads, prt_dn);
-               TALLOC_FREE(prt_dn);
-       }
-
-       if (res) {
-               ads_msgfree(ads, res);
-       }
-       return WERR_OK;
-}
-
-/****************************************************************************
- * Publish a printer in the directory
- *
- * @param mem_ctx      memory context
- * @param server_info  server_info to access winreg pipe
- * @param pinfo2       printer information
- * @param action       publish/unpublish action
- * @return WERROR indicating status of publishing
- ***************************************************************************/
-
-WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
-                         struct auth_serversupplied_info *server_info,
-                         struct spoolss_PrinterInfo2 *pinfo2,
-                         int action)
-{
-       uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
-       struct spoolss_SetPrinterInfo2 *sinfo2;
-       ADS_STATUS ads_rc;
-       ADS_STRUCT *ads = NULL;
-       WERROR win_rc;
-
-       sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
-       if (!sinfo2) {
-               return WERR_NOMEM;
-       }
-
-       switch (action) {
-       case DSPRINT_PUBLISH:
-       case DSPRINT_UPDATE:
-               pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
-               break;
-       case DSPRINT_UNPUBLISH:
-               pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
-               break;
-       default:
-               win_rc = WERR_NOT_SUPPORTED;
-               goto done;
-       }
-
-       sinfo2->attributes = pinfo2->attributes;
-
-       win_rc = winreg_update_printer(mem_ctx, server_info,
-                                       pinfo2->sharename, info2_mask,
-                                       sinfo2, NULL, NULL);
-       if (!W_ERROR_IS_OK(win_rc)) {
-               DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
-               goto done;
-       }
-
-       TALLOC_FREE(sinfo2);
-
-       ads = ads_init(lp_realm(), lp_workgroup(), NULL);
-       if (!ads) {
-               DEBUG(3, ("ads_init() failed\n"));
-               win_rc = WERR_SERVER_UNAVAILABLE;
-               goto done;
-       }
-       setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
-       SAFE_FREE(ads->auth.password);
-       ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
-               NULL, NULL);
-
-       /* ads_connect() will find the DC for us */
-       ads_rc = ads_connect(ads);
-       if (!ADS_ERR_OK(ads_rc)) {
-               DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
-               win_rc = WERR_ACCESS_DENIED;
-               goto done;
-       }
-
-       switch (action) {
-       case DSPRINT_PUBLISH:
-       case DSPRINT_UPDATE:
-               win_rc = nt_printer_publish_ads(ads, pinfo2);
-               break;
-       case DSPRINT_UNPUBLISH:
-               win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
-               break;
-       }
-
-done:
-       ads_destroy(&ads);
-       return win_rc;
-}
-
-WERROR check_published_printers(void)
-{
-       ADS_STATUS ads_rc;
-       ADS_STRUCT *ads = NULL;
-       int snum;
-       int n_services = lp_numservices();
-       TALLOC_CTX *tmp_ctx = NULL;
-       struct auth_serversupplied_info *server_info = NULL;
-       struct spoolss_PrinterInfo2 *pinfo2;
-       NTSTATUS status;
-       WERROR result;
-
-       tmp_ctx = talloc_new(NULL);
-       if (!tmp_ctx) return WERR_NOMEM;
-
-       ads = ads_init(lp_realm(), lp_workgroup(), NULL);
-       if (!ads) {
-               DEBUG(3, ("ads_init() failed\n"));
-               return WERR_SERVER_UNAVAILABLE;
-       }
-       setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
-       SAFE_FREE(ads->auth.password);
-       ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
-               NULL, NULL);
-
-       /* ads_connect() will find the DC for us */
-       ads_rc = ads_connect(ads);
-       if (!ADS_ERR_OK(ads_rc)) {
-               DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
-               result = WERR_ACCESS_DENIED;
-               goto done;
-       }
-
-       status = make_server_info_system(tmp_ctx, &server_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("check_published_printers: "
-                         "Could not create system server_info\n"));
-               result = WERR_ACCESS_DENIED;
-               goto done;
-       }
-
-       for (snum = 0; snum < n_services; snum++) {
-               if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
-                       continue;
-               }
-
-               result = winreg_get_printer(tmp_ctx, server_info, NULL,
-                                           lp_servicename(snum), &pinfo2);
-               if (!W_ERROR_IS_OK(result)) {
-                       continue;
-               }
-
-               if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
-                       nt_printer_publish_ads(ads, pinfo2);
-               }
-
-               TALLOC_FREE(pinfo2);
-       }
-
-       result = WERR_OK;
-done:
-       ads_destroy(&ads);
-       ads_kdestroy("MEMORY:prtpub_cache");
-       talloc_free(tmp_ctx);
-       return result;
-}
-
-bool is_printer_published(TALLOC_CTX *mem_ctx,
-                         struct auth_serversupplied_info *server_info,
-                         char *servername, char *printer, struct GUID *guid,
-                         struct spoolss_PrinterInfo2 **info2)
-{
-       struct spoolss_PrinterInfo2 *pinfo2 = NULL;
-       enum winreg_Type type;
-       uint8_t *data;
-       uint32_t data_size;
-       WERROR result;
-       NTSTATUS status;
-
-       result = winreg_get_printer(mem_ctx, server_info,
-                                   servername, printer, &pinfo2);
-       if (!W_ERROR_IS_OK(result)) {
-               return false;
-       }
-
-       if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
-               TALLOC_FREE(pinfo2);
-               return false;
-       }
-
-       if (!guid) {
-               goto done;
-       }
-
-       /* fetching printer guids really ought to be a separate function. */
-
-       result = winreg_get_printer_dataex(mem_ctx, server_info, printer,
-                                          SPOOL_DSSPOOLER_KEY, "objectGUID",
-                                          &type, &data, &data_size);
-       if (!W_ERROR_IS_OK(result)) {
-               TALLOC_FREE(pinfo2);
-               return false;
-       }
-
-       /* We used to store the guid as REG_BINARY, then swapped
-          to REG_SZ for Vista compatibility so check for both */
-
-       switch (type) {
-       case REG_SZ:
-               status = GUID_from_string((char *)data, guid);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(pinfo2);
-                       return false;
-               }
-               break;
-
-       case REG_BINARY:
-               if (data_size != sizeof(struct GUID)) {
-                       TALLOC_FREE(pinfo2);
-                       return false;
-               }
-               memcpy(guid, data, sizeof(struct GUID));
-               break;
-       default:
-               DEBUG(0,("is_printer_published: GUID value stored as "
-                        "invaluid type (%d)\n", type));
-               break;
-       }
-
-done:
-       if (info2) {
-               *info2 = talloc_move(mem_ctx, &pinfo2);
-       }
-       talloc_free(pinfo2);
-       return true;
-}
-#else
-WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
-                         struct auth_serversupplied_info *server_info,
-                         struct spoolss_PrinterInfo2 *pinfo2,
-                         int action)
-{
-       return WERR_OK;
-}
-
-WERROR check_published_printers(void)
-{
-       return WERR_OK;
-}
-
-bool is_printer_published(TALLOC_CTX *mem_ctx,
-                         struct auth_serversupplied_info *server_info,
-                         char *servername, char *printer, struct GUID *guid,
-                         struct spoolss_PrinterInfo2 **info2)
-{
-       return False;
-}
-#endif /* HAVE_ADS */
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
-{
-       NT_PRINTER_DATA *data;
-       int             i;
-       int             removed_keys = 0;
-       int             empty_slot;
-
-       data = p2->data;
-       empty_slot = data->num_keys;
-
-       if ( !key )
-               return WERR_INVALID_PARAM;
-
-       /* remove all keys */
-
-       if ( !strlen(key) ) {
-
-               TALLOC_FREE( data );
-
-               p2->data = NULL;
-
-               DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
-                       p2->printername ));
-
-               return WERR_OK;
-       }
-
-       /* remove a specific key (and all subkeys) */
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
-                       DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
-                               data->keys[i].name));
-
-                       TALLOC_FREE( data->keys[i].name );
-                       TALLOC_FREE( data->keys[i].values );
-
-                       /* mark the slot as empty */
-
-                       ZERO_STRUCTP( &data->keys[i] );
-               }
-       }
-
-       /* find the first empty slot */
-
-       for ( i=0; i<data->num_keys; i++ ) {
-               if ( !data->keys[i].name ) {
-                       empty_slot = i;
-                       removed_keys++;
-                       break;
-               }
-       }
-
-       if ( i == data->num_keys )
-               /* nothing was removed */
-               return WERR_INVALID_PARAM;
-
-       /* move everything down */
-
-       for ( i=empty_slot+1; i<data->num_keys; i++ ) {
-               if ( data->keys[i].name ) {
-                       memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
-                       ZERO_STRUCTP( &data->keys[i] );
-                       empty_slot++;
-                       removed_keys++;
-               }
-       }
-
-       /* update count */
-
-       data->num_keys -= removed_keys;
-
-       /* sanity check to see if anything is left */
-
-       if ( !data->num_keys ) {
-               DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
-
-               SAFE_FREE( data->keys );
-               ZERO_STRUCTP( data );
-       }
-
-       return WERR_OK;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
-       WERROR          result = WERR_OK;
-       int             key_index;
-
-       /* we must have names on non-zero length */
-
-       if ( !key || !*key|| !value || !*value )
-               return WERR_INVALID_NAME;
-
-       /* find the printer key first */
-
-       key_index = lookup_printerkey( p2->data, key );
-       if ( key_index == -1 )
-               return WERR_OK;
-
-       /* make sure the value exists so we can return the correct error code */
-
-       if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
-               return WERR_BADFILE;
-
-       regval_ctr_delvalue( p2->data->keys[key_index].values, value );
-
-       DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
-               key, value ));
-
-       return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
-                           uint32 type, uint8 *data, int real_len )
-{
-       WERROR          result = WERR_OK;
-       int             key_index;
-
-       /* we must have names on non-zero length */
-
-       if ( !key || !*key|| !value || !*value )
-               return WERR_INVALID_NAME;
-
-       /* find the printer key first */
-
-       key_index = lookup_printerkey( p2->data, key );
-       if ( key_index == -1 )
-               key_index = add_new_printer_key( p2->data, key );
-
-       if ( key_index == -1 )
-               return WERR_NOMEM;
-
-       regval_ctr_addvalue( p2->data->keys[key_index].values, value,
-               type, data, real_len );
+       sa = PRINTER_ACE_FULL_CONTROL;
+       init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
+               SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+               SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+       init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
+               SEC_ACE_TYPE_ACCESS_ALLOWED,
+               sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
-       DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
-               key, value, type, real_len  ));
+       /* Make the security descriptor owned by the BUILTIN\Administrators */
 
-       return result;
-}
+       /* The ACL revision number in rpc_secdesc.h differs from the one
+          created by NT when setting ACE entries in printer
+          descriptors.  NT4 complains about the property being edited by a
+          NT5 machine. */
 
-/****************************************************************************
- ***************************************************************************/
+       if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
+               psd = make_sec_desc(mem_ctx,
+                                   SD_REVISION,
+                                   SEC_DESC_SELF_RELATIVE,
+                                   &global_sid_Builtin_Administrators,
+                                   &global_sid_Builtin_Administrators,
+                                   NULL,
+                                   psa,
+                                   &sd_size);
+       }
 
-struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
-       int             key_index;
+       if (psd == NULL) {
+               DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
+               return WERR_NOMEM;
+       }
 
-       if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
-               return NULL;
+       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
+                (unsigned int)sd_size));
 
-       DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
-               key, value ));
+       *secdesc = psd;
 
-       return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
+       return WERR_OK;
 }
 
 /****************************************************************************
@@ -3466,176 +1455,6 @@ WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
        return WERR_OK;
 }
 
-/****************************************************************************
- Debugging function, dump at level 6 the struct in the logs.
-****************************************************************************/
-static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
-       uint32 result;
-       NT_PRINTER_INFO_LEVEL_2 *info2;
-
-       DEBUG(106,("Dumping printer at level [%d]\n", level));
-
-       switch (level) {
-               case 2:
-               {
-                       if (printer->info_2 == NULL)
-                               result=5;
-                       else
-                       {
-                               info2=printer->info_2;
-
-                               DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
-                               DEBUGADD(106,("priority:[%d]\n", info2->priority));
-                               DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
-                               DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
-                               DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
-                               DEBUGADD(106,("status:[%d]\n", info2->status));
-                               DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
-                               DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
-                               DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
-                               DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
-                               DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
-
-                               DEBUGADD(106,("servername:[%s]\n", info2->servername));
-                               DEBUGADD(106,("printername:[%s]\n", info2->printername));
-                               DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
-                               DEBUGADD(106,("portname:[%s]\n", info2->portname));
-                               DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
-                               DEBUGADD(106,("comment:[%s]\n", info2->comment));
-                               DEBUGADD(106,("location:[%s]\n", info2->location));
-                               DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
-                               DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
-                               DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
-                               DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
-                               result=0;
-                       }
-                       break;
-               }
-               default:
-                       DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
-                       result=1;
-                       break;
-       }
-
-       return result;
-}
-
-/****************************************************************************
- Update the changeid time.
- This is SO NASTY as some drivers need this to change, others need it
- static. This value will change every second, and I must hope that this
- is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
- UTAH ! JRA.
-****************************************************************************/
-
-static uint32 rev_changeid(void)
-{
-       struct timeval tv;
-
-       get_process_uptime(&tv);
-
-#if 1  /* JERRY */
-       /* Return changeid as msec since spooler restart */
-       return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#else
-       /*
-        * This setting seems to work well but is too untested
-        * to replace the above calculation.  Left in for experiementation
-        * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
-        */
-       return tv.tv_sec * 10 + tv.tv_usec / 100000;
-#endif
-}
-
-
-/*
- * The function below are the high level ones.
- * only those ones must be called from the spoolss code.
- * JFM.
- */
-
-/****************************************************************************
- Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
-****************************************************************************/
-
-WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
-       WERROR result;
-
-       dump_a_printer(printer, level);
-
-       switch (level) {
-               case 2:
-               {
-                       /*
-                        * Update the changestamp.  Emperical tests show that the
-                        * ChangeID is always updated,but c_setprinter is
-                        *  global spooler variable (not per printer).
-                        */
-
-                       /* ChangeID **must** be increasing over the lifetime
-                          of client's spoolss service in order for the
-                          client's cache to show updates */
-
-                       printer->info_2->changeid = rev_changeid();
-
-                       /*
-                        * Because one day someone will ask:
-                        * NT->NT       An admin connection to a remote
-                        *              printer show changes imeediately in
-                        *              the properities dialog
-                        *
-                        *              A non-admin connection will only show the
-                        *              changes after viewing the properites page
-                        *              2 times.  Seems to be related to a
-                        *              race condition in the client between the spooler
-                        *              updating the local cache and the Explorer.exe GUI
-                        *              actually displaying the properties.
-                        *
-                        *              This is fixed in Win2k.  admin/non-admin
-                        *              connections both display changes immediately.
-                        *
-                        * 14/12/01     --jerry
-                        */
-
-                       result=update_a_printer_2(printer->info_2);
-                       break;
-               }
-               default:
-                       result=WERR_UNKNOWN_LEVEL;
-                       break;
-       }
-
-       return result;
-}
-
-/****************************************************************************
- Deletes a NT_PRINTER_INFO_LEVEL struct.
-****************************************************************************/
-
-uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
-{
-       NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
-
-       if ( !printer )
-               return 0;
-
-       switch (level) {
-               case 2:
-                        TALLOC_FREE(printer->info_2);
-                       break;
-
-               default:
-                       DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
-                       return 1;
-       }
-
-       TALLOC_FREE(*pp_printer);
-
-       return 0;
-}
-
 /****************************************************************************
 ****************************************************************************/
 
@@ -4156,312 +1975,6 @@ bool delete_driver_files(struct auth_serversupplied_info *server_info,
        return ret;
 }
 
-/****************************************************************************
- Store a security desc for a printer.
-****************************************************************************/
-
-WERROR nt_printing_setsec(const char *sharename, struct sec_desc_buf *secdesc_ctr)
-{
-       struct sec_desc_buf *new_secdesc_ctr = NULL;
-       struct sec_desc_buf *old_secdesc_ctr = NULL;
-       TALLOC_CTX *mem_ctx = NULL;
-       TDB_DATA kbuf;
-       TDB_DATA dbuf;
-       DATA_BLOB blob;
-       WERROR status;
-       NTSTATUS nt_status;
-
-       mem_ctx = talloc_init("nt_printing_setsec");
-       if (mem_ctx == NULL)
-               return WERR_NOMEM;
-
-        /* The old owner and group sids of the security descriptor are not
-          present when new ACEs are added or removed by changing printer
-          permissions through NT.  If they are NULL in the new security
-          descriptor then copy them over from the old one. */
-
-       if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
-               struct dom_sid *owner_sid, *group_sid;
-               struct security_acl *dacl, *sacl;
-               struct security_descriptor *psd = NULL;
-               size_t size;
-
-               if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
-                       status = WERR_NOMEM;
-                       goto out;
-               }
-
-               /* Pick out correct owner and group sids */
-
-               owner_sid = secdesc_ctr->sd->owner_sid ?
-                       secdesc_ctr->sd->owner_sid :
-                       old_secdesc_ctr->sd->owner_sid;
-
-               group_sid = secdesc_ctr->sd->group_sid ?
-                       secdesc_ctr->sd->group_sid :
-                       old_secdesc_ctr->sd->group_sid;
-
-               dacl = secdesc_ctr->sd->dacl ?
-                       secdesc_ctr->sd->dacl :
-                       old_secdesc_ctr->sd->dacl;
-
-               sacl = secdesc_ctr->sd->sacl ?
-                       secdesc_ctr->sd->sacl :
-                       old_secdesc_ctr->sd->sacl;
-
-               /* Make a deep copy of the security descriptor */
-
-               psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,
-                                   owner_sid, group_sid,
-                                   sacl,
-                                   dacl,
-                                   &size);
-
-               if (!psd) {
-                       status = WERR_NOMEM;
-                       goto out;
-               }
-
-               new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
-       }
-
-       if (!new_secdesc_ctr) {
-               new_secdesc_ctr = secdesc_ctr;
-       }
-
-       /* Store the security descriptor in a tdb */
-
-       nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
-                                         &blob.data, &blob.length);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               status = ntstatus_to_werror(nt_status);
-               goto out;
-       }
-
-       kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
-
-       dbuf.dptr = (unsigned char *)blob.data;
-       dbuf.dsize = blob.length;
-
-       if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
-               status = WERR_OK;
-       } else {
-               DEBUG(1,("Failed to store secdesc for %s\n", sharename));
-               status = WERR_BADFUNC;
-       }
-
-       /* Free malloc'ed memory */
-       talloc_free(blob.data);
-
- out:
-
-       if (mem_ctx)
-               talloc_destroy(mem_ctx);
-       return status;
-}
-
-/****************************************************************************
- Construct a default security descriptor buffer for a printer.
-****************************************************************************/
-
-static struct sec_desc_buf *construct_default_printer_sdb(TALLOC_CTX *ctx)
-{
-       struct security_ace ace[7];     /* max number of ace entries */
-       int i = 0;
-       uint32_t sa;
-       struct security_acl *psa = NULL;
-       struct sec_desc_buf *sdb = NULL;
-       struct security_descriptor *psd = NULL;
-       struct dom_sid adm_sid;
-       size_t sd_size;
-
-       /* Create an ACE where Everyone is allowed to print */
-
-       sa = PRINTER_ACE_PRINT;
-       init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* Add the domain admins group if we are a DC */
-
-       if ( IS_DC ) {
-               struct dom_sid domadmins_sid;
-
-               sid_compose(&domadmins_sid, get_global_sam_sid(),
-                           DOMAIN_RID_ADMINS);
-
-               sa = PRINTER_ACE_FULL_CONTROL;
-               init_sec_ace(&ace[i++], &domadmins_sid,
-                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-                       SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-               init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-       }
-       else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
-               sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
-
-               sa = PRINTER_ACE_FULL_CONTROL;
-               init_sec_ace(&ace[i++], &adm_sid,
-                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-                       SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-               init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-       }
-
-       /* add BUILTIN\Administrators as FULL CONTROL */
-
-       sa = PRINTER_ACE_FULL_CONTROL;
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-               SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED,
-               sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* add BUILTIN\Print Operators as FULL CONTROL */
-
-       sa = PRINTER_ACE_FULL_CONTROL;
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-               SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED,
-               sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* Make the security descriptor owned by the BUILTIN\Administrators */
-
-       /* The ACL revision number in rpc_secdesc.h differs from the one
-          created by NT when setting ACE entries in printer
-          descriptors.  NT4 complains about the property being edited by a
-          NT5 machine. */
-
-       if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
-               psd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
-                       &global_sid_Builtin_Administrators,
-                       &global_sid_Builtin_Administrators,
-                       NULL, psa, &sd_size);
-       }
-
-       if (!psd) {
-               DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
-               return NULL;
-       }
-
-       sdb = make_sec_desc_buf(ctx, sd_size, psd);
-
-       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
-                (unsigned int)sd_size));
-
-       return sdb;
-}
-
-/****************************************************************************
- Get a security desc for a printer.
-****************************************************************************/
-
-bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, struct sec_desc_buf **secdesc_ctr)
-{
-       TDB_DATA kbuf;
-       TDB_DATA dbuf;
-       DATA_BLOB blob;
-       char *temp;
-       NTSTATUS status;
-
-       if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
-               sharename = temp + 1;
-       }
-
-       /* Fetch security descriptor from tdb */
-
-       kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
-
-       dbuf = tdb_fetch(tdb_printers, kbuf);
-       if (dbuf.dptr) {
-
-               status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
-                                                secdesc_ctr);
-               SAFE_FREE(dbuf.dptr);
-
-               if (NT_STATUS_IS_OK(status)) {
-                       return true;
-               }
-       }
-
-       *secdesc_ctr = construct_default_printer_sdb(ctx);
-       if (!*secdesc_ctr) {
-               return false;
-       }
-
-       status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
-                                      &blob.data, &blob.length);
-       if (NT_STATUS_IS_OK(status)) {
-               dbuf.dptr = (unsigned char *)blob.data;
-               dbuf.dsize = blob.length;
-               tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
-               talloc_free(blob.data);
-       }
-
-       /* If security descriptor is owned by S-1-1-0 and winbindd is up,
-          this security descriptor has been created when winbindd was
-          down.  Take ownership of security descriptor. */
-
-       if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
-               struct dom_sid owner_sid;
-
-               /* Change sd owner to workgroup administrator */
-
-               if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
-                       struct sec_desc_buf *new_secdesc_ctr = NULL;
-                       struct security_descriptor *psd = NULL;
-                       size_t size;
-
-                       /* Create new sd */
-
-                       sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
-
-                       psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
-                                           &owner_sid,
-                                           (*secdesc_ctr)->sd->group_sid,
-                                           (*secdesc_ctr)->sd->sacl,
-                                           (*secdesc_ctr)->sd->dacl,
-                                           &size);
-
-                       if (!psd) {
-                               return False;
-                       }
-
-                       new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
-                       if (!new_secdesc_ctr) {
-                               return False;
-                       }
-
-                       /* Swap with other one */
-
-                       *secdesc_ctr = new_secdesc_ctr;
-
-                       /* Set it */
-
-                       nt_printing_setsec(sharename, *secdesc_ctr);
-               }
-       }
-
-       if (DEBUGLEVEL >= 10) {
-               struct security_acl *the_acl = (*secdesc_ctr)->sd->dacl;
-               int i;
-
-               DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
-                          sharename, the_acl->num_aces));
-
-               for (i = 0; i < the_acl->num_aces; i++) {
-                       DEBUG(10, ("%s %d %d 0x%08x\n",
-                                  sid_string_dbg(&the_acl->aces[i].trustee),
-                                  the_acl->aces[i].type, the_acl->aces[i].flags,
-                                  the_acl->aces[i].access_mask));
-               }
-       }
-
-       return True;
-}
-
 /* error code:
        0: everything OK
        1: level not implemented