*/
#include "includes.h"
-#include "librpc/gen_ndr/messaging.h"
-#include "printing/pcap.h"
-#include "registry.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 "printing/nt_printing_tdb.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
+#include "rpc_server/spoolss/srv_spoolss_util.h"
+#include "nt_printing.h"
+#include "secrets.h"
+#include "../librpc/gen_ndr/netlogon.h"
+#include "../libcli/security/security.h"
+#include "passdb/machine_sid.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "auth.h"
+#include "messages.h"
+#include "rpc_server/spoolss/srv_spoolss_nt.h"
+#include "rpc_client/cli_winreg_spoolss.h"
/* Map generic permissions to printer object specific permissions */
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 = {
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 = {
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 },
{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;
}
- update_c_setprinter(True);
-
/*
* register callback to handle updating printers as new
* drivers are installed
*/
-
messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
do_drv_upgrade_printer);
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();
+ win_rc = check_published_printers(msg_ctx);
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;
}
/*******************************************************************
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 dependent directory\n"));
+ do {
+ i++;
+ } while ( (archi_table[i].long_archi!=NULL ) &&
+ strcasecmp_m(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;
- }
- return ARRAY_SIZE(default_forms);
-}
-
-/****************************************************************************
- get a builtin form struct
-****************************************************************************/
+ int i;
+ char *buf = NULL;
+ ssize_t byte_count;
-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;
- }
+ 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 false;
-}
+ 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;
+ }
-/****************************************************************************
- 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;
-}
-
-/****************************************************************************
- Get the nt drivers list.
- Traverse the database and look-up the matching names.
-****************************************************************************/
-int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
-{
- int total=0;
- const char *short_archi;
- char *key = NULL;
- TDB_DATA kbuf, newkey;
-
- short_archi = get_short_archi(architecture);
- if (!short_archi) {
- return 0;
- }
-
- if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX,
- short_archi, version) < 0) {
- return 0;
- }
-
- for (kbuf = tdb_firstkey(tdb_drivers);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
-
- if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)
- continue;
-
- if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
- DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
- SAFE_FREE(key);
- return -1;
- }
-
- fstrcpy((*list)[total], (const char *)kbuf.dptr+strlen(key));
- total++;
- }
-
- SAFE_FREE(key);
- return(total);
-}
-
-/****************************************************************************
- 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 */
if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(struct pipes_struct *p,
+static uint32 get_correct_cversion(struct auth_session_info *session_info,
const char *architecture,
const char *driverpath_in,
WERROR *perr)
{
- int cversion;
+ int cversion = -1;
NTSTATUS nt_status;
struct smb_filename *smb_fname = NULL;
char *driverpath = NULL;
files_struct *fsp = NULL;
connection_struct *conn = NULL;
- NTSTATUS status;
char *oldcwd;
- fstring printdollar;
+ char *printdollar = NULL;
int printdollar_snum;
*perr = WERR_INVALID_PARAM;
return 3;
}
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
+ printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
+ if (!printdollar) {
+ *perr = WERR_NOMEM;
+ return -1;
+ }
if (printdollar_snum == -1) {
*perr = WERR_NO_SUCH_SHARE;
return -1;
}
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn,
+ printdollar_snum,
lp_pathname(printdollar_snum),
- p->server_info, &oldcwd);
+ session_info, &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("get_correct_cversion: create_conn_struct "
"returned %s\n", nt_errstr(nt_status)));
return -1;
}
+ nt_status = set_conn_force_user_group(conn, printdollar_snum);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("failed set force user / group\n"));
+ *perr = ntstatus_to_werror(nt_status);
+ goto error_free_conn;
+ }
+
+ if (!become_user_by_session(conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ *perr = WERR_ACCESS_DENIED;
+ goto error_free_conn;
+ }
+
/* Open the driver file (Portable Executable format) and determine the
* deriver the cversion. */
driverpath = talloc_asprintf(talloc_tos(),
nt_status = vfs_file_exist(conn, smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(3,("get_correct_cversion: vfs_file_exist failed\n"));
*perr = WERR_BADFILE;
goto error_exit;
}
- status = SMB_VFS_CREATE_FILE(
+ nt_status = SMB_VFS_CREATE_FILE(
conn, /* conn */
NULL, /* req */
0, /* root_dir_fid */
&fsp, /* result */
NULL); /* pinfo */
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
"%d\n", smb_fname_str_dbg(smb_fname), errno));
*perr = WERR_ACCESS_DENIED;
int ret;
ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
- if (ret == -1) goto error_exit;
-
- if (!ret) {
+ if (ret == -1) {
+ *perr = WERR_INVALID_PARAM;
+ goto error_exit;
+ } else if (!ret) {
DEBUG(6,("get_correct_cversion: Version info not "
"found [%s]\n",
smb_fname_str_dbg(smb_fname)));
+ *perr = WERR_INVALID_PARAM;
goto error_exit;
}
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
smb_fname_str_dbg(smb_fname), cversion));
-
- goto done;
+ *perr = WERR_OK;
error_exit:
- cversion = -1;
- done:
+ unbecome_user();
+ error_free_conn:
TALLOC_FREE(smb_fname);
if (fsp != NULL) {
close_file(NULL, fsp, NORMAL_CLOSE);
}
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
- if (cversion != -1) {
- *perr = WERR_OK;
+ if (!W_ERROR_IS_OK(*perr)) {
+ cversion = -1;
}
+
return cversion;
}
} while (0);
static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
- struct pipes_struct *rpc_pipe,
+ struct auth_session_info *session_info,
const char *architecture,
const char **driver_path,
const char **data_file,
const char **config_file,
const char **help_file,
struct spoolss_StringArray *dependent_files,
- uint32_t *version)
+ enum spoolss_DriverOSVersion *version)
{
const char *short_architecture;
int i;
WERROR err;
char *_p;
- if (!*driver_path || !*data_file || !*config_file) {
+ if (!*driver_path || !*data_file) {
+ return WERR_INVALID_PARAM;
+ }
+
+ if (!strequal(architecture, SPOOLSS_ARCHITECTURE_4_0) && !*config_file) {
return WERR_INVALID_PARAM;
}
strip_driver_path(mem_ctx, *driver_path);
strip_driver_path(mem_ctx, *data_file);
- strip_driver_path(mem_ctx, *config_file);
+ if (*config_file) {
+ strip_driver_path(mem_ctx, *config_file);
+ }
if (help_file) {
strip_driver_path(mem_ctx, *help_file);
}
* NT2K: cversion=3
*/
- *version = get_correct_cversion(rpc_pipe, short_architecture,
+ *version = get_correct_cversion(session_info, short_architecture,
*driver_path, &err);
if (*version == -1) {
return err;
/****************************************************************************
****************************************************************************/
-WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
+ struct auth_session_info *session_info,
struct spoolss_AddDriverInfoCtr *r)
{
switch (r->level) {
case 3:
- return clean_up_driver_struct_level(r, rpc_pipe,
+ return clean_up_driver_struct_level(mem_ctx, session_info,
r->info.info3->architecture,
&r->info.info3->driver_path,
&r->info.info3->data_file,
r->info.info3->dependent_files,
&r->info.info3->version);
case 6:
- return clean_up_driver_struct_level(r, rpc_pipe,
+ return clean_up_driver_struct_level(mem_ctx, session_info,
r->info.info6->architecture,
&r->info.info6->driver_path,
&r->info.info6->data_file,
dst->dependent_files = src->dependent_files;
}
-/****************************************************************************
- This function sucks and should be replaced. JRA.
-****************************************************************************/
-
-static void convert_level_8_to_level3(TALLOC_CTX *mem_ctx,
- struct spoolss_AddDriverInfo3 *dst,
- const struct spoolss_DriverInfo8 *src)
-{
- dst->version = src->version;
- dst->driver_name = src->driver_name;
- dst->architecture = src->architecture;
- dst->driver_path = src->driver_path;
- dst->data_file = src->data_file;
- dst->config_file = src->config_file;
- dst->help_file = src->help_file;
- dst->monitor_name = src->monitor_name;
- dst->default_datatype = src->default_datatype;
- if (src->dependent_files) {
- dst->dependent_files = talloc_zero(mem_ctx, struct spoolss_StringArray);
- if (!dst->dependent_files) return;
- dst->dependent_files->string = src->dependent_files;
- } else {
- dst->dependent_files = NULL;
- }
-}
-
/****************************************************************************
****************************************************************************/
}
/* Setup a synthetic smb_filename struct */
- smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
+ smb_fname_new = talloc_zero(mem_ctx, struct smb_filename);
if (!smb_fname_new) {
ret = WERR_NOMEM;
goto out;
return ret;
}
-WERROR move_driver_to_download_area(struct pipes_struct *p,
- struct spoolss_AddDriverInfoCtr *r,
- WERROR *perr)
+WERROR move_driver_to_download_area(struct auth_session_info *session_info,
+ struct spoolss_AddDriverInfoCtr *r)
{
struct spoolss_AddDriverInfo3 *driver;
struct spoolss_AddDriverInfo3 converted_driver;
TALLOC_CTX *ctx = talloc_tos();
int ver = 0;
char *oldcwd;
- fstring printdollar;
+ char *printdollar = NULL;
int printdollar_snum;
-
- *perr = WERR_OK;
+ WERROR err = WERR_OK;
switch (r->level) {
case 3:
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
+ printdollar_snum = find_service(ctx, "print$", &printdollar);
+ if (!printdollar) {
+ return WERR_NOMEM;
+ }
if (printdollar_snum == -1) {
- *perr = WERR_NO_SUCH_SHARE;
return WERR_NO_SUCH_SHARE;
}
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn,
+ printdollar_snum,
lp_pathname(printdollar_snum),
- p->server_info, &oldcwd);
+ session_info, &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("move_driver_to_download_area: create_conn_struct "
"returned %s\n", nt_errstr(nt_status)));
- *perr = ntstatus_to_werror(nt_status);
- return *perr;
+ err = ntstatus_to_werror(nt_status);
+ return err;
+ }
+
+ nt_status = set_conn_force_user_group(conn, printdollar_snum);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("failed set force user / group\n"));
+ err = ntstatus_to_werror(nt_status);
+ goto err_free_conn;
+ }
+
+ if (!become_user_by_session(conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ err = WERR_ACCESS_DENIED;
+ goto err_free_conn;
}
new_dir = talloc_asprintf(ctx,
short_architecture,
driver->version);
if (!new_dir) {
- *perr = WERR_NOMEM;
+ err = WERR_NOMEM;
goto err_exit;
}
nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
if (!NT_STATUS_IS_OK(nt_status)) {
- *perr = WERR_NOMEM;
+ err = WERR_NOMEM;
goto err_exit;
}
DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
- create_directory(conn, NULL, smb_dname);
+ nt_status = create_directory(conn, NULL, smb_dname);
+ if (!NT_STATUS_IS_OK(nt_status)
+ && !NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+ DEBUG(0, ("failed to create driver destination directory: %s\n",
+ nt_errstr(nt_status)));
+ err = ntstatus_to_werror(nt_status);
+ goto err_exit;
+ }
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
* listed for this driver which has already been moved, skip it (note:
if (driver->driver_path && strlen(driver->driver_path)) {
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->driver_path,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->driver_path,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
if (driver->data_file && strlen(driver->data_file)) {
if (!strequal(driver->data_file, driver->driver_path)) {
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->data_file,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- }
-
- if (driver->config_file && strlen(driver->config_file)) {
- if (!strequal(driver->config_file, driver->driver_path) &&
- !strequal(driver->config_file, driver->data_file)) {
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->config_file,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- }
-
- if (driver->help_file && strlen(driver->help_file)) {
- if (!strequal(driver->help_file, driver->driver_path) &&
- !strequal(driver->help_file, driver->data_file) &&
- !strequal(driver->help_file, driver->config_file)) {
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->help_file,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->data_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
- }
-
- if (driver->dependent_files && driver->dependent_files->string) {
- for (i=0; driver->dependent_files->string[i]; i++) {
- if (!strequal(driver->dependent_files->string[i], driver->driver_path) &&
- !strequal(driver->dependent_files->string[i], driver->data_file) &&
- !strequal(driver->dependent_files->string[i], driver->config_file) &&
- !strequal(driver->dependent_files->string[i], driver->help_file)) {
- int j;
- for (j=0; j < i; j++) {
- if (strequal(driver->dependent_files->string[i], driver->dependent_files->string[j])) {
- goto NextDriver;
- }
- }
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->dependent_files->string[i],
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- NextDriver: ;
- }
- }
-
- err_exit:
- TALLOC_FREE(smb_dname);
-
- if (conn != NULL) {
- vfs_ChDir(conn, oldcwd);
- conn_free(conn);
- }
-
- if (W_ERROR_EQUAL(*perr, WERR_OK)) {
- return WERR_OK;
- }
- if (ver == -1) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
- return (*perr);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static uint32 add_a_printer_driver_3(struct spoolss_AddDriverInfo3 *driver)
-{
- TALLOC_CTX *ctx = talloc_tos();
- int len, buflen;
- const char *architecture;
- char *directory = NULL;
- char *key = NULL;
- uint8 *buf;
- int i, ret;
- TDB_DATA dbuf;
-
- architecture = get_short_archi(driver->architecture);
- if (!architecture) {
- return (uint32)-1;
- }
-
- /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
- * \\server is added in the rpc server layer.
- * It does make sense to NOT store the server's name in the printer TDB.
- */
-
- directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\",
- architecture, driver->version);
- if (!directory) {
- return (uint32)-1;
- }
-
-#define gen_full_driver_unc_path(ctx, directory, file) \
- do { \
- if (file && strlen(file)) { \
- file = talloc_asprintf(ctx, "%s%s", directory, file); \
- } else { \
- file = talloc_strdup(ctx, ""); \
- } \
- if (!file) { \
- return (uint32_t)-1; \
- } \
- } while (0);
-
- /* .inf files do not always list a file for each of the four standard files.
- * Don't prepend a path to a null filename, or client claims:
- * "The server on which the printer resides does not have a suitable
- * <printer driver name> printer driver installed. Click OK if you
- * wish to install the driver on your local machine."
- */
-
- gen_full_driver_unc_path(ctx, directory, driver->driver_path);
- gen_full_driver_unc_path(ctx, directory, driver->data_file);
- gen_full_driver_unc_path(ctx, directory, driver->config_file);
- gen_full_driver_unc_path(ctx, directory, driver->help_file);
-
- if (driver->dependent_files && driver->dependent_files->string) {
- for (i=0; driver->dependent_files->string[i]; i++) {
- gen_full_driver_unc_path(ctx, directory,
- driver->dependent_files->string[i]);
- }
- }
-
- key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX,
- architecture, driver->version, driver->driver_name);
- if (!key) {
- return (uint32)-1;
- }
-
- DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
-
- buf = NULL;
- len = buflen = 0;
-
- again:
- len = 0;
- len += tdb_pack(buf+len, buflen-len, "dffffffff",
- driver->version,
- driver->driver_name,
- driver->architecture,
- driver->driver_path,
- driver->data_file,
- driver->config_file,
- driver->help_file,
- driver->monitor_name ? driver->monitor_name : "",
- driver->default_datatype ? driver->default_datatype : "");
-
- if (driver->dependent_files && driver->dependent_files->string) {
- for (i=0; driver->dependent_files->string[i]; i++) {
- len += tdb_pack(buf+len, buflen-len, "f",
- driver->dependent_files->string[i]);
- }
- }
-
- if (len != buflen) {
- buf = (uint8 *)SMB_REALLOC(buf, len);
- if (!buf) {
- DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
- ret = -1;
- goto done;
- }
- buflen = len;
- goto again;
- }
-
- dbuf.dptr = buf;
- dbuf.dsize = len;
-
- ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
-
-done:
- if (ret)
- DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
-
- SAFE_FREE(buf);
- return ret;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static uint32_t add_a_printer_driver_8(struct spoolss_DriverInfo8 *driver)
-{
- TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
- struct spoolss_AddDriverInfo3 info3;
- uint32_t ret;
-
- convert_level_8_to_level3(mem_ctx, &info3, driver);
-
- ret = add_a_printer_driver_3(&info3);
- talloc_free(mem_ctx);
-
- return ret;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR get_a_printer_driver_3_default(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo3 *info,
- const char *driver, const char *arch)
-{
- info->driver_name = talloc_strdup(mem_ctx, driver);
- if (!info->driver_name) {
- return WERR_NOMEM;
- }
-
- info->default_datatype = talloc_strdup(mem_ctx, "RAW");
- if (!info->default_datatype) {
- return WERR_NOMEM;
- }
-
- info->driver_path = talloc_strdup(mem_ctx, "");
- info->data_file = talloc_strdup(mem_ctx, "");
- info->config_file = talloc_strdup(mem_ctx, "");
- info->help_file = talloc_strdup(mem_ctx, "");
- if (!info->driver_path || !info->data_file || !info->config_file || !info->help_file) {
- return WERR_NOMEM;
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR get_a_printer_driver_3(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo3 *driver,
- const char *drivername, const char *arch,
- uint32_t version)
-{
- TDB_DATA dbuf;
- const char *architecture;
- int len = 0;
- int i;
- char *key = NULL;
- fstring name, driverpath, environment, datafile, configfile, helpfile, monitorname, defaultdatatype;
-
- architecture = get_short_archi(arch);
- if ( !architecture ) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- /* Windows 4.0 (i.e. win9x) should always use a version of 0 */
-
- if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 )
- version = 0;
-
- DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
-
- if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
- architecture, version, drivername) < 0) {
- return WERR_NOMEM;
- }
-
- dbuf = tdb_fetch_bystring(tdb_drivers, key);
- if (!dbuf.dptr) {
- SAFE_FREE(key);
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
- &driver->version,
- name,
- environment,
- driverpath,
- datafile,
- configfile,
- helpfile,
- monitorname,
- defaultdatatype);
-
- driver->driver_name = talloc_strdup(mem_ctx, name);
- driver->architecture = talloc_strdup(mem_ctx, environment);
- driver->driver_path = talloc_strdup(mem_ctx, driverpath);
- driver->data_file = talloc_strdup(mem_ctx, datafile);
- driver->config_file = talloc_strdup(mem_ctx, configfile);
- driver->help_file = talloc_strdup(mem_ctx, helpfile);
- driver->monitor_name = talloc_strdup(mem_ctx, monitorname);
- driver->default_datatype = talloc_strdup(mem_ctx, defaultdatatype);
-
- i=0;
-
- while (len < dbuf.dsize) {
-
- fstring file;
-
- driver->dependent_files = talloc_realloc(mem_ctx, driver->dependent_files, const char *, i+2);
- if (!driver->dependent_files ) {
- DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
- break;
- }
-
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
- &file);
-
- driver->dependent_files[i] = talloc_strdup(mem_ctx, file);
-
- i++;
- }
-
- if (driver->dependent_files)
- driver->dependent_files[i] = NULL;
-
- SAFE_FREE(dbuf.dptr);
- SAFE_FREE(key);
-
- if (len != dbuf.dsize) {
- return get_a_printer_driver_3_default(mem_ctx, driver, drivername, arch);
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
-{
- int len = 0;
-
- len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
-
- if (!nt_devmode)
- return len;
-
- len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
- nt_devmode->devicename,
- nt_devmode->formname,
-
- nt_devmode->specversion,
- nt_devmode->driverversion,
- nt_devmode->size,
- nt_devmode->driverextra,
- nt_devmode->orientation,
- nt_devmode->papersize,
- nt_devmode->paperlength,
- nt_devmode->paperwidth,
- nt_devmode->scale,
- nt_devmode->copies,
- nt_devmode->defaultsource,
- nt_devmode->printquality,
- nt_devmode->color,
- nt_devmode->duplex,
- nt_devmode->yresolution,
- nt_devmode->ttoption,
- nt_devmode->collate,
- nt_devmode->logpixels,
-
- nt_devmode->fields,
- nt_devmode->bitsperpel,
- nt_devmode->pelswidth,
- nt_devmode->pelsheight,
- nt_devmode->displayflags,
- nt_devmode->displayfrequency,
- nt_devmode->icmmethod,
- nt_devmode->icmintent,
- nt_devmode->mediatype,
- nt_devmode->dithertype,
- nt_devmode->reserved1,
- nt_devmode->reserved2,
- nt_devmode->panningwidth,
- nt_devmode->panningheight,
- nt_devmode->nt_dev_private);
-
- if (nt_devmode->nt_dev_private) {
- len += tdb_pack(buf+len, buflen-len, "B",
- nt_devmode->driverextra,
- nt_devmode->nt_dev_private);
- }
-
- DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
-
- 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;
-}
-
-
-/****************************************************************************
- Delete a printer - this just deletes the printer info file, any open
- handles are not affected.
-****************************************************************************/
-
-uint32 del_a_printer(const char *sharename)
-{
- TDB_DATA kbuf;
- char *printdb_path = NULL;
- TALLOC_CTX *ctx = talloc_tos();
-
- kbuf = make_printer_tdbkey(ctx, sharename);
- tdb_delete(tdb_printers, kbuf);
-
- kbuf= make_printers_secdesc_tdbkey(ctx, sharename);
- tdb_delete(tdb_printers, kbuf);
-
- close_all_print_db();
-
- if (geteuid() == sec_initial_uid()) {
- if (asprintf(&printdb_path, "%s%s.tdb",
- cache_path("printing/"),
- sharename) < 0) {
- return (uint32)-1;
- }
- unlink(printdb_path);
- SAFE_FREE(printdb_path);
- }
-
- return 0;
-}
-
-/****************************************************************************
-****************************************************************************/
-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.
-****************************************************************************/
-
-WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
- const char *devicename,
- struct spoolss_DeviceMode **devmode)
-{
- struct spoolss_DeviceMode *dm;
- char *dname;
-
- dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
- if (dm == NULL) {
- return WERR_NOMEM;
- }
-
- dname = talloc_asprintf(dm, "%s", devicename);
- if (dname == NULL) {
- return WERR_NOMEM;
- }
- if (strlen(dname) > MAXDEVICENAME) {
- dname[MAXDEVICENAME] = '\0';
- }
- dm->devicename = dname;
-
- dm->formname = talloc_strdup(dm, "Letter");
- if (dm->formname == NULL) {
- return WERR_NOMEM;
- }
-
- dm->specversion = DMSPEC_NT4_AND_ABOVE;
- dm->driverversion = 0x0400;
- dm->size = 0x00DC;
- dm->__driverextra_length = 0;
- dm->fields = DEVMODE_FORMNAME |
- DEVMODE_TTOPTION |
- DEVMODE_PRINTQUALITY |
- DEVMODE_DEFAULTSOURCE |
- DEVMODE_COPIES |
- DEVMODE_SCALE |
- DEVMODE_PAPERSIZE |
- DEVMODE_ORIENTATION;
- dm->orientation = DMORIENT_PORTRAIT;
- dm->papersize = DMPAPER_LETTER;
- dm->paperlength = 0;
- dm->paperwidth = 0;
- dm->scale = 0x64;
- dm->copies = 1;
- dm->defaultsource = DMBIN_FORMSOURCE;
- dm->printquality = DMRES_HIGH; /* 0x0258 */
- dm->color = DMRES_MONOCHROME;
- dm->duplex = DMDUP_SIMPLEX;
- dm->yresolution = 0;
- dm->ttoption = DMTT_SUBDEV;
- dm->collate = DMCOLLATE_FALSE;
- dm->icmmethod = 0;
- dm->icmintent = 0;
- dm->mediatype = 0;
- dm->dithertype = 0;
-
- dm->logpixels = 0;
- dm->bitsperpel = 0;
- dm->pelswidth = 0;
- dm->pelsheight = 0;
- dm->displayflags = 0;
- dm->displayfrequency = 0;
- dm->reserved1 = 0;
- dm->reserved2 = 0;
- dm->panningwidth = 0;
- dm->panningheight = 0;
-
- dm->driverextra_data.data = NULL;
- dm->driverextra_data.length = 0;
-
- *devmode = dm;
- return WERR_OK;
-}
-
-WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
- struct spoolss_security_descriptor **secdesc)
-{
- struct security_ace ace[5]; /* max number of ace entries */
- int i = 0;
- uint32_t sa;
- struct security_acl *psa = NULL;
- struct security_descriptor *psd = NULL;
- 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 ) {
- 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);
-
- /* 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;
-}
-
-/****************************************************************************
- Malloc and return an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
-{
-
- char adevice[MAXDEVICENAME];
- NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE);
-
- if (nt_devmode == NULL) {
- DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
- return NULL;
- }
-
- ZERO_STRUCTP(nt_devmode);
-
- slprintf(adevice, sizeof(adevice), "%s", default_devicename);
- fstrcpy(nt_devmode->devicename, adevice);
-
- fstrcpy(nt_devmode->formname, "Letter");
-
- nt_devmode->specversion = DMSPEC_NT4_AND_ABOVE;
- nt_devmode->driverversion = 0x0400;
- nt_devmode->size = 0x00DC;
- nt_devmode->driverextra = 0x0000;
- nt_devmode->fields = DEVMODE_FORMNAME |
- DEVMODE_TTOPTION |
- DEVMODE_PRINTQUALITY |
- DEVMODE_DEFAULTSOURCE |
- DEVMODE_COPIES |
- DEVMODE_SCALE |
- DEVMODE_PAPERSIZE |
- DEVMODE_ORIENTATION;
- nt_devmode->orientation = DMORIENT_PORTRAIT;
- nt_devmode->papersize = DMPAPER_LETTER;
- nt_devmode->paperlength = 0;
- nt_devmode->paperwidth = 0;
- nt_devmode->scale = 0x64;
- nt_devmode->copies = 1;
- nt_devmode->defaultsource = DMBIN_FORMSOURCE;
- nt_devmode->printquality = DMRES_HIGH; /* 0x0258 */
- nt_devmode->color = DMRES_MONOCHROME;
- nt_devmode->duplex = DMDUP_SIMPLEX;
- nt_devmode->yresolution = 0;
- nt_devmode->ttoption = DMTT_SUBDEV;
- nt_devmode->collate = DMCOLLATE_FALSE;
- nt_devmode->icmmethod = 0;
- nt_devmode->icmintent = 0;
- nt_devmode->mediatype = 0;
- nt_devmode->dithertype = 0;
-
- /* non utilisés par un driver d'imprimante */
- nt_devmode->logpixels = 0;
- nt_devmode->bitsperpel = 0;
- nt_devmode->pelswidth = 0;
- nt_devmode->pelsheight = 0;
- nt_devmode->displayflags = 0;
- nt_devmode->displayfrequency = 0;
- nt_devmode->reserved1 = 0;
- nt_devmode->reserved2 = 0;
- nt_devmode->panningwidth = 0;
- nt_devmode->panningheight = 0;
-
- nt_devmode->nt_dev_private = NULL;
- return nt_devmode;
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
-****************************************************************************/
-
-void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
-{
- NT_DEVICEMODE *nt_devmode = *devmode_ptr;
-
- if(nt_devmode == NULL)
- return;
-
- DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
-
- SAFE_FREE(nt_devmode->nt_dev_private);
- SAFE_FREE(*devmode_ptr);
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
-****************************************************************************/
-
-static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
-{
- NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
-
- if ( !info )
- return;
-
- free_nt_devicemode(&info->devmode);
-
- TALLOC_FREE( *info_ptr );
-}
-
-
-/****************************************************************************
-****************************************************************************/
-int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
-{
- int len = 0;
- int extra_len = 0;
- NT_DEVICEMODE devmode;
-
- ZERO_STRUCT(devmode);
-
- len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
-
- if (!*nt_devmode) return len;
-
- len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
- devmode.devicename,
- devmode.formname,
-
- &devmode.specversion,
- &devmode.driverversion,
- &devmode.size,
- &devmode.driverextra,
- &devmode.orientation,
- &devmode.papersize,
- &devmode.paperlength,
- &devmode.paperwidth,
- &devmode.scale,
- &devmode.copies,
- &devmode.defaultsource,
- &devmode.printquality,
- &devmode.color,
- &devmode.duplex,
- &devmode.yresolution,
- &devmode.ttoption,
- &devmode.collate,
- &devmode.logpixels,
-
- &devmode.fields,
- &devmode.bitsperpel,
- &devmode.pelswidth,
- &devmode.pelsheight,
- &devmode.displayflags,
- &devmode.displayfrequency,
- &devmode.icmmethod,
- &devmode.icmintent,
- &devmode.mediatype,
- &devmode.dithertype,
- &devmode.reserved1,
- &devmode.reserved2,
- &devmode.panningwidth,
- &devmode.panningheight,
- &devmode.nt_dev_private);
-
- if (devmode.nt_dev_private) {
- /* the len in tdb_unpack is an int value and
- * devmode.driverextra is only a short
- */
- len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private);
- devmode.driverextra=(uint16)extra_len;
-
- /* check to catch an invalid TDB entry so we don't segfault */
- if (devmode.driverextra == 0) {
- devmode.nt_dev_private = NULL;
- }
- }
-
- *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
- if (!*nt_devmode) {
- SAFE_FREE(devmode.nt_dev_private);
- return -1;
- }
-
- DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
- if (devmode.nt_dev_private)
- DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
-
- return len;
-}
-
-/****************************************************************************
- 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;
-
- 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 );
-
- if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, struct regval_ctr )) )
- 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,
- (char *) &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,
- (char *) &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 the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing.
- *
- * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified
- * @return bool indicating success or failure
- ***************************************************************************/
-
-static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
-{
- struct regval_ctr *ctr = NULL;
- fstring longname;
- const char *dnssuffix;
- char *allocated_string = NULL;
- const char *ascii_str;
- int i;
-
- if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
- i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
- ctr = info2->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) {
- 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);
-
- return True;
-}
-
-/*****************************************************************
- ****************************************************************/
-
-static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
- struct GUID guid)
-{
- int i;
- struct regval_ctr *ctr=NULL;
-
- /* find the DsSpooler key */
- if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
- i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
- ctr = info2->data->keys[i].values;
-
- regval_ctr_delvalue(ctr, "objectGUID");
-
- /* We used to store this as a REG_BINARY but that causes
- Vista to whine */
-
- regval_ctr_addvalue_sz(ctr, "objectGUID",
- GUID_string(talloc_tos(), &guid));
-}
-
-static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
- NT_PRINTER_INFO_LEVEL *printer)
-{
- 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;
-
- /* build the ads mods */
- ctx = talloc_init("nt_printer_publish_ads");
- if (ctx == NULL) {
- return WERR_NOMEM;
- }
-
- DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
-
- /* 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->info_2->sharename);
- 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, printer->info_2->data);
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
- printer->info_2->sharename);
-
- /* 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->info_2->sharename, 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->info_2, guid);
- win_rc = mod_a_printer(printer, 2);
- }
- TALLOC_FREE(ctx);
-
- return win_rc;
-}
-
-static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
- NT_PRINTER_INFO_LEVEL *printer)
-{
- ADS_STATUS ads_rc;
- LDAPMessage *res = NULL;
- char *prt_dn = NULL;
-
- DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
-
- /* remove the printer from the directory */
- ads_rc = ads_find_printer_on_server(ads, &res,
- printer->info_2->sharename, 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 snum describing printer service
- * @return WERROR indicating status of publishing
- ***************************************************************************/
-
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
- ADS_STATUS ads_rc;
- ADS_STRUCT *ads = NULL;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- WERROR win_rc;
-
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(win_rc))
- goto done;
-
- switch (action) {
- case DSPRINT_PUBLISH:
- case DSPRINT_UPDATE:
- /* set the DsSpooler info and attributes */
- if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
- win_rc = WERR_NOMEM;
- goto done;
- }
-
- printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
- break;
- case DSPRINT_UNPUBLISH:
- printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
- break;
- default:
- win_rc = WERR_NOT_SUPPORTED;
- goto done;
- }
-
- win_rc = mod_a_printer(printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
- goto done;
- }
-
- 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, printer);
- break;
- case DSPRINT_UNPUBLISH:
- win_rc = nt_printer_unpublish_ads(ads, printer);
- break;
- }
-
-done:
- free_a_printer(&printer, 2);
- 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();
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- 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)));
- ads_destroy(&ads);
- ads_kdestroy("MEMORY:prtpub_cache");
- return WERR_ACCESS_DENIED;
- }
-
- for (snum = 0; snum < n_services; snum++) {
- if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
- continue;
-
- if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
- lp_servicename(snum))) &&
- (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- nt_printer_publish_ads(ads, printer);
-
- free_a_printer(&printer, 2);
- }
-
- ads_destroy(&ads);
- ads_kdestroy("MEMORY:prtpub_cache");
- return WERR_OK;
-}
-
-bool is_printer_published(Printer_entry *print_hnd, int snum,
- struct GUID *guid)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- struct regval_ctr *ctr;
- struct regval_blob *guid_val;
- WERROR win_rc;
- int i;
- bool ret = False;
- DATA_BLOB blob;
-
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
-
- if (!W_ERROR_IS_OK(win_rc) ||
- !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
- ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) ||
- !(ctr = printer->info_2->data->keys[i].values) ||
- !(guid_val = regval_ctr_getvalue(ctr, "objectGUID")))
- {
- free_a_printer(&printer, 2);
- return False;
- }
-
- /* fetching printer guids really ought to be a separate function. */
-
- if ( guid ) {
- char *guid_str;
-
- /* We used to store the guid as REG_BINARY, then swapped
- to REG_SZ for Vista compatibility so check for both */
-
- switch ( regval_type(guid_val) ){
- case REG_SZ:
- blob = data_blob_const(regval_data_p(guid_val),
- regval_size(guid_val));
- pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str);
- ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
- talloc_free(guid_str);
- break;
- case REG_BINARY:
- if ( regval_size(guid_val) != sizeof(struct GUID) ) {
- ret = False;
- break;
- }
- memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
- break;
- default:
- DEBUG(0,("is_printer_published: GUID value stored as "
- "invaluid type (%d)\n", regval_type(guid_val) ));
- break;
- }
- }
-
- free_a_printer(&printer, 2);
- return ret;
-}
-#else
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
- return WERR_OK;
-}
-
-WERROR check_published_printers(void)
-{
- return WERR_OK;
-}
-
-bool is_printer_published(Printer_entry *print_hnd, int snum,
- struct GUID *guid)
-{
- 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, (const char *)data, real_len );
-
- DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
- key, value, type, real_len ));
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
- int key_index;
-
- if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
- return NULL;
-
- DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
- key, value ));
-
- return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
-}
-
-/****************************************************************************
- Unpack a list of registry values frem the TDB
- ***************************************************************************/
-
-static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen)
-{
- int len = 0;
- uint32 type;
- fstring string;
- const char *valuename = NULL;
- const char *keyname = NULL;
- char *str;
- int size;
- uint8 *data_p;
- struct regval_blob *regval_p;
- int key_index;
-
- /* add the "PrinterDriverData" key first for performance reasons */
-
- add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
-
- /* loop and unpack the rest of the registry values */
-
- while ( True ) {
-
- /* check to see if there are any more registry values */
-
- regval_p = NULL;
- len += tdb_unpack(buf+len, buflen-len, "p", ®val_p);
- if ( !regval_p )
- break;
-
- /* unpack the next regval */
-
- len += tdb_unpack(buf+len, buflen-len, "fdB",
- string,
- &type,
- &size,
- &data_p);
-
- /* lookup for subkey names which have a type of REG_NONE */
- /* there's no data with this entry */
-
- if ( type == REG_NONE ) {
- if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
- add_new_printer_key( printer_data, string );
- continue;
- }
-
- /*
- * break of the keyname from the value name.
- * Valuenames can have embedded '\'s so be careful.
- * only support one level of keys. See the
- * "Konica Fiery S300 50C-K v1.1. enu" 2k driver.
- * -- jerry
- */
-
- str = strchr_m( string, '\\');
-
- /* Put in "PrinterDriverData" is no key specified */
-
- if ( !str ) {
- keyname = SPOOL_PRINTERDATA_KEY;
- valuename = string;
- }
- else {
- *str = '\0';
- keyname = string;
- valuename = str+1;
- }
-
- /* see if we need a new key */
-
- if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
- key_index = add_new_printer_key( printer_data, keyname );
-
- if ( key_index == -1 ) {
- DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
- keyname));
- break;
- }
-
- DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
-
- /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
- Thanks to Martin Zielinski for the hint. */
-
- if ( type == REG_BINARY &&
- strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
- strequal( valuename, "objectGUID" ) )
- {
- struct GUID guid;
-
- /* convert the GUID to a UNICODE string */
-
- memcpy( &guid, data_p, sizeof(struct GUID) );
-
- regval_ctr_addvalue_sz(printer_data->keys[key_index].values,
- valuename,
- GUID_string(talloc_tos(), &guid));
-
- } else {
- /* add the value */
-
- regval_ctr_addvalue( printer_data->keys[key_index].values,
- valuename, type, (const char *)data_p,
- size );
- }
-
- SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
-
- }
-
- return len;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-static char *win_driver;
-static char *os2_driver;
-
-static const char *get_win_driver(void)
-{
- if (win_driver == NULL) {
- return "";
- }
- return win_driver;
-}
-
-static const char *get_os2_driver(void)
-{
- if (os2_driver == NULL) {
- return "";
- }
- return os2_driver;
-}
-
-static bool set_driver_mapping(const char *from, const char *to)
-{
- SAFE_FREE(win_driver);
- SAFE_FREE(os2_driver);
-
- win_driver = SMB_STRDUP(from);
- os2_driver = SMB_STRDUP(to);
-
- if (win_driver == NULL || os2_driver == NULL) {
- SAFE_FREE(win_driver);
- SAFE_FREE(os2_driver);
- return false;
- }
- return true;
-}
-
-static void map_to_os2_driver(fstring drivername)
-{
- char *mapfile = lp_os2_driver_map();
- char **lines = NULL;
- int numlines = 0;
- int i;
-
- if (!strlen(drivername))
- return;
-
- if (!*mapfile)
- return;
-
- if (strequal(drivername, get_win_driver())) {
- DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
- drivername, get_os2_driver()));
- fstrcpy(drivername, get_os2_driver());
- return;
- }
-
- lines = file_lines_load(mapfile, &numlines,0,NULL);
- if (numlines == 0 || lines == NULL) {
- DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
- TALLOC_FREE(lines);
- return;
- }
-
- DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
-
- for( i = 0; i < numlines; i++) {
- char *nt_name = lines[i];
- char *os2_name = strchr(nt_name,'=');
-
- if (!os2_name)
- continue;
-
- *os2_name++ = 0;
-
- while (isspace(*nt_name))
- nt_name++;
-
- if (!*nt_name || strchr("#;",*nt_name))
- continue;
-
- {
- int l = strlen(nt_name);
- while (l && isspace(nt_name[l-1])) {
- nt_name[l-1] = 0;
- l--;
- }
- }
-
- while (isspace(*os2_name))
- os2_name++;
-
- {
- int l = strlen(os2_name);
- while (l && isspace(os2_name[l-1])) {
- os2_name[l-1] = 0;
- l--;
- }
- }
-
- if (strequal(nt_name,drivername)) {
- DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
- set_driver_mapping(drivername,os2_name);
- fstrcpy(drivername,os2_name);
- TALLOC_FREE(lines);
- return;
- }
- }
-
- TALLOC_FREE(lines);
-}
-
-/**
- * @internal
- *
- * @brief Map a Windows driver to a OS/2 driver.
- *
- * @param[in] mem_ctx The memory context to use.
- *
- * @param[in,out] pdrivername The drivername of Windows to remap.
- *
- * @return WERR_OK on success, a corresponding WERROR on failure.
- */
-WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
-{
- const char *mapfile = lp_os2_driver_map();
- char **lines = NULL;
- const char *drivername;
- int numlines = 0;
- int i;
-
- if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
- return WERR_INVALID_PARAMETER;
- }
-
- drivername = *pdrivername;
-
- if (mapfile[0] == '\0') {
- return WERR_BADFILE;
- }
-
- if (strequal(drivername, get_win_driver())) {
- DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
- drivername, get_os2_driver()));
- drivername = talloc_strdup(mem_ctx, get_os2_driver());
- if (drivername == NULL) {
- return WERR_NOMEM;
- }
- *pdrivername = drivername;
- return WERR_OK;
- }
-
- lines = file_lines_load(mapfile, &numlines, 0, NULL);
- if (numlines == 0 || lines == NULL) {
- DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
- TALLOC_FREE(lines);
- return WERR_EMPTY;
- }
-
- DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
-
- for( i = 0; i < numlines; i++) {
- char *nt_name = lines[i];
- char *os2_name = strchr(nt_name, '=');
-
- if (os2_name == NULL) {
- continue;
- }
-
- *os2_name++ = '\0';
-
- while (isspace(*nt_name)) {
- nt_name++;
- }
-
- if (*nt_name == '\0' || strchr("#;", *nt_name)) {
- continue;
- }
-
- {
- int l = strlen(nt_name);
- while (l && isspace(nt_name[l - 1])) {
- nt_name[l - 1] = 0;
- l--;
- }
- }
-
- while (isspace(*os2_name)) {
- os2_name++;
- }
-
- {
- int l = strlen(os2_name);
- while (l && isspace(os2_name[l-1])) {
- os2_name[l-1] = 0;
- l--;
- }
- }
-
- if (strequal(nt_name, drivername)) {
- DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
- set_driver_mapping(drivername, os2_name);
- drivername = talloc_strdup(mem_ctx, os2_name);
- TALLOC_FREE(lines);
- if (drivername == NULL) {
- return WERR_NOMEM;
- }
- *pdrivername = drivername;
- return WERR_OK;
- }
- }
-
- TALLOC_FREE(lines);
- return WERR_OK;
-}
-
-/****************************************************************************
- Get a default printer info 2 struct.
-****************************************************************************/
-
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
- const char *servername,
- const char* sharename,
- bool get_loc_com)
-{
- int snum = lp_servicenumber(sharename);
-
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
- slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- servername, sharename);
- fstrcpy(info->sharename, sharename);
- fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
-
- /* by setting the driver name to an empty string, a local NT admin
- can now run the **local** APW to install a local printer driver
- for a Samba shared printer in 2.2. Without this, drivers **must** be
- installed on the Samba server for NT clients --jerry */
-#if 0 /* JERRY --do not uncomment-- */
- if (!*info->drivername)
- fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
-#endif
-
-
- DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
-
- strlcpy(info->comment, "", sizeof(info->comment));
- fstrcpy(info->printprocessor, "winprint");
- fstrcpy(info->datatype, "RAW");
-
-#ifdef HAVE_CUPS
- if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
- /* Pull the location and comment strings from cups if we don't
- already have one */
- if ( !strlen(info->location) || !strlen(info->comment) ) {
- char *comment = NULL;
- char *location = NULL;
- if (cups_pull_comment_location(info, info->sharename,
- &comment, &location)) {
- strlcpy(info->comment, comment, sizeof(info->comment));
- fstrcpy(info->location, location);
- TALLOC_FREE(comment);
- TALLOC_FREE(location);
- }
- }
- }
-#endif
-
- info->attributes = PRINTER_ATTRIBUTE_SAMBA;
-
- info->starttime = 0; /* Minutes since 12:00am GMT */
- info->untiltime = 0; /* Minutes since 12:00am GMT */
- info->priority = 1;
- info->default_priority = 1;
- info->setuptime = (uint32)time(NULL);
-
- /*
- * I changed this as I think it is better to have a generic
- * DEVMODE than to crash Win2k explorer.exe --jerry
- * See the HP Deskjet 990c Win2k drivers for an example.
- *
- * However the default devmode appears to cause problems
- * with the HP CLJ 8500 PCL driver. Hence the addition of
- * the "default devmode" parameter --jerry 22/01/2002
- */
-
- if (lp_default_devmode(snum)) {
- if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) {
- goto fail;
- }
- } else {
- info->devmode = NULL;
- }
-
- if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
- goto fail;
- }
-
- info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA);
- if (!info->data) {
- goto fail;
- }
-
- add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY);
-
- return WERR_OK;
-
-fail:
- if (info->devmode)
- free_nt_devicemode(&info->devmode);
-
- return WERR_ACCESS_DENIED;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
- const char *servername,
- const char *sharename,
- bool get_loc_com)
-{
- int len = 0;
- int snum = lp_servicenumber(sharename);
- TDB_DATA kbuf, dbuf;
- fstring printername;
- char adevice[MAXDEVICENAME];
- char *comment = NULL;
-
- kbuf = make_printer_tdbkey(talloc_tos(), sharename);
-
- dbuf = tdb_fetch(tdb_printers, kbuf);
- if (!dbuf.dptr) {
- return get_a_printer_2_default(info, servername,
- sharename, get_loc_com);
- }
-
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-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,
- &comment,
- info->location,
- info->sepfile,
- info->printprocessor,
- info->datatype,
- info->parameters);
-
- if (comment) {
- strlcpy(info->comment, comment, sizeof(info->comment));
- SAFE_FREE(comment);
- }
-
- /* Samba has to have shared raw drivers. */
- info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
- info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
-
- /* Restore the stripped strings. */
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
-
- if ( lp_force_printername(snum) ) {
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
- } else {
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
- }
-
- fstrcpy(info->printername, printername);
-
-#ifdef HAVE_CUPS
- if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
- /* Pull the location and comment strings from cups if we don't
- already have one */
- if ( !strlen(info->location) || !strlen(info->comment) ) {
- char *location = NULL;
- comment = NULL;
- if (cups_pull_comment_location(info, info->sharename,
- &comment, &location)) {
- strlcpy(info->comment, comment, sizeof(info->comment));
- fstrcpy(info->location, location);
- TALLOC_FREE(comment);
- TALLOC_FREE(location);
- }
- }
- }
-#endif
-
- len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len);
-
- /*
- * Some client drivers freak out if there is a NULL devmode
- * (probably the driver is not checking before accessing
- * the devmode pointer) --jerry
- *
- * See comments in get_a_printer_2_default()
- */
-
- if (lp_default_devmode(snum) && !info->devmode) {
- DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
- printername));
- info->devmode = construct_nt_devicemode(printername);
- }
-
- slprintf( adevice, sizeof(adevice), "%s", info->printername );
- if (info->devmode) {
- fstrcpy(info->devmode->devicename, adevice);
- }
-
- if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
- DEBUG(0,("unpack_values: talloc() failed!\n"));
- SAFE_FREE(dbuf.dptr);
- return WERR_NOMEM;
- }
- len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
-
- /* This will get the current RPC talloc context, but we should be
- passing this as a parameter... fixme... JRA ! */
-
- if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
- SAFE_FREE(dbuf.dptr);
- return WERR_NOMEM;
- }
-
- /* Fix for OS/2 drivers. */
-
- if (get_remote_arch() == RA_OS2) {
- map_to_os2_driver(info->drivername);
- }
-
- SAFE_FREE(dbuf.dptr);
-
- DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
- sharename, info->printername, info->drivername));
-
- 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;
-}
-
-/****************************************************************************
- Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
-
- Previously the code had a memory allocation problem because it always
- used the TALLOC_CTX from the Printer_entry*. This context lasts
- as a long as the original handle is open. So if the client made a lot
- of getprinter[data]() calls, the memory usage would climb. Now we use
- a short lived TALLOC_CTX for printer_info_2 objects returned. We
- still use the Printer_entry->ctx for maintaining the cache copy though
- since that object must live as long as the handle by definition.
- --jerry
-
-****************************************************************************/
-
-static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
- const char *sharename, bool get_loc_com)
-{
- WERROR result;
- fstring servername;
-
- DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
-
- if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
- DEBUG(0,("get_a_printer: talloc() fail.\n"));
- return WERR_NOMEM;
- }
-
- switch (level) {
- case 2:
- if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
- DEBUG(0,("get_a_printer: talloc() fail.\n"));
- TALLOC_FREE( *pp_printer );
- return WERR_NOMEM;
- }
-
- if ( print_hnd )
- fstrcpy( servername, print_hnd->servername );
- else {
- fstrcpy( servername, "%L" );
- standard_sub_basic( "", "", servername,
- sizeof(servername)-1 );
- }
-
- result = get_a_printer_2( (*pp_printer)->info_2,
- servername, sharename, get_loc_com);
-
- /* we have a new printer now. Save it with this handle */
-
- if ( !W_ERROR_IS_OK(result) ) {
- TALLOC_FREE( *pp_printer );
- DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
- sharename, (unsigned int)level, win_errstr(result)));
- return result;
- }
-
- dump_a_printer( *pp_printer, level);
-
- break;
-
- default:
- TALLOC_FREE( *pp_printer );
- return WERR_UNKNOWN_LEVEL;
- }
-
- return WERR_OK;
-}
-
-WERROR get_a_printer( Printer_entry *print_hnd,
- NT_PRINTER_INFO_LEVEL **pp_printer,
- uint32 level,
- const char *sharename)
-{
- return get_a_printer_internal(print_hnd, pp_printer, level,
- sharename, true);
-}
-
-WERROR get_a_printer_search( Printer_entry *print_hnd,
- NT_PRINTER_INFO_LEVEL **pp_printer,
- uint32 level,
- const char *sharename)
-{
- return get_a_printer_internal(print_hnd, pp_printer, level,
- sharename, false);
-}
-
-/****************************************************************************
- 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:
- if ( printer->info_2 )
- free_nt_printer_info_level_2(&printer->info_2);
- break;
-
- default:
- DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
- return 1;
- }
-
- TALLOC_FREE(*pp_printer);
-
- return 0;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
- struct spoolss_DriverInfo8 *_info8)
-{
- struct spoolss_DriverInfo8 info8;
-
- ZERO_STRUCT(info8);
-
- switch (r->level) {
- case 3:
- info8.version = r->info.info3->version;
- info8.driver_name = r->info.info3->driver_name;
- info8.architecture = r->info.info3->architecture;
- info8.driver_path = r->info.info3->driver_path;
- info8.data_file = r->info.info3->data_file;
- info8.config_file = r->info.info3->config_file;
- info8.help_file = r->info.info3->help_file;
- info8.monitor_name = r->info.info3->monitor_name;
- info8.default_datatype = r->info.info3->default_datatype;
- if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
- info8.dependent_files = r->info.info3->dependent_files->string;
- }
- break;
- case 6:
- info8.version = r->info.info6->version;
- info8.driver_name = r->info.info6->driver_name;
- info8.architecture = r->info.info6->architecture;
- info8.driver_path = r->info.info6->driver_path;
- info8.data_file = r->info.info6->data_file;
- info8.config_file = r->info.info6->config_file;
- info8.help_file = r->info.info6->help_file;
- info8.monitor_name = r->info.info6->monitor_name;
- info8.default_datatype = r->info.info6->default_datatype;
- if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
- info8.dependent_files = r->info.info6->dependent_files->string;
- }
- info8.driver_date = r->info.info6->driver_date;
- info8.driver_version = r->info.info6->driver_version;
- info8.manufacturer_name = r->info.info6->manufacturer_name;
- info8.manufacturer_url = r->info.info6->manufacturer_url;
- info8.hardware_id = r->info.info6->hardware_id;
- info8.provider = r->info.info6->provider;
- break;
- case 8:
- info8.version = r->info.info8->version;
- info8.driver_name = r->info.info8->driver_name;
- info8.architecture = r->info.info8->architecture;
- info8.driver_path = r->info.info8->driver_path;
- info8.data_file = r->info.info8->data_file;
- info8.config_file = r->info.info8->config_file;
- info8.help_file = r->info.info8->help_file;
- info8.monitor_name = r->info.info8->monitor_name;
- info8.default_datatype = r->info.info8->default_datatype;
- if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
- info8.dependent_files = r->info.info8->dependent_files->string;
- }
- if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
- info8.previous_names = r->info.info8->previous_names->string;
- }
- info8.driver_date = r->info.info8->driver_date;
- info8.driver_version = r->info.info8->driver_version;
- info8.manufacturer_name = r->info.info8->manufacturer_name;
- info8.manufacturer_url = r->info.info8->manufacturer_url;
- info8.hardware_id = r->info.info8->hardware_id;
- info8.provider = r->info.info8->provider;
- info8.print_processor = r->info.info8->print_processor;
- info8.vendor_setup = r->info.info8->vendor_setup;
- if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
- info8.color_profiles = r->info.info8->color_profiles->string;
- }
- info8.inf_path = r->info.info8->inf_path;
- info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
- if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
- info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
- }
- info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
- info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
- break;
- default:
- return false;
- }
-
- *_info8 = info8;
-
- return true;
-}
-
-
-uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
- struct spoolss_AddDriverInfoCtr *r,
- char **driver_name,
- uint32_t *version)
-{
- struct spoolss_DriverInfo8 info8;
-
- ZERO_STRUCT(info8);
-
- DEBUG(10,("adding a printer at level [%d]\n", r->level));
-
- if (!driver_info_ctr_to_info8(r, &info8)) {
- return -1;
- }
-
- *driver_name = talloc_strdup(mem_ctx, info8.driver_name);
- if (!*driver_name) {
- return -1;
- }
- *version = info8.version;
-
- return add_a_printer_driver_8(&info8);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo8 **driver,
- const char *drivername, const char *architecture,
- uint32_t version)
-{
- WERROR result;
- struct spoolss_DriverInfo3 info3;
- struct spoolss_DriverInfo8 *info8;
-
- ZERO_STRUCT(info3);
+ }
- /* Sometime we just want any version of the driver */
+ if (driver->config_file && strlen(driver->config_file)) {
+ if (!strequal(driver->config_file, driver->driver_path) &&
+ !strequal(driver->config_file, driver->data_file)) {
- if (version == DRIVER_ANY_VERSION) {
- /* look for Win2k first and then for NT4 */
- result = get_a_printer_driver_3(mem_ctx,
- &info3,
- drivername,
- architecture, 3);
- if (!W_ERROR_IS_OK(result)) {
- result = get_a_printer_driver_3(mem_ctx,
- &info3,
- drivername,
- architecture, 2);
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->config_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
+ goto err_exit;
+ }
}
- } else {
- result = get_a_printer_driver_3(mem_ctx,
- &info3,
- drivername,
- architecture,
- version);
}
- if (!W_ERROR_IS_OK(result)) {
- return result;
- }
+ if (driver->help_file && strlen(driver->help_file)) {
+ if (!strequal(driver->help_file, driver->driver_path) &&
+ !strequal(driver->help_file, driver->data_file) &&
+ !strequal(driver->help_file, driver->config_file)) {
- info8 = talloc_zero(mem_ctx, struct spoolss_DriverInfo8);
- if (!info8) {
- return WERR_NOMEM;
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->help_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
+ goto err_exit;
+ }
+ }
}
- info8->version = info3.version;
- info8->driver_name = info3.driver_name;
- info8->architecture = info3.architecture;
- info8->driver_path = info3.driver_path;
- info8->data_file = info3.data_file;
- info8->config_file = info3.config_file;
- info8->help_file = info3.help_file;
- info8->dependent_files = info3.dependent_files;
- info8->monitor_name = info3.monitor_name;
- info8->default_datatype = info3.default_datatype;
+ if (driver->dependent_files && driver->dependent_files->string) {
+ for (i=0; driver->dependent_files->string[i]; i++) {
+ if (!strequal(driver->dependent_files->string[i], driver->driver_path) &&
+ !strequal(driver->dependent_files->string[i], driver->data_file) &&
+ !strequal(driver->dependent_files->string[i], driver->config_file) &&
+ !strequal(driver->dependent_files->string[i], driver->help_file)) {
+ int j;
+ for (j=0; j < i; j++) {
+ if (strequal(driver->dependent_files->string[i], driver->dependent_files->string[j])) {
+ goto NextDriver;
+ }
+ }
- *driver = info8;
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->dependent_files->string[i],
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
+ goto err_exit;
+ }
+ }
+ NextDriver: ;
+ }
+ }
- return WERR_OK;
-}
+ err = WERR_OK;
+ err_exit:
+ unbecome_user();
+ err_free_conn:
+ TALLOC_FREE(smb_dname);
-/****************************************************************************
-****************************************************************************/
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
+ conn_free(conn);
+ }
-uint32_t free_a_printer_driver(struct spoolss_DriverInfo8 *driver)
-{
- talloc_free(driver);
- return 0;
+ return err;
}
-
/****************************************************************************
Determine whether or not a particular driver is currently assigned
to a printer
****************************************************************************/
-bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r)
+bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
+ const struct spoolss_DriverInfo8 *r)
{
int snum;
int n_services = lp_numservices();
- NT_PRINTER_INFO_LEVEL *printer = NULL;
bool in_use = False;
+ struct spoolss_PrinterInfo2 *pinfo2 = NULL;
+ WERROR result;
if (!r) {
return false;
/* loop through the printers.tdb and check for the drivername */
for (snum=0; snum<n_services && !in_use; snum++) {
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
+ if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
continue;
+ }
- if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
- continue;
+ result = winreg_get_printer(mem_ctx, b,
+ lp_servicename(snum),
+ &pinfo2);
+ if (!W_ERROR_IS_OK(result)) {
+ continue; /* skip */
+ }
- if (strequal(r->driver_name, printer->info_2->drivername))
+ if (strequal(r->driver_name, pinfo2->drivername)) {
in_use = True;
+ }
- free_a_printer( &printer, 2 );
+ TALLOC_FREE(pinfo2);
}
DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
if ( in_use ) {
- struct spoolss_DriverInfo8 *d;
+ struct spoolss_DriverInfo8 *driver;
WERROR werr;
DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
"Windows NT x86" version 2 or 3 left */
if (!strequal("Windows NT x86", r->architecture)) {
- werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", DRIVER_ANY_VERSION);
- }
- else {
- switch (r->version) {
- case 2:
- werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 3);
- break;
- case 3:
- werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 2);
- break;
- default:
- DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n",
- r->version));
- werr = WERR_UNKNOWN_PRINTER_DRIVER;
- break;
- }
+ werr = winreg_get_driver(mem_ctx, b,
+ "Windows NT x86",
+ r->driver_name,
+ DRIVER_ANY_VERSION,
+ &driver);
+ } else if (r->version == 2) {
+ werr = winreg_get_driver(mem_ctx, b,
+ "Windows NT x86",
+ r->driver_name,
+ 3, &driver);
+ } else if (r->version == 3) {
+ werr = winreg_get_driver(mem_ctx, b,
+ "Windows NT x86",
+ r->driver_name,
+ 2, &driver);
+ } else {
+ DEBUG(0, ("printer_driver_in_use: ERROR!"
+ " unknown driver version (%d)\n",
+ r->version));
+ werr = WERR_UNKNOWN_PRINTER_DRIVER;
}
/* now check the error code */
if ( W_ERROR_IS_OK(werr) ) {
/* it's ok to remove the driver, we have other architctures left */
in_use = False;
- free_a_printer_driver(d);
+ talloc_free(driver);
}
}
****************************************************************************/
bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
struct spoolss_DriverInfo8 *info)
{
int i;
- int ndrivers;
uint32 version;
- fstring *list = NULL;
struct spoolss_DriverInfo8 *driver;
bool in_use = false;
+ uint32_t num_drivers;
+ const char **drivers;
+ WERROR result;
if ( !info )
return False;
/* loop over all driver versions */
- DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
+ DEBUG(5,("printer_driver_files_in_use: Beginning search of drivers...\n"));
/* get the list of drivers */
- list = NULL;
- ndrivers = get_ntdrivers(&list, info->architecture, version);
+ result = winreg_get_driver_list(mem_ctx, b,
+ info->architecture, version,
+ &num_drivers, &drivers);
+ if (!W_ERROR_IS_OK(result)) {
+ return true;
+ }
- DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
- ndrivers, info->architecture, version));
+ DEBUGADD(4, ("we have:[%d] drivers in environment [%s] and version [%d]\n",
+ num_drivers, info->architecture, version));
/* check each driver for overlap in files */
- for (i=0; i<ndrivers; i++) {
- DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
+ for (i = 0; i < num_drivers; i++) {
+ DEBUGADD(5,("\tdriver: [%s]\n", drivers[i]));
driver = NULL;
- if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, list[i], info->architecture, version))) {
- SAFE_FREE(list);
+ result = winreg_get_driver(mem_ctx, b,
+ info->architecture, drivers[i],
+ version, &driver);
+ if (!W_ERROR_IS_OK(result)) {
+ talloc_free(drivers);
return True;
}
}
}
- free_a_printer_driver(driver);
+ talloc_free(driver);
}
- SAFE_FREE(list);
+ talloc_free(drivers);
- DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
+ DEBUG(5,("printer_driver_files_in_use: Completed search of drivers...\n"));
return in_use;
}
static NTSTATUS driver_unlink_internals(connection_struct *conn,
- const char *name)
+ const char *short_arch,
+ int vers,
+ const char *fname)
{
+ TALLOC_CTX *tmp_ctx = talloc_new(conn);
struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
+ char *print_dlr_path;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ print_dlr_path = talloc_asprintf(tmp_ctx, "%s/%d/%s",
+ short_arch, vers, fname);
+ if (print_dlr_path == NULL) {
+ goto err_out;
+ }
- status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
- &smb_fname);
+ status = create_synthetic_smb_fname(tmp_ctx, print_dlr_path,
+ NULL, NULL, &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto err_out;
}
status = unlink_internals(conn, NULL, 0, smb_fname, false);
-
- TALLOC_FREE(smb_fname);
+err_out:
+ talloc_free(tmp_ctx);
return status;
}
this.
****************************************************************************/
-static bool delete_driver_files(struct pipes_struct *rpc_pipe,
- const struct spoolss_DriverInfo8 *r)
+bool delete_driver_files(const struct auth_session_info *session_info,
+ const struct spoolss_DriverInfo8 *r)
{
- int i = 0;
- char *s;
- const char *file;
+ const char *short_arch;
connection_struct *conn;
NTSTATUS nt_status;
char *oldcwd;
- fstring printdollar;
+ char *printdollar = NULL;
int printdollar_snum;
bool ret = false;
DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
r->driver_name, r->version));
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
+ printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
+ if (!printdollar) {
+ return false;
+ }
if (printdollar_snum == -1) {
return false;
}
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ nt_status = create_conn_struct(talloc_tos(), smbd_server_conn, &conn,
+ printdollar_snum,
lp_pathname(printdollar_snum),
- rpc_pipe->server_info, &oldcwd);
+ session_info, &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("delete_driver_files: create_conn_struct "
"returned %s\n", nt_errstr(nt_status)));
return false;
}
+ nt_status = set_conn_force_user_group(conn, printdollar_snum);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("failed set force user / group\n"));
+ ret = false;
+ goto err_free_conn;
+ }
+
+ if (!become_user_by_session(conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ ret = false;
+ goto err_free_conn;
+ }
+
if ( !CAN_WRITE(conn) ) {
DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
- goto fail;
+ ret = false;
+ goto err_out;
+ }
+
+ short_arch = get_short_archi(r->architecture);
+ if (short_arch == NULL) {
+ DEBUG(0, ("bad architecture %s\n", r->architecture));
+ ret = false;
+ goto err_out;
}
- /* now delete the files; must strip the '\print$' string from
- fron of path */
+ /* now delete the files */
if (r->driver_path && r->driver_path[0]) {
- if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting driverfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting driverfile [%s]\n", r->driver_path));
+ driver_unlink_internals(conn, short_arch, r->version, r->driver_path);
}
if (r->config_file && r->config_file[0]) {
- if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting configfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting configfile [%s]\n", r->config_file));
+ driver_unlink_internals(conn, short_arch, r->version, r->config_file);
}
if (r->data_file && r->data_file[0]) {
- if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting datafile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting datafile [%s]\n", r->data_file));
+ driver_unlink_internals(conn, short_arch, r->version, r->data_file);
}
if (r->help_file && r->help_file[0]) {
- if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting helpfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting helpfile [%s]\n", r->help_file));
+ driver_unlink_internals(conn, short_arch, r->version, r->help_file);
}
- /* check if we are done removing files */
-
if (r->dependent_files) {
+ int i = 0;
while (r->dependent_files[i] && r->dependent_files[i][0]) {
- char *p;
-
- /* bypass the "\print$" portion of the path */
-
- if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
- file = p;
- DEBUG(10,("deleting dependent file [%s]\n", file));
- driver_unlink_internals(conn, file);
- }
-
+ DEBUG(10,("deleting dependent file [%s]\n", r->dependent_files[i]));
+ driver_unlink_internals(conn, short_arch, r->version, r->dependent_files[i]);
i++;
}
}
- goto done;
- fail:
- ret = false;
- done:
+ ret = true;
+ err_out:
+ unbecome_user();
+ err_free_conn:
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
return ret;
}
-/****************************************************************************
- Remove a printer driver from the TDB. This assumes that the the driver was
- previously looked up.
- ***************************************************************************/
-
-WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
- const struct spoolss_DriverInfo8 *r,
- uint32 version, bool delete_files )
-{
- char *key = NULL;
- const char *arch;
- TDB_DATA dbuf;
-
- /* delete the tdb data first */
-
- arch = get_short_archi(r->architecture);
- if (!arch) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
- if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
- arch, version, r->driver_name) < 0) {
- return WERR_NOMEM;
- }
-
- DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
- key, delete_files ? "TRUE" : "FALSE" ));
-
- /* check if the driver actually exists for this environment */
-
- dbuf = tdb_fetch_bystring( tdb_drivers, key );
- if ( !dbuf.dptr ) {
- DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));
- SAFE_FREE(key);
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- SAFE_FREE( dbuf.dptr );
-
- /* ok... the driver exists so the delete should return success */
-
- if (tdb_delete_bystring(tdb_drivers, key) == -1) {
- DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
- SAFE_FREE(key);
- return WERR_ACCESS_DENIED;
- }
-
- /*
- * now delete any associated files if delete_files == True
- * even if this part failes, we return succes because the
- * driver doesn not exist any more
- */
-
- if ( delete_files )
- delete_driver_files(rpc_pipe, r);
-
- DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
- SAFE_FREE(key);
-
- return WERR_OK;
-}
-
-/****************************************************************************
- 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) {
- 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[5]; /* 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;
- 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 ) {
- 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);
-
- /* 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)) {
- 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
3) "printer admins" (may result in numerous calls to winbind)
****************************************************************************/
-bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
+bool print_access_check(const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx, int snum,
int access_type)
{
- struct sec_desc_buf *secdesc = NULL;
+ struct spoolss_security_descriptor *secdesc = NULL;
uint32 access_granted;
+ size_t sd_size;
NTSTATUS status;
+ WERROR result;
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
- SE_PRIV se_printop = SE_PRINT_OPERATOR;
/* If user is NULL then use the current_user structure */
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if (server_info->utok.uid == sec_initial_uid()
- || user_has_privileges(server_info->ptok, &se_printop ) ) {
+ if (session_info->unix_token->uid == sec_initial_uid()
+ || security_token_has_privilege(session_info->security_token, SEC_PRIV_PRINT_OPERATOR)) {
return True;
}
/* Get printer name */
- pname = PRINTERNAME(snum);
+ pname = lp_printername(snum);
if (!pname || !*pname) {
errno = EACCES;
return False;
}
- if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) {
+ result = winreg_get_printer_secdesc_internal(mem_ctx,
+ get_session_info_system(),
+ msg_ctx,
+ pname,
+ &secdesc);
+ if (!W_ERROR_IS_OK(result)) {
talloc_destroy(mem_ctx);
errno = ENOMEM;
return False;
}
if (access_type == JOB_ACCESS_ADMINISTER) {
- struct sec_desc_buf *parent_secdesc = secdesc;
+ struct spoolss_security_descriptor *parent_secdesc = secdesc;
/* Create a child security descriptor to check permissions
against. This is because print jobs are child objects
objects of a printer. */
-
- status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False);
-
+ status = se_create_child_secdesc(mem_ctx,
+ &secdesc,
+ &sd_size,
+ parent_secdesc,
+ parent_secdesc->owner_sid,
+ parent_secdesc->group_sid,
+ false);
if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(mem_ctx);
errno = map_errno_from_nt_status(status);
return False;
}
- map_job_permissions(secdesc->sd);
+ map_job_permissions(secdesc);
} else {
- map_printer_permissions(secdesc->sd);
+ map_printer_permissions(secdesc);
}
/* Check access */
- status = se_access_check(secdesc->sd, server_info->ptok, access_type,
+ status = se_access_check(secdesc, session_info->security_token, access_type,
&access_granted);
DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
/* see if we need to try the printer admin list */
if (!NT_STATUS_IS_OK(status) &&
- (token_contains_name_in_list(uidtoname(server_info->utok.uid),
- NULL, NULL, server_info->ptok,
+ (token_contains_name_in_list(uidtoname(session_info->unix_token->uid),
+ session_info->info->domain_name,
+ NULL, session_info->security_token,
lp_printer_admin(snum)))) {
talloc_destroy(mem_ctx);
return True;
Check the time parameters allow a print operation.
*****************************************************************************/
-bool print_time_access_check(const char *servicename)
+bool print_time_access_check(const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *servicename)
{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
+ struct spoolss_PrinterInfo2 *pinfo2 = NULL;
+ WERROR result;
bool ok = False;
time_t now = time(NULL);
struct tm *t;
uint32 mins;
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
+ result = winreg_get_printer_internal(NULL, session_info, msg_ctx,
+ servicename, &pinfo2);
+ if (!W_ERROR_IS_OK(result)) {
return False;
+ }
- if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
+ if (pinfo2->starttime == 0 && pinfo2->untiltime == 0) {
ok = True;
+ }
t = gmtime(&now);
mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
- if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
+ if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) {
ok = True;
+ }
- free_a_printer(&printer, 2);
+ TALLOC_FREE(pinfo2);
- if (!ok)
+ if (!ok) {
errno = EACCES;
+ }
return ok;
}
-/****************************************************************************
- Fill in the servername sent in the _spoolss_open_printer_ex() call
-****************************************************************************/
-
-char* get_server_name( Printer_entry *printer )
+void nt_printer_remove(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *printer)
{
- return printer->servername;
+ WERROR result;
+
+ result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx,
+ printer, "");
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("nt_printer_remove: failed to remove printer %s: "
+ "%s\n", printer, win_errstr(result)));
+ }
}
+void nt_printer_add(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *printer)
+{
+ WERROR result;
+ result = winreg_create_printer_internal(mem_ctx, session_info, msg_ctx,
+ printer);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("nt_printer_add: failed to add printer %s: %s\n",
+ printer, win_errstr(result)));
+ }
+}