summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-06-24 19:51:23 +0000
committerGerald Carter <jerry@samba.org>2002-06-24 19:51:23 +0000
commit900fb62238be30cdc87bfd2bede6fdff611ebae5 (patch)
treecb5073f32d4faf1a3eee3392da04b3b09424d10f /source3
parent24b67730bf7bbf4414df99129a3cc20aa93dc0da (diff)
downloadsamba-900fb62238be30cdc87bfd2bede6fdff611ebae5.tar.gz
samba-900fb62238be30cdc87bfd2bede6fdff611ebae5.tar.bz2
samba-900fb62238be30cdc87bfd2bede6fdff611ebae5.zip
printing merge from SAMBA_2_2. Ther server code looks to be in sync now.
Mostly formatting and s/free/SAFE_FREE/g changes with the two exceptions being * John driver init changes * Tim's printer enumeration bug fix (This used to be commit f7536762863811f96364e8acd3716bdb7d665bbf)
Diffstat (limited to 'source3')
-rw-r--r--source3/printing/nt_printing.c19
-rw-r--r--source3/printing/pcap.c22
-rw-r--r--source3/printing/print_cups.c2
-rw-r--r--source3/printing/printing.c20
-rw-r--r--source3/rpc_parse/parse_spoolss.c2
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c137
6 files changed, 131 insertions, 71 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index ecf873c1ba..08d5ea430a 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2838,7 +2838,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
Initialize printer devmode & data with previously saved driver init values.
****************************************************************************/
-static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
+static BOOL set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
{
int len = 0;
pstring key;
@@ -2891,9 +2891,14 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
* NT/2k does not change out the entire DeviceMode of a printer
* when changing the driver. Only the driverextra, private, &
* driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
+ *
+ * Later e4xamination revealed that Windows NT/2k does reset the
+ * the printer's device mode, bit **only** when you change a
+ * property of the device mode such as the page orientation.
+ * --jerry
*/
-#if 0 /* JERRY */
+#if 1 /* JERRY */
/*
* Bind the saved DEVMODE to the new the printer.
@@ -2945,19 +2950,19 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
is bound to the new printer.
****************************************************************************/
-uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
+BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
- uint32 result;
+ BOOL result = False;
switch (level)
{
case 2:
- {
result=set_driver_init_2(printer->info_2);
break;
- }
+
default:
- result=1;
+ DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
+ level));
break;
}
diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c
index 920c6f354e..01e03c7c6b 100644
--- a/source3/printing/pcap.c
+++ b/source3/printing/pcap.c
@@ -111,7 +111,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
iEtat = 0;
/* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
{
if (*line == '*' || *line == 0)
continue;
@@ -181,7 +181,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
{
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- free(pName);
+ SAFE_FREE(pName);
return(False);
}
slprintf(pName, iLg + 9, "%s:",pszPrintername);
@@ -189,7 +189,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
/*DEBUG(3,( " Looking for entry %s\n",pName));*/
iEtat = 0;
/* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
{
if (*line == '*' || *line == 0)
continue;
@@ -208,8 +208,8 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
{
/* name is found without stanza device */
/* probably a good printer ??? */
- free (line);
- free(pName);
+ SAFE_FREE (line);
+ SAFE_FREE(pName);
fclose(pfile);
return(True);
}
@@ -222,15 +222,15 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
else if (strlocate(line,"device"))
{
/* it's a good virtual printer */
- free (line);
- free(pName);
+ SAFE_FREE (line);
+ SAFE_FREE(pName);
fclose(pfile);
return(True);
}
break;
}
}
- free (pName);
+ SAFE_FREE (pName);
x_fclose(pfile);
return(False);
}
@@ -288,7 +288,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
return(False);
}
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
{
if (*line == '#' || *line == 0)
continue;
@@ -307,7 +307,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
{
/* normalise the case */
pstrcpy(pszPrintername,p);
- free(line);
+ SAFE_FREE(line);
x_fclose(pfile);
return(True);
}
@@ -369,7 +369,7 @@ void pcap_printer_fn(void (*fn)(char *, char *))
return;
}
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); SAFE_FREE(line))
{
if (*line == '#' || *line == 0)
continue;
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index b5315e10b2..51ebb739a3 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -824,7 +824,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
ippDelete(response);
httpClose(http);
- free (queue);
+ SAFE_FREE(queue);
return (0);
}
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 47fc019d64..aa9df5e47f 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -52,7 +52,8 @@ BOOL print_backend_init(void)
{
char *sversion = "INFO/version";
- if (tdb && local_pid == sys_getpid()) return True;
+ if (tdb && local_pid == sys_getpid())
+ return True;
tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb) {
DEBUG(0,("print_backend_init: Failed to open printing backend database %s\n",
@@ -108,7 +109,7 @@ static struct printjob *print_job_find(int jobid)
return NULL;
memcpy(&pjob, ret.dptr, sizeof(pjob));
- free(ret.dptr);
+ SAFE_FREE(ret.dptr);
return &pjob;
}
@@ -291,7 +292,7 @@ static pid_t get_updating_pid(fstring printer_name)
return (pid_t)-1;
memcpy(&updating_pid, data.dptr, sizeof(pid_t));
- free(data.dptr);
+ SAFE_FREE(data.dptr);
if (process_exists(updating_pid))
return updating_pid;
@@ -568,10 +569,9 @@ BOOL print_job_exists(int jobid)
return tdb_exists(tdb, print_key(jobid));
}
-
/****************************************************************************
- Work out which service a jobid is for
- note that we have to look up by queue name to ensure that it works for
+ Work out which service a jobid is for.
+ Note that we have to look up by queue name to ensure that it works for
other than the process that started the job.
****************************************************************************/
@@ -922,7 +922,7 @@ static int get_queue_status(int snum, print_status_struct *status)
if (data.dsize == sizeof(print_status_struct)) {
memcpy(status, data.dptr, sizeof(print_status_struct));
}
- free(data.dptr);
+ SAFE_FREE(data.dptr);
}
return status->qcount;
}
@@ -968,7 +968,7 @@ static int get_total_jobs(int snum)
}
/***************************************************************************
-start spooling a job - return the jobid
+ Start spooling a job - return the jobid.
***************************************************************************/
int print_job_start(struct current_user *user, int snum, char *jobname)
@@ -1116,7 +1116,7 @@ to open spool file %s.\n", pjob.filename));
}
/****************************************************************************
- Update the number of pages spooled to jobid.
+ Update the number of pages spooled to jobid
****************************************************************************/
void print_job_endpage(int jobid)
@@ -1330,7 +1330,7 @@ int print_queue_status(int snum,
if (data.dsize == sizeof(*status)) {
memcpy(status, data.dptr, sizeof(*status));
}
- free(data.dptr);
+ SAFE_FREE(data.dptr);
}
/*
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 60b5e60a81..aa7fcd0010 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -695,6 +695,7 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
{
+ DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
return False;
available_space -= sizeof(uint32);
@@ -1115,6 +1116,7 @@ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
q_u->handle = *handle;
init_unistr2(&q_u->valuename, valuename, strlen(valuename) + 1);
q_u->size = size;
+
return True;
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index fc63275869..56806823d1 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -809,8 +809,10 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
/* Iterate the printer list */
- for (snum=0; snum<n_services; snum++) {
- if (lp_snum_ok(snum) && lp_print_ok(snum) ) {
+ for (snum=0; snum<n_services; snum++)
+ {
+ if (lp_snum_ok(snum) && lp_print_ok(snum) )
+ {
WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
@@ -818,15 +820,19 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
if (!W_ERROR_IS_OK(result))
continue;
- if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername)) {
+ if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
+ {
DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
+
/* all we care about currently is the change_id */
+
result = mod_a_printer(*printer, 2);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
dos_errstr(result)));
}
}
+
free_a_printer(&printer, 2);
}
}
@@ -1000,16 +1006,6 @@ Can't find printer handle we created for printer %s\n", name ));
}
/*
- if (printer_default->datatype_ptr != NULL)
- {
- unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
- set_printer_hnd_datatype(handle, datatype);
- }
- else
- set_printer_hnd_datatype(handle, "");
-*/
-
- /*
First case: the user is opening the print server:
Disallow MS AddPrinterWizard if parameter disables it. A Win2k
@@ -3492,10 +3488,26 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
enum_all_printers_info_1_network.
*********************************************************************/
-static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
+ char *s = name;
+
DEBUG(4,("enum_all_printers_info_1_network\n"));
+ /* If we respond to a enum_printers level 1 on our name with flags
+ set to PRINTER_ENUM_REMOTE with a list of printers then these
+ printers incorrectly appear in the APW browse list.
+ Specifically the printers for the server appear at the workgroup
+ level where all the other servers in the domain are
+ listed. Windows responds to this call with a
+ WERR_CAN_NOT_COMPLETE so we should do the same. */
+
+ if (name[0] == '\\' && name[1] == '\\')
+ s = name + 2;
+
+ if (is_myname_or_ipaddr(s))
+ return WERR_CAN_NOT_COMPLETE;
+
return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
}
@@ -3582,7 +3594,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
if (flags & PRINTER_ENUM_NETWORK)
- return enum_all_printers_info_1_network(buffer, offered, needed, returned);
+ return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
return WERR_OK; /* NT4sp5 does that */
}
@@ -5247,7 +5259,10 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
* bound to the printer, simulating what happens in the Windows arch.
*/
if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){
- set_driver_init(printer, 2);
+ if (!set_driver_init(printer, 2)) {
+ DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
+ printer->info_2->drivername));
+ }
msg.flags |= PRINTER_MESSAGE_DRIVER;
}
}
@@ -6603,16 +6618,70 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
driver_name));
}
- /* if driver is not 9x, delete existing driver init data */
+ /*
+ * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
+ * decide if the driver init data should be deleted. The rules are:
+ * 1) never delete init data if it is a 9x driver, they don't use it anyway
+ * 2) delete init data only if there is no 2k/Xp driver
+ * 3) always delete init data
+ * The generalized rule is always use init data from the highest order driver.
+ * It is necessary to follow the driver install by an initialization step to
+ * finish off this process.
+ */
+ if (level == 3)
+ version = driver.info_3->cversion;
+ else if (level == 6)
+ version = driver.info_6->version;
+ else
+ version = -1;
+ switch (version) {
+ /*
+ * 9x printer driver - never delete init data
+ */
+ case 0:
+ DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
+ driver_name));
+ break;
+
+ /*
+ * Nt or 2k (compatiblity mode) printer driver - only delete init data if
+ * there is no 2k/Xp driver init data for this driver name.
+ */
+ case 2:
+ {
+ NT_PRINTER_DRIVER_INFO_LEVEL driver1;
- if ((level == 3 && driver.info_3->cversion != 0) ||
- (level == 6 && driver.info_6->version != 0)) {
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
+ /*
+ * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
+ */
if (!del_driver_init(driver_name))
- DEBUG(3,("_spoolss_addprinterdriver: del_driver_init(%s) failed!\n", driver_name));
+ DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
} else {
- DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n", driver_name));
+ /*
+ * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
+ */
+ free_a_printer_driver(driver1,3);
+ DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
+ driver_name));
+ }
+ }
+ break;
+
+ /*
+ * 2k or Xp printer driver - always delete init data
+ */
+ case 3:
+ if (!del_driver_init(driver_name))
+ DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
+ break;
+
+ default:
+ DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
+ break;
}
+
done:
free_a_printer_driver(driver, level);
return err;
@@ -6756,23 +6825,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if ( (in_value_len==0) && (in_data_len==0) ) {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
-#if 0
- /*
- * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
- * if this parameter size doesn't exist.
- * Ok - my opinion here is that the client is not asking for the greatest
- * possible size of all the parameters, but is asking specifically for the size needed
- * for this specific parameter. In that case we can remove the loop below and
- * simplify this lookup code considerably. JF - comments welcome. JRA.
- */
-
- if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
- SAFE_FREE(data);
- free_a_printer(&printer, 2);
- return WERR_NO_MORE_ITEMS;
- }
-#endif
-
SAFE_FREE(data);
param_index=0;
@@ -7925,7 +7977,7 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
- if (get_short_archi(short_archi, long_archi)==FALSE)
+ if (get_short_archi(short_archi, long_archi)==False)
return WERR_INVALID_ENVIRONMENT;
if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
@@ -7958,6 +8010,7 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
NEW_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
+ WERROR result;
/* that's an [in out] buffer */
spoolss_move_buffer(q_u->buffer, &r_u->buffer);
@@ -7969,11 +8022,11 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
switch(level) {
case 1:
- return getprintprocessordirectory_level_1
+ result = getprintprocessordirectory_level_1
(&q_u->name, &q_u->environment, buffer, offered, needed);
default:
- return WERR_UNKNOWN_LEVEL;
+ result = WERR_UNKNOWN_LEVEL;
}
- return WERR_ACCESS_DENIED;
+ return result;
}