2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern int DEBUGLEVEL;
26 the printing backend revolves around a tdb database that stores the
27 SMB view of the print queue
29 The key for this database is a jobid - a internally generated number that
30 uniquely identifies a print job
32 reading the print queue involves two steps:
33 - possibly running lpq and updating the internal database from that
34 - reading entries from the database
36 jobids are assigned when a job starts spooling.
40 pid_t pid; /* which process launched the job */
41 int sysjob; /* the system (lp) job number */
42 int fd; /* file descriptor of open file if open */
43 time_t starttime; /* when the job started spooling */
44 int status; /* the status of this job */
45 size_t size; /* the size of the job so far */
46 BOOL spooled; /* has it been sent to the spooler yet? */
47 BOOL smbjob; /* set if the job is a SMB job */
48 fstring filename; /* the filename used to spool the file */
49 fstring jobname; /* the job name given to us by the client */
50 fstring user; /* the user who started the job */
51 fstring qname; /* name of the print queue the job was sent to */
54 /* the open printing.tdb database */
55 static TDB_CONTEXT *tdb;
56 static pid_t local_pid;
58 #define PRINT_MAX_JOBID 10000
59 #define UNIX_JOB_START PRINT_MAX_JOBID
61 #define PRINT_SPOOL_PREFIX "smbprn."
62 #define PRINT_DATABASE_VERSION 1
64 /****************************************************************************
65 initialise the printing backend. Called once at startup.
66 Does not survive a fork
67 ****************************************************************************/
68 BOOL print_backend_init(void)
70 if (tdb && local_pid == sys_getpid()) return True;
71 tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
73 DEBUG(0,("Failed to open printing backend database\n"));
75 local_pid = sys_getpid();
77 /* handle a Samba upgrade */
79 if (tdb_fetch_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) {
80 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
81 tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION);
85 return nt_printing_init();
88 /****************************************************************************
89 useful function to generate a tdb key
90 ****************************************************************************/
91 static TDB_DATA print_key(int jobid)
97 ret.dptr = (void *)&j;
98 ret.dsize = sizeof(j);
102 /****************************************************************************
103 useful function to find a print job in the database
104 ****************************************************************************/
105 static struct printjob *print_job_find(int jobid)
107 static struct printjob pjob;
110 ret = tdb_fetch(tdb, print_key(jobid));
111 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
113 memcpy(&pjob, ret.dptr, sizeof(pjob));
118 /****************************************************************************
119 store a job structure back to the database
120 ****************************************************************************/
121 static BOOL print_job_store(int jobid, struct printjob *pjob)
124 d.dptr = (void *)pjob;
125 d.dsize = sizeof(*pjob);
126 return (0 == tdb_store(tdb, print_key(jobid), d, TDB_REPLACE));
129 /****************************************************************************
130 run a given print command
131 a null terminated list of value/substitute pairs is provided
132 for local substitution strings
133 ****************************************************************************/
134 static int print_run_command(int snum,char *command,
143 if (!command || !*command) return -1;
145 if (!VALID_SNUM(snum)) {
146 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
150 pstrcpy(syscmd, command);
152 va_start(ap, outfile);
153 while ((arg = va_arg(ap, char *))) {
154 char *value = va_arg(ap,char *);
155 pstring_sub(syscmd, arg, value);
159 p = PRINTERNAME(snum);
160 if (!p || !*p) p = SERVICE(snum);
162 pstring_sub(syscmd, "%p", p);
163 standard_sub_snum(snum,syscmd);
165 ret = smbrun(syscmd,outfile,False);
167 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
172 /****************************************************************************
173 parse a file name from the system spooler to generate a jobid
174 ****************************************************************************/
175 static int print_parse_jobid(char *fname)
179 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
180 fname += strlen(PRINT_SPOOL_PREFIX);
183 if (jobid <= 0) return -1;
189 /****************************************************************************
190 list a unix job in the print database
191 ****************************************************************************/
192 static void print_unix_job(int snum, print_queue_struct *q)
194 int jobid = q->job + UNIX_JOB_START;
202 pj.starttime = q->time;
203 pj.status = q->status;
207 fstrcpy(pj.filename, "");
208 fstrcpy(pj.jobname, q->file);
209 fstrcpy(pj.user, q->user);
210 fstrcpy(pj.qname, lp_servicename(snum));
212 print_job_store(jobid, &pj);
216 struct traverse_struct {
217 print_queue_struct *queue;
221 /* utility fn to delete any jobs that are no longer active */
222 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
224 struct traverse_struct *ts = (struct traverse_struct *)state;
225 struct printjob pjob;
228 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
229 memcpy(&jobid, key.dptr, sizeof(jobid));
230 memcpy(&pjob, data.dptr, sizeof(pjob));
232 if (strcmp(lp_servicename(ts->snum), pjob.qname)) {
233 /* this isn't for the queue we are looking at */
238 /* remove a unix job if it isn't in the system queue
240 for (i=0;i<ts->qcount;i++) {
241 if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
243 if (i == ts->qcount) tdb_delete(tdb, key);
247 /* maybe it hasn't been spooled yet */
249 /* if a job is not spooled and the process doesn't
250 exist then kill it. This cleans up after smbd
252 if (!process_exists(pjob.pid)) {
253 tdb_delete(tdb, key);
258 for (i=0;i<ts->qcount;i++) {
259 int qid = print_parse_jobid(ts->queue[i].file);
260 if (jobid == qid) break;
263 if (i == ts->qcount) {
264 /* the job isn't in the system queue - we have to
265 assume it has completed, so delete the database
273 /****************************************************************************
274 check if the print queue has been updated recently enough
275 ****************************************************************************/
276 static void print_cache_flush(int snum)
279 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
280 tdb_store_int(tdb, key, -1);
283 /****************************************************************************
284 update the internal database from the system print queue for a queue
285 ****************************************************************************/
286 static void print_queue_update(int snum)
288 char *path = lp_pathname(snum);
289 char *cmd = lp_lpqcommand(snum);
292 int numlines, i, qcount;
293 print_queue_struct *queue = NULL;
294 print_status_struct status;
295 struct printjob *pjob;
296 struct traverse_struct tstruct;
300 slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid);
303 print_run_command(snum, cmd, tmp_file,
307 qlines = file_lines_load(tmp_file, &numlines);
310 /* turn the lpq output into a series of job structures */
313 for (i=0; i<numlines; i++) {
314 queue = Realloc(queue,sizeof(print_queue_struct)*(qcount+1));
320 if (parse_lpq_entry(snum,qlines[i],
321 &queue[qcount],&status,qcount==0)) {
325 file_lines_free(qlines);
328 any job in the internal database that is marked as spooled
329 and doesn't exist in the system queue is considered finished
330 and removed from the database
332 any job in the system database but not in the internal database
333 is added as a unix job
335 fill in any system job numbers as we go
337 for (i=0; i<qcount; i++) {
338 int jobid = print_parse_jobid(queue[i].file);
341 /* assume its a unix print job */
342 print_unix_job(snum, &queue[i]);
346 /* we have an active SMB print job - update its status */
347 pjob = print_job_find(jobid);
349 /* err, somethings wrong. Probably smbd was restarted
350 with jobs in the queue. All we can do is treat them
351 like unix jobs. Pity. */
352 print_unix_job(snum, &queue[i]);
356 pjob->sysjob = queue[i].job;
357 pjob->status = queue[i].status;
359 print_job_store(jobid, pjob);
362 /* now delete any queued entries that don't appear in the
364 tstruct.queue = queue;
365 tstruct.qcount = qcount;
368 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
370 safe_free(tstruct.queue);
372 /* store the queue status structure */
373 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
374 data.dptr = (void *)&status;
375 data.dsize = sizeof(status);
377 key.dsize = strlen(keystr);
378 tdb_store(tdb, key, data, TDB_REPLACE);
380 /* update the cache time */
381 slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum));
382 tdb_store_int(tdb, keystr, (int)time(NULL));
385 /****************************************************************************
386 check if a jobid is valid. It is valid if it exists in the database
387 ****************************************************************************/
388 BOOL print_job_exists(int jobid)
390 return tdb_exists(tdb, print_key(jobid));
394 /****************************************************************************
395 work out which service a jobid is for
396 note that we have to look up by queue name to ensure that it works for
397 other than the process that started the job
398 ****************************************************************************/
399 int print_job_snum(int jobid)
401 struct printjob *pjob = print_job_find(jobid);
402 if (!pjob) return -1;
404 return lp_servicenumber(pjob->qname);
407 /****************************************************************************
408 give the fd used for a jobid
409 ****************************************************************************/
410 int print_job_fd(int jobid)
412 struct printjob *pjob = print_job_find(jobid);
413 if (!pjob) return -1;
414 /* don't allow another process to get this info - it is meaningless */
415 if (pjob->pid != local_pid) return -1;
419 /****************************************************************************
420 give the filename used for a jobid
421 only valid for the process doing the spooling and when the job
423 ****************************************************************************/
424 char *print_job_fname(int jobid)
426 struct printjob *pjob = print_job_find(jobid);
427 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
428 return pjob->filename;
432 /****************************************************************************
433 set the place in the queue for a job
434 ****************************************************************************/
435 BOOL print_job_set_place(int jobid, int place)
437 DEBUG(2,("print_job_set_place not implemented yet\n"));
441 /****************************************************************************
442 set the name of a job. Only possible for owner
443 ****************************************************************************/
444 BOOL print_job_set_name(int jobid, char *name)
446 struct printjob *pjob = print_job_find(jobid);
447 if (!pjob || pjob->pid != local_pid) return False;
449 fstrcpy(pjob->jobname, name);
450 return print_job_store(jobid, pjob);
454 /****************************************************************************
455 delete a print job - don't update queue
456 ****************************************************************************/
457 static BOOL print_job_delete1(int jobid)
459 struct printjob *pjob = print_job_find(jobid);
462 if (!pjob) return False;
464 snum = print_job_snum(jobid);
466 if (pjob->spooled && pjob->sysjob != -1) {
467 /* need to delete the spooled entry */
469 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
470 print_run_command(snum,
471 lp_lprmcommand(snum), NULL,
473 "%T", http_timestring(pjob->starttime),
480 /****************************************************************************
481 return true if the uid owns the print job
482 ****************************************************************************/
483 static BOOL is_owner(uid_t uid, int jobid)
485 struct printjob *pjob = print_job_find(jobid);
488 if (!pjob || !(pw = sys_getpwuid(uid))) return False;
490 return (pw && pjob && strequal(pw->pw_name, pjob->user));
493 /****************************************************************************
495 ****************************************************************************/
496 BOOL print_job_delete(struct current_user *user, int jobid)
498 int snum = print_job_snum(jobid);
501 if (!user) return False;
503 owner = is_owner(user->uid, jobid);
505 /* Check access against security descriptor or whether the user
509 !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
510 DEBUG(3, ("delete denied by security descriptor\n"));
514 if (!print_job_delete1(jobid)) return False;
516 /* force update the database and say the delete failed if the
519 print_queue_update(snum);
521 return !print_job_exists(jobid);
525 /****************************************************************************
527 ****************************************************************************/
528 BOOL print_job_pause(struct current_user *user, int jobid)
530 struct printjob *pjob = print_job_find(jobid);
536 if (!pjob || !user) return False;
538 if (!pjob->spooled || pjob->sysjob == -1) return False;
540 snum = print_job_snum(jobid);
541 owner = is_owner(user->uid, jobid);
544 !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
545 DEBUG(3, ("pause denied by security descriptor\n"));
549 /* need to pause the spooled entry */
550 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
551 ret = print_run_command(snum,
552 lp_lppausecommand(snum), NULL,
556 /* force update the database */
557 print_cache_flush(snum);
559 /* how do we tell if this succeeded? */
563 /****************************************************************************
565 ****************************************************************************/
566 BOOL print_job_resume(struct current_user *user, int jobid)
568 struct printjob *pjob = print_job_find(jobid);
573 if (!pjob || !user) return False;
575 if (!pjob->spooled || pjob->sysjob == -1) return False;
577 snum = print_job_snum(jobid);
578 owner = is_owner(user->uid, jobid);
580 if (!is_owner(user->uid, jobid) &&
581 !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
582 DEBUG(3, ("resume denied by security descriptor\n"));
586 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
587 ret = print_run_command(snum,
588 lp_lpresumecommand(snum), NULL,
592 /* force update the database */
593 print_cache_flush(snum);
595 /* how do we tell if this succeeded? */
599 /****************************************************************************
600 write to a print file
601 ****************************************************************************/
602 int print_job_write(int jobid, const char *buf, int size)
606 fd = print_job_fd(jobid);
607 if (fd == -1) return -1;
609 return write(fd, buf, size);
613 /***************************************************************************
614 start spooling a job - return the jobid
615 ***************************************************************************/
616 int print_job_start(struct current_user *user, int snum, char *jobname)
620 struct printjob pjob;
622 extern struct current_user current_user;
624 if (!print_access_check(user, snum, PRINTER_ACE_PRINT)) {
625 DEBUG(3, ("job start denied by security descriptor\n"));
629 path = lp_pathname(snum);
631 /* see if we have sufficient disk space */
632 if (lp_minprintspace(snum)) {
633 SMB_BIG_UINT dspace, dsize;
634 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
635 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
641 /* for autoloaded printers, check that the printcap entry still exists */
642 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
647 /* create the database entry */
649 pjob.pid = local_pid;
652 pjob.starttime = time(NULL);
653 pjob.status = LPQ_QUEUED;
655 pjob.spooled = False;
658 fstrcpy(pjob.jobname, jobname);
659 fstrcpy(pjob.user, uidtoname(current_user.uid));
660 fstrcpy(pjob.qname, lp_servicename(snum));
662 /* lock the database */
665 next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
666 if (next_jobid == -1) next_jobid = 1;
668 for (jobid = next_jobid+1; jobid != next_jobid; ) {
669 if (!print_job_exists(jobid)) break;
670 jobid = (jobid + 1) % PRINT_MAX_JOBID;
671 if (jobid == 0) jobid = 1;
673 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
678 tdb_store_int(tdb, "INFO/nextjob", jobid);
680 /* we have a job entry - now create the spool file
682 we unlink first to cope with old spool files and also to beat
683 a symlink security hole - it allows us to use O_EXCL
685 slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d",
686 path, PRINT_SPOOL_PREFIX, jobid);
687 if (unlink(pjob.filename) == -1 && errno != ENOENT) {
690 pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
691 if (pjob.fd == -1) goto fail;
693 print_job_store(jobid, &pjob);
696 * If the printer is marked as postscript output a leading
697 * file identifier to ensure the file is treated as a raw
699 * This has a similar effect as CtrlD=0 in WIN.INI file.
700 * tim@fsg.com 09/06/94
702 if (lp_postscript(snum)) {
703 print_job_write(jobid, "%!\n",3);
706 tdb_writeunlock(tdb);
711 tdb_delete(tdb, print_key(jobid));
714 tdb_writeunlock(tdb);
718 /****************************************************************************
719 print a file - called on closing the file. This spools the job
720 ****************************************************************************/
721 BOOL print_job_end(int jobid)
723 struct printjob *pjob = print_job_find(jobid);
725 SMB_STRUCT_STAT sbuf;
726 pstring current_directory;
727 pstring print_directory;
731 if (!pjob) return False;
733 if (pjob->spooled || pjob->pid != local_pid) return False;
735 snum = print_job_snum(jobid);
737 if (sys_fstat(pjob->fd, &sbuf) == 0) pjob->size = sbuf.st_size;
742 if (pjob->size == 0) {
743 /* don't bother spooling empty files */
744 unlink(pjob->filename);
745 tdb_delete(tdb, print_key(jobid));
749 /* we print from the directory path to give the best chance of
750 parsing the lpq output */
751 wd = sys_getwd(current_directory);
752 if (!wd) return False;
754 pstrcpy(print_directory, pjob->filename);
755 p = strrchr(print_directory,'/');
756 if (!p) return False;
759 if (chdir(print_directory) != 0) return False;
761 pstrcpy(jobname, pjob->jobname);
762 pstring_sub(jobname, "'", "_");
764 /* send it to the system spooler */
765 print_run_command(snum,
766 lp_printcommand(snum), NULL,
774 pjob->spooled = True;
775 print_job_store(jobid, pjob);
777 /* force update the database */
778 print_cache_flush(snum);
784 /****************************************************************************
785 check if the print queue has been updated recently enough
786 ****************************************************************************/
787 static BOOL print_cache_expired(int snum)
790 time_t t2, t = time(NULL);
791 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
792 t2 = tdb_fetch_int(tdb, key);
793 if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
799 /* utility fn to enumerate the print queue */
800 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
802 struct traverse_struct *ts = (struct traverse_struct *)state;
803 struct printjob pjob;
806 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
807 memcpy(&jobid, key.dptr, sizeof(jobid));
808 memcpy(&pjob, data.dptr, sizeof(pjob));
810 /* maybe it isn't for this queue */
811 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
813 ts->queue = Realloc(ts->queue,sizeof(print_queue_struct)*(ts->qcount+1));
814 if (!ts->queue) return -1;
817 ts->queue[i].job = jobid;
818 ts->queue[i].size = pjob.size;
819 ts->queue[i].status = pjob.status;
820 ts->queue[i].priority = 1;
821 ts->queue[i].time = pjob.starttime;
822 fstrcpy(ts->queue[i].user, pjob.user);
823 fstrcpy(ts->queue[i].file, pjob.jobname);
830 /****************************************************************************
831 get a printer queue listing
832 ****************************************************************************/
833 int print_queue_status(int snum,
834 print_queue_struct **queue,
835 print_status_struct *status)
837 struct traverse_struct tstruct;
841 /* make sure the database is up to date */
842 if (print_cache_expired(snum)) print_queue_update(snum);
844 /* fill in the queue */
845 tstruct.queue = NULL;
849 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
851 /* also fetch the queue status */
852 ZERO_STRUCTP(status);
853 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
855 key.dsize = strlen(keystr);
856 data = tdb_fetch(tdb, key);
858 if (data.dsize == sizeof(*status)) {
859 memcpy(status, data.dptr, sizeof(*status));
864 *queue = tstruct.queue;
865 return tstruct.qcount;
869 /****************************************************************************
870 turn a queue name into a snum
871 ****************************************************************************/
872 int print_queue_snum(char *qname)
874 int snum = lp_servicenumber(qname);
875 if (snum == -1 || !lp_print_ok(snum)) return -1;
880 /****************************************************************************
882 ****************************************************************************/
883 BOOL print_queue_pause(struct current_user *user, int snum)
887 if (!user) return False;
889 if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
893 ret = print_run_command(snum, lp_queuepausecommand(snum), NULL,
896 /* force update the database */
897 print_cache_flush(snum);
902 /****************************************************************************
904 ****************************************************************************/
905 BOOL print_queue_resume(struct current_user *user, int snum)
909 if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
913 ret = print_run_command(snum, lp_queueresumecommand(snum), NULL,
916 /* force update the database */
917 print_cache_flush(snum);
922 /****************************************************************************
923 purge a queue - implemented by deleting all jobs that we can delete
924 ****************************************************************************/
925 BOOL print_queue_purge(struct current_user *user, int snum)
927 print_queue_struct *queue;
928 print_status_struct status;
931 if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
935 njobs = print_queue_status(snum, &queue, &status);
936 for (i=0;i<njobs;i++) {
937 print_job_delete1(queue[i].job);
940 print_cache_flush(snum);