summaryrefslogtreecommitdiff
path: root/source3/printing
diff options
context:
space:
mode:
authorDavid O'Neill <dmo@samba.org>2001-01-29 21:34:08 +0000
committerDavid O'Neill <dmo@samba.org>2001-01-29 21:34:08 +0000
commit2506c61ab3bd667d54c5e004cc80ce5e40643b5d (patch)
treeb31d685b78a8ba71f3599aa481ce281d5fea290b /source3/printing
parent9ec19336e519ef3543eb9d3eafb24585657a2e8d (diff)
downloadsamba-2506c61ab3bd667d54c5e004cc80ce5e40643b5d.tar.gz
samba-2506c61ab3bd667d54c5e004cc80ce5e40643b5d.tar.bz2
samba-2506c61ab3bd667d54c5e004cc80ce5e40643b5d.zip
Changes from APPLIANCE_HEAD:
source/include/proto.h - make proto source/printing/nt_printing.c source/rpc_server/srv_spoolss_nt.c - Fix for the overwriting of printerdata entries when WinNT and Win2k are modifying printer parameters on PCL printers. Turns out that Win2k creates a printer with a NULL devmode entry and then expects to set it on *OPEN* (yes this is insane). So we cannot return a "default" devmode for a printer - and we must allow an open to set it. source/tdb/tdb.c - Show freelist in an easier format. Show total free. - When storing a new record, allocate memory for the key + data before the tdb_allocate() as if the malloc fails a (sparse) hole is left in the tdb. source/tdb/tdbtool.c - Show freelist in an easier format. Show total free. source/tdb/Makefile - cleaned up Makefile dependancies source/smbd/lanman.c - Fix for Win9x corrupting it's own parameter string. source/printing/printfsp.c source/printing/printing.c source/rpc_server/srv_spoolss_nt.c source/smbd/close.c - Added normal close parameter into print_fsp_end() which treats an abnormal close as error condition and deletes the spool file. (This used to be commit 025f7a092ad258ff774e3f5e53737f8210cc8af6)
Diffstat (limited to 'source3/printing')
-rw-r--r--source3/printing/nt_printing.c105
-rw-r--r--source3/printing/printfsp.c4
-rw-r--r--source3/printing/printing.c13
3 files changed, 94 insertions, 28 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index eb4b243f2e..ff24849f0b 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1722,8 +1722,6 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
char *buf;
int buflen, len, ret;
TDB_DATA kbuf, dbuf;
- NT_PRINTER_INFO_LEVEL_2 *old_printer = NULL;
- NT_DEVICEMODE *devmode = NULL;
/*
* in addprinter: no servername and the printer is the name
@@ -1779,20 +1777,7 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
info->datatype,
info->parameters);
- /* do not write a NULL devicemode if there was previously
- a valid one. Windows 2000 likes to send setprinter calls
- with NULL devicemodes (e.g. HP 4050 PCL6 driver) --jerry
-
- We need to get the previously saved information for
- this printer if the devicemode is NULL */
- devmode = info->devmode;
- if (!devmode && info->sharename)
- {
- get_a_printer_2(&old_printer, info->sharename);
- if (old_printer)
- devmode = old_printer->devmode;
- }
- len += pack_devicemode(devmode, buf+len, buflen-len);
+ len += pack_devicemode(info->devmode, buf+len, buflen-len);
len += pack_specifics(info->specific, buf+len, buflen-len);
@@ -1821,9 +1806,6 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
info->sharename, info->drivername, info->portname, len));
- if (old_printer)
- free_nt_printer_info_level_2(&old_printer);
-
return ret;
}
@@ -1977,8 +1959,7 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
nt_devmode->panningwidth = 0;
nt_devmode->panningheight = 0;
- nt_devmode->private=NULL;
-
+ nt_devmode->private = NULL;
return nt_devmode;
}
@@ -2110,7 +2091,7 @@ static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
if (devmode.private) {
/* the len in tdb_unpack is an int value and
- * devmoce.driverextra is only a short
+ * devmode.driverextra is only a short
*/
len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
devmode.driverextra=(uint16)extra_len;
@@ -2198,8 +2179,18 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
info.default_priority = 1;
info.setuptime = (uint32)time(NULL);
+#if 1 /* JRA - NO NOT CHANGE ! */
+ info.devmode = NULL;
+#else
+ /*
+ * We should not return a default devicemode, as this causes
+ * Win2K to not send the correct one on PCL drivers. It needs to
+ * see a null devicemode so it can then overwrite the devicemode
+ * on OpenPrinterEx. Yes this *is* insane :-). JRA.
+ */
if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
goto fail;
+#endif
if (!nt_printing_getsec(sharename, &info.secdesc_buf))
goto fail;
@@ -2421,9 +2412,13 @@ uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
NTTIME time_nt;
time_t time_unix = time(NULL);
unix_to_nt_time(&time_nt, time_unix);
- printer.info_2->changeid=time_nt.low;
+ if (printer.info_2->changeid==time_nt.low)
+ printer.info_2->changeid++;
+ else
+ printer.info_2->changeid=time_nt.low;
printer.info_2->c_setprinter++;
+
result=update_a_printer_2(printer.info_2);
break;
}
@@ -3145,5 +3140,69 @@ BOOL print_time_access_check(int snum)
return ok;
}
+/****************************************************************************
+ Attempt to write a default device.
+*****************************************************************************/
+
+uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+
+ uint32 result = 0;
+
+ /*
+ * Don't bother if no default devicemode was sent.
+ */
+
+ if (printer_default->devmode_cont.devmode == NULL)
+ return 0;
+
+ if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ return ERROR_ACCESS_DENIED;
+
+ /*
+ * Just ignore it if we already have a devmode.
+ */
+
+ if (printer->info_2->devmode != NULL)
+ goto done;
+
+ /*
+ * We don't have a devicemode and we're trying to write
+ * one. Check we have the access needed.
+ */
+
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
+ lp_servicename(snum) ));
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
+
+ /*
+ * Convert the on the wire devicemode format to the internal one.
+ */
+
+ if (!convert_devicemode(printer->info_2->printername,
+ printer_default->devmode_cont.devmode,
+ &printer->info_2->devmode)) {
+ result = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ /*
+ * Finally write back to the tdb.
+ */
+
+ if (add_a_printer(*printer, 2)!=0) {
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
+
+ done:
+
+ free_a_printer(&printer, 2);
+ return result;
+}
#undef OLD_NTDOMAIN
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index 9b5a4877ee..f6ab69fd93 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -82,9 +82,9 @@ files_struct *print_fsp_open(connection_struct *conn,char *jobname)
/****************************************************************************
print a file - called on closing the file
****************************************************************************/
-void print_fsp_end(files_struct *fsp)
+void print_fsp_end(files_struct *fsp, BOOL normal_close)
{
- print_job_end(fsp->print_jobid);
+ print_job_end(fsp->print_jobid, normal_close);
if (fsp->fsp_name) {
string_free(&fsp->fsp_name);
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 46d872df7c..4dbb01e839 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -950,9 +950,11 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
/****************************************************************************
Print a file - called on closing the file. This spools the job.
+ If normal close is false then we're tearing down the jobs - treat as an
+ error.
****************************************************************************/
-BOOL print_job_end(int jobid)
+BOOL print_job_end(int jobid, BOOL normal_close)
{
struct printjob *pjob = print_job_find(jobid);
int snum, ret;
@@ -970,12 +972,17 @@ BOOL print_job_end(int jobid)
snum = print_job_snum(jobid);
- if (sys_fstat(pjob->fd, &sbuf) == 0) {
+ if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
pjob->size = sbuf.st_size;
close(pjob->fd);
pjob->fd = -1;
} else {
- /* Couldn't stat the job file, so something has gone wrong. Cleanup */
+
+ /*
+ * Not a normal close or we couldn't stat the job file,
+ * so something has gone wrong. Cleanup.
+ */
+
unlink(pjob->filename);
tdb_delete(tdb, print_key(jobid));
return False;