summaryrefslogtreecommitdiff
path: root/source3/printing/printing.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-02-22 01:31:55 +0000
committerJeremy Allison <jra@samba.org>2001-02-22 01:31:55 +0000
commit201753ddc623a18f4ddd0d9a19391ea0471d4c49 (patch)
treef8e52b7b06464d16b93522a8bf9abbb6c343be17 /source3/printing/printing.c
parent5fa7c79c336584b9eb868abaae69f8fb5950c43b (diff)
downloadsamba-201753ddc623a18f4ddd0d9a19391ea0471d4c49.tar.gz
samba-201753ddc623a18f4ddd0d9a19391ea0471d4c49.tar.bz2
samba-201753ddc623a18f4ddd0d9a19391ea0471d4c49.zip
Fixed file descriptor leak in error processing of print jobs.
NT sends "delete on close" to cancel a print job copied from the command line. Deal with this. Merged JohnR's fixes for print job errors. Jeremy. (This used to be commit 2060d74e48d62c99a1689ee02ac435b71918ddf0)
Diffstat (limited to 'source3/printing/printing.c')
-rw-r--r--source3/printing/printing.c91
1 files changed, 39 insertions, 52 deletions
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 9ed33bc6ae..49681d9040 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -38,6 +38,9 @@ extern int DEBUGLEVEL;
jobids are assigned when a job starts spooling.
*/
+#define NEXT_JOBID(j) ((j+1) % PRINT_MAX_JOBID > 0 ? (j+1) % PRINT_MAX_JOBID : 1)
+
+
struct printjob {
pid_t pid; /* which process launched the job */
int sysjob; /* the system (lp) job number */
@@ -588,9 +591,11 @@ static BOOL is_owner(struct current_user *user, int jobid)
if (!pjob || !user) return False;
if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- return strequal(pjob->user, vuser->user.smb_name);
+ return strequal(pjob->user,
+ unix_to_dos(vuser->user.smb_name,False));
} else {
- return strequal(pjob->user, uidtoname(user->uid));
+ return strequal(pjob->user,
+ unix_to_dos(uidtoname(user->uid),False));
}
}
@@ -884,9 +889,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
fstrcpy(pjob.jobname, jobname);
if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- fstrcpy(pjob.user, vuser->user.smb_name);
+ fstrcpy(pjob.user, unix_to_dos(vuser->user.smb_name,False));
} else {
- fstrcpy(pjob.user, uidtoname(user->uid));
+ fstrcpy(pjob.user, unix_to_dos(uidtoname(user->uid),False));
}
fstrcpy(pjob.qname, lp_servicename(snum));
@@ -898,10 +903,8 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
if (next_jobid == -1) next_jobid = 1;
- for (jobid = next_jobid+1; jobid != next_jobid; ) {
+ for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
if (!print_job_exists(jobid)) break;
- jobid = (jobid + 1) % PRINT_MAX_JOBID;
- if (jobid == 0) jobid = 1;
}
if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
jobid = -1;
@@ -922,23 +925,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
goto next_jobnum;
}
pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
- if (pjob.fd == -1) {
- if (errno == EACCES) {
- /* Common setup error, force a report. */
- DEBUG(0, ("print_job_start: insufficient permissions "
- "to open spool file %s.\n",
- pjob.filename));
- }
- else {
- /* Normal case, report at level 3 and above.*/
- DEBUG(3, ("print_job_start: can't open spool "
- "file %s,\n",
- pjob.filename));
- DEBUGADD(3, ("errno = %d (%s).\n", errno,
- strerror(errno)));
- }
- goto fail;
- }
+ if (pjob.fd == -1) goto fail;
print_job_store(jobid, &pjob);
@@ -1000,12 +987,14 @@ BOOL print_job_end(int jobid, BOOL normal_close)
* 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;
+ close(pjob->fd);
+ pjob->fd = -1;
+ goto fail;
}
-
+
+ /* Technically, this is not quit right. If the printer has a separator
+ * page turned on, the NT spooler prints the separator page even if the
+ * print job is 0 bytes. 010215 JRR */
if (pjob->size == 0) {
/* don't bother spooling empty files */
unlink(pjob->filename);
@@ -1016,17 +1005,14 @@ BOOL print_job_end(int jobid, BOOL normal_close)
/* we print from the directory path to give the best chance of
parsing the lpq output */
wd = sys_getwd(current_directory);
- if (!wd)
- return False;
+ if (!wd) goto fail;
pstrcpy(print_directory, pjob->filename);
p = strrchr(print_directory,'/');
- if (!p)
- return False;
+ if (!p) goto fail;
*p++ = 0;
- if (chdir(print_directory) != 0)
- return False;
+ if (chdir(print_directory) != 0) goto fail;
pstrcpy(jobname, pjob->jobname);
pstring_sub(jobname, "'", "_");
@@ -1041,23 +1027,24 @@ BOOL print_job_end(int jobid, BOOL normal_close)
chdir(wd);
- if (ret == 0) {
- /* The print job has been sucessfully handed over to the back-end */
-
- pjob->spooled = True;
- print_job_store(jobid, pjob);
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum)) print_queue_update(snum);
-
- return True;
- } else {
- /* The print job was not succesfully started. Cleanup */
- /* Still need to add proper error return propagation! 010122:JRR */
- unlink(pjob->filename);
- tdb_delete(tdb, print_key(jobid));
- return False;
- }
+ if (ret) goto fail;
+
+ /* The print job has been sucessfully handed over to the back-end */
+
+ pjob->spooled = True;
+ print_job_store(jobid, pjob);
+
+ /* make sure the database is up to date */
+ if (print_cache_expired(snum)) print_queue_update(snum);
+
+ return True;
+
+fail:
+ /* The print job was not succesfully started. Cleanup */
+ /* Still need to add proper error return propagation! 010122:JRR */
+ unlink(pjob->filename);
+ tdb_delete(tdb, print_key(jobid));
+ return False;
}
/* utility fn to enumerate the print queue */