summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsource3/include/rpc_spoolss.h17
-rw-r--r--source3/printing/nt_printing.c217
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c43
3 files changed, 180 insertions, 97 deletions
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
index 82062d5278..18cf35f440 100755
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -401,16 +401,19 @@ PRINTER_MESSAGE_INFO;
/* FLAGS for SPOOLSS_DELETEPRINTERDRIVEREX */
-#define DPD_DELETE_UNUSED_FILES 0x00000001
-#define DPD_DELETE_SPECIFIC_VERSION 0x00000002
-#define DPD_DELETE_ALL_FILES 0x00000004
+#define DPD_DELETE_UNUSED_FILES 0x00000001
+#define DPD_DELETE_SPECIFIC_VERSION 0x00000002
+#define DPD_DELETE_ALL_FILES 0x00000004
+
+#define DRIVER_ANY_VERSION 0xffffffff
+#define DRIVER_MAX_VERSION 4
/* FLAGS for SPOOLSS_ADDPRINTERDRIVEREX */
-#define APD_STRICT_UPGRADE 0x00000001
-#define APD_STRICT_DOWNGRADE 0x00000002
-#define APD_COPY_ALL_FILES 0x00000004
-#define APD_COPY_NEW_FILES 0x00000008
+#define APD_STRICT_UPGRADE 0x00000001
+#define APD_STRICT_DOWNGRADE 0x00000002
+#define APD_COPY_ALL_FILES 0x00000004
+#define APD_COPY_NEW_FILES 0x00000008
/* this struct is undocumented */
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 2abe27b95d..fe90625e78 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1683,13 +1683,13 @@ static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
+static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring driver, fstring arch)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
ZERO_STRUCT(info);
- fstrcpy(info.name, in_prt);
+ fstrcpy(info.name, driver);
fstrcpy(info.defaultdatatype, "RAW");
fstrcpy(info.driverpath, "");
@@ -1710,7 +1710,7 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
+static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, fstring arch, uint32 version)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
TDB_DATA kbuf, dbuf;
@@ -1721,21 +1721,19 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
ZERO_STRUCT(driver);
- get_short_archi(architecture, in_arch);
+ get_short_archi(architecture, arch);
- DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
+ DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
- slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
+ slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername);
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
dbuf = tdb_fetch(tdb_drivers, kbuf);
-#if 0
- if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
-#else
- if (!dbuf.dptr) return WERR_ACCESS_DENIED;
-#endif
+ if (!dbuf.dptr)
+ return WERR_ACCESS_DENIED;
+
len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
&driver.cversion,
driver.name,
@@ -1771,7 +1769,7 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
if (len != dbuf.dsize) {
SAFE_FREE(driver.dependentfiles);
- return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
+ return get_a_printer_driver_3_default(info_ptr, drivername, arch);
}
*info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
@@ -3335,17 +3333,31 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
/****************************************************************************
****************************************************************************/
WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
- fstring printername, fstring architecture, uint32 version)
+ fstring drivername, fstring architecture, uint32 version)
{
WERROR result;
switch (level)
{
case 3:
- {
- result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
+ /* Sometime we just want any version of the driver */
+
+ if ( version == DRIVER_ANY_VERSION ) {
+ /* look for Win2k first and then for NT4 */
+ result = get_a_printer_driver_3(&driver->info_3, drivername,
+ architecture, 3);
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ result = get_a_printer_driver_3( &driver->info_3,
+ drivername, architecture, 2 );
+ }
+ }
+ else {
+ result = get_a_printer_driver_3(&driver->info_3, drivername,
+ architecture, version);
+ }
break;
- }
+
default:
result=W_ERROR(1);
break;
@@ -3353,6 +3365,7 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
if (W_ERROR_IS_OK(result))
dump_a_printer_driver(*driver, level);
+
return result;
}
@@ -3411,91 +3424,144 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
Determine whether or not a particular driver is currently assigned
to a printer
****************************************************************************/
-BOOL printer_driver_in_use (char *arch, char *driver)
+
+BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i )
{
- TDB_DATA kbuf, newkey, dbuf;
- NT_PRINTER_INFO_LEVEL_2 info;
- int ret;
+ int snum;
+ int n_services = lp_numservices();
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
- if (!tdb_printers)
- if (!nt_printing_init())
- return False;
+ if ( !i )
+ return False;
- DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
+ DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
/* loop through the printers.tdb and check for the drivername */
- for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
- newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
+
+ for (snum=0; snum<n_services; snum++)
{
-
- dbuf = tdb_fetch(tdb_printers, kbuf);
- if (!dbuf.dptr)
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
continue;
-
- if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0)
+
+ if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) )
continue;
+
+ if ( !StrCaseCmp(i->name, printer->info_2->drivername) ) {
+ free_a_printer( &printer, 2 );
+ return True;
+ }
+
+ free_a_printer( &printer, 2 );
+ }
+
+ DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
+
+ /* report that the driver is not in use by default */
+
+ return False;
+}
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "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);
+/**********************************************************************
+ Check if any of the files used by src are also used by drv
+ *********************************************************************/
- SAFE_FREE(dbuf.dptr);
+static BOOL check_driver_file_overlap( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
+{
+
- if (ret == -1) {
- DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
- info.printername));
- continue;
- }
+ return False;
+}
+
+/****************************************************************************
+ Determine whether or not a particular driver files are currently being
+ used by any other driver. Requires using the full path from [print$]
+****************************************************************************/
+
+BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
+{
+ int i;
+ int ndrivers;
+ uint32 version;
+ fstring *list = NULL;
+ NT_PRINTER_DRIVER_INFO_LEVEL driver;
+
+ /* loop over all driver versions */
+
+ DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
+
+ for ( version=0; version<DRIVER_MAX_VERSION; version++ )
+ {
+ /* get the list of drivers */
- DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
- info.printername, info.drivername));
+ list = NULL;
+ ndrivers = get_ntdrivers(&list, info->environment, version);
+
+ DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
+ ndrivers, info->environment, version));
+
+ if(ndrivers == -1)
+ continue;
- if (strcmp(info.drivername, driver) == 0)
+ /* check each driver for overlap in files */
+
+ for (i=0; i<ndrivers; i++)
{
- DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
- info.printername, driver));
- return True;
+ DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
+
+ ZERO_STRUCT(driver);
+
+ if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i],
+ info->environment, version)) )
+ {
+ SAFE_FREE(list);
+ return True;
+ }
+
+ /* check if d2 uses any files from d1 */
+
+ if ( check_driver_file_overlap(info, driver.info_3) ) {
+ free_a_printer_driver(driver, 3);
+ SAFE_FREE( list );
+ return True;
+ }
+
+ free_a_printer_driver(driver, 3);
}
+
+ SAFE_FREE(list);
}
- DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
-
+ DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
- /* report that the driver is in use by default */
return False;
}
/****************************************************************************
+ Actually delete the driver files. Make sure that
+ printer_driver_files_in_use() return False before calling
+ this.
+****************************************************************************/
+
+static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i )
+{
+
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
Remove a printer driver from the TDB. This assumes that the the driver was
previously looked up.
***************************************************************************/
-WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
+WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_files)
{
pstring key;
fstring arch;
TDB_DATA kbuf;
-
+ /* delete the tdb data first */
+
get_short_archi(arch, i->environment);
slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
arch, i->cversion, i->name);
@@ -3512,6 +3578,15 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
i->name));
+ /*
+ * 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( i );
+
return WERR_OK;
}
/****************************************************************************
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 70964ce668..8acdd9d5ab 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -1562,16 +1562,21 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* this is what NT returns */
return WERR_INVALID_ENVIRONMENT;
}
+
+ /* if they said "Windows NT x86", then try for version 2 & 3 */
+
+ if ( version == 2 )
+ version = DRIVER_ANY_VERSION;
ZERO_STRUCT(info);
+
if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
return WERR_UNKNOWN_PRINTER_DRIVER;
-
- if (printer_driver_in_use(arch, driver))
+ if (printer_driver_in_use(info.info_3))
return WERR_PRINTER_DRIVER_IN_USE;
- return delete_printer_driver(info.info_3);
+ return delete_printer_driver(info.info_3, False);
}
/********************************************************************
@@ -1584,6 +1589,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
fstring arch;
NT_PRINTER_DRIVER_INFO_LEVEL info;
int version;
+ uint32 flags = q_u->delete_flags;
unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
@@ -1594,18 +1600,25 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
return WERR_INVALID_ENVIRONMENT;
}
- if (q_u->delete_flags & DPD_DELETE_SPECIFIC_VERSION)
+ if ( flags & DPD_DELETE_SPECIFIC_VERSION )
version = q_u->version;
+ else if ( version == 2 )
+ /* if they said "Windows NT x86", then try for version 2 & 3 */
+ version = DRIVER_ANY_VERSION;
ZERO_STRUCT(info);
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
- return WERR_UNKNOWN_PRINTER_DRIVER;
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
+ return WERR_UNKNOWN_PRINTER_DRIVER;
- if (printer_driver_in_use(arch, driver))
+ if ( printer_driver_in_use(info.info_3) )
return WERR_PRINTER_DRIVER_IN_USE;
+
+ if ( printer_driver_files_in_use(info.info_3) )
+ /* no idea of the correct error here */
+ return WERR_ACCESS_DENIED;
- return delete_printer_driver(info.info_3);
+ return delete_printer_driver(info.info_3, True);
}
@@ -5869,8 +5882,6 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
{
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
-/* uint32 level = q_u->level; - notused. */
-/* JOB_INFO *ctr = &q_u->ctr; - notused. */
uint32 command = q_u->command;
struct current_user user;
@@ -5928,9 +5939,7 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
*returned=0;
-#define MAX_VERSION 4
-
- for (version=0; version<MAX_VERSION; version++) {
+ for (version=0; version<DRIVER_MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6009,9 +6018,7 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
*returned=0;
-#define MAX_VERSION 4
-
- for (version=0; version<MAX_VERSION; version++) {
+ for (version=0; version<DRIVER_MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
@@ -6091,9 +6098,7 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
*returned=0;
-#define MAX_VERSION 4
-
- for (version=0; version<MAX_VERSION; version++) {
+ for (version=0; version<DRIVER_MAX_VERSION; version++) {
list=NULL;
ndrivers=get_ntdrivers(&list, architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));