3 Unix SMB/Netbios implementation.
5 printing backend routines
6 Copyright (C) Andrew Tridgell 1992-2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
27 the printing backend revolves around a tdb database that stores the
28 SMB view of the print queue
30 The key for this database is a jobid - a internally generated number that
31 uniquely identifies a print job
33 reading the print queue involves two steps:
34 - possibly running lpq and updating the internal database from that
35 - reading entries from the database
37 jobids are assigned when a job starts spooling.
41 pid_t pid; /* which process launched the job */
42 int sysjob; /* the system (lp) job number */
43 int fd; /* file descriptor of open file if open */
44 time_t starttime; /* when the job started spooling */
45 int status; /* the status of this job */
46 size_t size; /* the size of the job so far */
47 BOOL spooled; /* has it been sent to the spooler yet? */
48 BOOL smbjob; /* set if the job is a SMB job */
49 fstring filename; /* the filename used to spool the file */
50 fstring jobname; /* the job name given to us by the client */
51 fstring user; /* the user who started the job */
52 fstring qname; /* name of the print queue the job was sent to */
55 /* the open printing.tdb database */
56 static TDB_CONTEXT *tdb;
57 static pid_t local_pid;
59 #define PRINT_MAX_JOBID 10000
60 #define UNIX_JOB_START PRINT_MAX_JOBID
62 #define PRINT_SPOOL_PREFIX "smbprn."
63 #define PRINT_DATABASE_VERSION 1
65 /****************************************************************************
66 initialise the printing backend. Called once at startup.
67 Does not survive a fork
68 ****************************************************************************/
69 BOOL print_backend_init(void)
71 if (tdb && local_pid == sys_getpid()) return True;
72 tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
74 DEBUG(0,("Failed to open printing backend database\n"));
76 local_pid = sys_getpid();
78 /* handle a Samba upgrade */
80 if (tdb_fetch_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) {
81 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
82 tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION);
86 return nt_printing_init();
89 /****************************************************************************
90 useful function to generate a tdb key
91 ****************************************************************************/
92 static TDB_DATA print_key(int jobid)
98 ret.dptr = (void *)&j;
99 ret.dsize = sizeof(j);
103 /****************************************************************************
104 useful function to find a print job in the database
105 ****************************************************************************/
106 static struct printjob *print_job_find(int jobid)
108 static struct printjob pjob;
111 ret = tdb_fetch(tdb, print_key(jobid));
112 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
114 memcpy(&pjob, ret.dptr, sizeof(pjob));
119 /****************************************************************************
120 store a job structure back to the database
121 ****************************************************************************/
122 static BOOL print_job_store(int jobid, struct printjob *pjob)
125 d.dptr = (void *)pjob;
126 d.dsize = sizeof(*pjob);
127 return (0 == tdb_store(tdb, print_key(jobid), d, TDB_REPLACE));
130 /****************************************************************************
131 run a given print command
132 a null terminated list of value/substitute pairs is provided
133 for local substitution strings
134 ****************************************************************************/
135 static int print_run_command(int snum,char *command,
144 if (!command || !*command) return -1;
146 if (!VALID_SNUM(snum)) {
147 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
151 pstrcpy(syscmd, command);
153 va_start(ap, outfile);
154 while ((arg = va_arg(ap, char *))) {
155 char *value = va_arg(ap,char *);
156 pstring_sub(syscmd, arg, value);
160 p = PRINTERNAME(snum);
161 if (!p || !*p) p = SERVICE(snum);
163 pstring_sub(syscmd, "%p", p);
164 standard_sub_snum(snum,syscmd);
166 ret = smbrun(syscmd,outfile,False);
168 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
173 /****************************************************************************
174 parse a file name from the system spooler to generate a jobid
175 ****************************************************************************/
176 static int print_parse_jobid(char *fname)
180 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
181 fname += strlen(PRINT_SPOOL_PREFIX);
184 if (jobid <= 0) return -1;
190 /****************************************************************************
191 list a unix job in the print database
192 ****************************************************************************/
193 static void print_unix_job(int snum, print_queue_struct *q)
195 int jobid = q->job + UNIX_JOB_START;
203 pj.starttime = q->time;
204 pj.status = q->status;
208 fstrcpy(pj.filename, "");
209 fstrcpy(pj.jobname, q->file);
210 fstrcpy(pj.user, q->user);
211 fstrcpy(pj.qname, lp_servicename(snum));
213 print_job_store(jobid, &pj);
217 struct traverse_struct {
218 print_queue_struct *queue;
222 /* utility fn to delete any jobs that are no longer active */
223 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
225 struct traverse_struct *ts = (struct traverse_struct *)state;
226 struct printjob pjob;
229 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
230 memcpy(&jobid, key.dptr, sizeof(jobid));
231 memcpy(&pjob, data.dptr, sizeof(pjob));
233 if (strcmp(lp_servicename(ts->snum), pjob.qname)) {
234 /* this isn't for the queue we are looking at */
239 /* remove a unix job if it isn't in the system queue
241 for (i=0;i<ts->qcount;i++) {
242 if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
244 if (i == ts->qcount) tdb_delete(tdb, key);
248 /* maybe it hasn't been spooled yet */
250 /* if a job is not spooled and the process doesn't
251 exist then kill it. This cleans up after smbd
253 if (!process_exists(pjob.pid)) {
254 tdb_delete(tdb, key);
259 for (i=0;i<ts->qcount;i++) {
260 int qid = print_parse_jobid(ts->queue[i].file);
261 if (jobid == qid) break;
264 if (i == ts->qcount) {
265 /* the job isn't in the system queue - we have to
266 assume it has completed, so delete the database
274 /****************************************************************************
275 check if the print queue has been updated recently enough
276 ****************************************************************************/
277 static void print_cache_flush(int snum)
280 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
281 tdb_store_int(tdb, key, -1);
284 /****************************************************************************
285 update the internal database from the system print queue for a queue
286 ****************************************************************************/
287 static void print_queue_update(int snum)
289 char *path = lp_pathname(snum);
290 char *cmd = lp_lpqcommand(snum);
293 int numlines, i, qcount;
294 print_queue_struct *queue = NULL;
295 print_status_struct status;
296 struct printjob *pjob;
297 struct traverse_struct tstruct;
301 slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid);
304 print_run_command(snum, cmd, tmp_file,
308 qlines = file_lines_load(tmp_file, &numlines);
311 /* turn the lpq output into a series of job structures */
314 for (i=0; i<numlines; i++) {
315 queue = Realloc(queue,sizeof(print_queue_struct)*(qcount+1));
321 if (parse_lpq_entry(snum,qlines[i],
322 &queue[qcount],&status,qcount==0)) {
326 file_lines_free(qlines);
329 any job in the internal database that is marked as spooled
330 and doesn't exist in the system queue is considered finished
331 and removed from the database
333 any job in the system database but not in the internal database
334 is added as a unix job
336 fill in any system job numbers as we go
338 for (i=0; i<qcount; i++) {
339 int jobid = print_parse_jobid(queue[i].file);
342 /* assume its a unix print job */
343 print_unix_job(snum, &queue[i]);
347 /* we have an active SMB print job - update its status */
348 pjob = print_job_find(jobid);
350 /* err, somethings wrong. Probably smbd was restarted
351 with jobs in the queue. All we can do is treat them
352 like unix jobs. Pity. */
353 print_unix_job(snum, &queue[i]);
357 pjob->sysjob = queue[i].job;
358 pjob->status = queue[i].status;
360 print_job_store(jobid, pjob);
363 /* now delete any queued entries that don't appear in the
365 tstruct.queue = queue;
366 tstruct.qcount = qcount;
369 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
371 safe_free(tstruct.queue);
373 /* store the queue status structure */
374 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
375 data.dptr = (void *)&status;
376 data.dsize = sizeof(status);
378 key.dsize = strlen(keystr);
379 tdb_store(tdb, key, data, TDB_REPLACE);
381 /* update the cache time */
382 slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum));
383 tdb_store_int(tdb, keystr, (int)time(NULL));
386 /****************************************************************************
387 check if a jobid is valid. It is valid if it exists in the database
388 ****************************************************************************/
389 BOOL print_job_exists(int jobid)
391 return tdb_exists(tdb, print_key(jobid));
395 /****************************************************************************
396 work out which service a jobid is for
397 note that we have to look up by queue name to ensure that it works for
398 other than the process that started the job
399 ****************************************************************************/
400 int print_job_snum(int jobid)
402 struct printjob *pjob = print_job_find(jobid);
403 if (!pjob) return -1;
405 return lp_servicenumber(pjob->qname);
408 /****************************************************************************
409 give the fd used for a jobid
410 ****************************************************************************/
411 int print_job_fd(int jobid)
413 struct printjob *pjob = print_job_find(jobid);
414 if (!pjob) return -1;
415 /* don't allow another process to get this info - it is meaningless */
416 if (pjob->pid != local_pid) return -1;
420 /****************************************************************************
421 give the filename used for a jobid
422 only valid for the process doing the spooling and when the job
424 ****************************************************************************/
425 char *print_job_fname(int jobid)
427 struct printjob *pjob = print_job_find(jobid);
428 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
429 return pjob->filename;
433 /****************************************************************************
434 set the place in the queue for a job
435 ****************************************************************************/
436 BOOL print_job_set_place(int jobid, int place)
438 DEBUG(2,("print_job_set_place not implemented yet\n"));
442 /****************************************************************************
443 set the name of a job. Only possible for owner
444 ****************************************************************************/
445 BOOL print_job_set_name(int jobid, char *name)
447 struct printjob *pjob = print_job_find(jobid);
448 if (!pjob || pjob->pid != local_pid) return False;
450 fstrcpy(pjob->jobname, name);
451 return print_job_store(jobid, pjob);
455 /****************************************************************************
456 delete a print job - don't update queue
457 ****************************************************************************/
458 static BOOL print_job_delete1(int jobid)
460 struct printjob *pjob = print_job_find(jobid);
463 if (!pjob) return False;
465 snum = print_job_snum(jobid);
467 if (pjob->spooled && pjob->sysjob != -1) {
468 /* need to delete the spooled entry */
470 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
471 print_run_command(snum,
472 lp_lprmcommand(snum), NULL,
474 "%T", http_timestring(pjob->starttime),
481 /****************************************************************************
482 return true if the current user owns the print job
483 ****************************************************************************/
484 static BOOL is_owner(struct current_user *user, int jobid)
486 struct printjob *pjob = print_job_find(jobid);
489 if (!pjob || !user) return False;
491 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
492 return strequal(pjob->user, vuser->user.smb_name);
494 return strequal(pjob->user, uidtoname(user->uid));
498 /****************************************************************************
500 ****************************************************************************/
501 BOOL print_job_delete(struct current_user *user, int jobid)
503 int snum = print_job_snum(jobid);
506 if (!user) return False;
508 owner = is_owner(user, jobid);
510 /* Check access against security descriptor or whether the user
514 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
515 DEBUG(3, ("delete denied by security descriptor\n"));
519 if (!print_job_delete1(jobid)) return False;
521 /* force update the database and say the delete failed if the
524 print_queue_update(snum);
526 return !print_job_exists(jobid);
530 /****************************************************************************
532 ****************************************************************************/
533 BOOL print_job_pause(struct current_user *user, int jobid)
535 struct printjob *pjob = print_job_find(jobid);
541 if (!pjob || !user) return False;
543 if (!pjob->spooled || pjob->sysjob == -1) return False;
545 snum = print_job_snum(jobid);
546 owner = is_owner(user, jobid);
549 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
550 DEBUG(3, ("pause denied by security descriptor\n"));
554 /* need to pause the spooled entry */
555 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
556 ret = print_run_command(snum,
557 lp_lppausecommand(snum), NULL,
561 /* force update the database */
562 print_cache_flush(snum);
564 /* how do we tell if this succeeded? */
568 /****************************************************************************
570 ****************************************************************************/
571 BOOL print_job_resume(struct current_user *user, int jobid)
573 struct printjob *pjob = print_job_find(jobid);
578 if (!pjob || !user) return False;
580 if (!pjob->spooled || pjob->sysjob == -1) return False;
582 snum = print_job_snum(jobid);
583 owner = is_owner(user, jobid);
585 if (!is_owner(user, jobid) &&
586 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
587 DEBUG(3, ("resume denied by security descriptor\n"));
591 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
592 ret = print_run_command(snum,
593 lp_lpresumecommand(snum), NULL,
597 /* force update the database */
598 print_cache_flush(snum);
600 /* how do we tell if this succeeded? */
604 /****************************************************************************
605 write to a print file
606 ****************************************************************************/
607 int print_job_write(int jobid, const char *buf, int size)
611 fd = print_job_fd(jobid);
612 if (fd == -1) return -1;
614 return write(fd, buf, size);
618 /***************************************************************************
619 start spooling a job - return the jobid
620 ***************************************************************************/
621 int print_job_start(struct current_user *user, int snum, char *jobname)
625 struct printjob pjob;
631 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
632 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
636 if (!print_time_access_check(snum)) {
637 DEBUG(3, ("print_job_start: job start denied by time check\n"));
641 path = lp_pathname(snum);
643 /* see if we have sufficient disk space */
644 if (lp_minprintspace(snum)) {
645 SMB_BIG_UINT dspace, dsize;
646 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
647 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
653 /* for autoloaded printers, check that the printcap entry still exists */
654 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
659 /* create the database entry */
661 pjob.pid = local_pid;
664 pjob.starttime = time(NULL);
665 pjob.status = LPQ_QUEUED;
667 pjob.spooled = False;
670 fstrcpy(pjob.jobname, jobname);
672 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
673 fstrcpy(pjob.user, vuser->user.smb_name);
675 fstrcpy(pjob.user, uidtoname(user->uid));
678 fstrcpy(pjob.qname, lp_servicename(snum));
680 /* lock the database */
684 next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
685 if (next_jobid == -1) next_jobid = 1;
687 for (jobid = next_jobid+1; jobid != next_jobid; ) {
688 if (!print_job_exists(jobid)) break;
689 jobid = (jobid + 1) % PRINT_MAX_JOBID;
690 if (jobid == 0) jobid = 1;
692 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
697 tdb_store_int(tdb, "INFO/nextjob", jobid);
699 /* we have a job entry - now create the spool file
701 we unlink first to cope with old spool files and also to beat
702 a symlink security hole - it allows us to use O_EXCL
703 There may be old spool files owned by other users lying around.
705 slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d",
706 path, PRINT_SPOOL_PREFIX, jobid);
707 if (unlink(pjob.filename) == -1 && errno != ENOENT) {
710 pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
711 if (pjob.fd == -1) goto fail;
713 print_job_store(jobid, &pjob);
715 tdb_writeunlock(tdb);
718 * If the printer is marked as postscript output a leading
719 * file identifier to ensure the file is treated as a raw
721 * This has a similar effect as CtrlD=0 in WIN.INI file.
722 * tim@fsg.com 09/06/94
724 if (lp_postscript(snum)) {
725 print_job_write(jobid, "%!\n",3);
732 tdb_delete(tdb, print_key(jobid));
735 tdb_writeunlock(tdb);
739 /****************************************************************************
740 Print a file - called on closing the file. This spools the job.
741 ****************************************************************************/
743 BOOL print_job_end(int jobid)
745 struct printjob *pjob = print_job_find(jobid);
747 SMB_STRUCT_STAT sbuf;
748 pstring current_directory;
749 pstring print_directory;
756 if (pjob->spooled || pjob->pid != local_pid)
759 snum = print_job_snum(jobid);
761 if (sys_fstat(pjob->fd, &sbuf) == 0)
762 pjob->size = sbuf.st_size;
767 if (pjob->size == 0) {
768 /* don't bother spooling empty files */
769 unlink(pjob->filename);
770 tdb_delete(tdb, print_key(jobid));
774 /* we print from the directory path to give the best chance of
775 parsing the lpq output */
776 wd = sys_getwd(current_directory);
780 pstrcpy(print_directory, pjob->filename);
781 p = strrchr(print_directory,'/');
786 if (chdir(print_directory) != 0)
789 pstrcpy(jobname, pjob->jobname);
790 pstring_sub(jobname, "'", "_");
792 /* send it to the system spooler */
793 print_run_command(snum,
794 lp_printcommand(snum), NULL,
802 pjob->spooled = True;
803 print_job_store(jobid, pjob);
805 /* force update the database */
806 print_cache_flush(snum);
811 /****************************************************************************
812 Check if the print queue has been updated recently enough.
813 ****************************************************************************/
815 static BOOL print_cache_expired(int snum)
818 time_t t2, t = time(NULL);
819 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
820 t2 = tdb_fetch_int(tdb, key);
821 if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
827 /* utility fn to enumerate the print queue */
828 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
830 struct traverse_struct *ts = (struct traverse_struct *)state;
831 struct printjob pjob;
834 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
835 memcpy(&jobid, key.dptr, sizeof(jobid));
836 memcpy(&pjob, data.dptr, sizeof(pjob));
838 /* maybe it isn't for this queue */
839 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
841 ts->queue = Realloc(ts->queue,sizeof(print_queue_struct)*(ts->qcount+1));
842 if (!ts->queue) return -1;
845 ts->queue[i].job = jobid;
846 ts->queue[i].size = pjob.size;
847 ts->queue[i].status = pjob.status;
848 ts->queue[i].priority = 1;
849 ts->queue[i].time = pjob.starttime;
850 fstrcpy(ts->queue[i].user, pjob.user);
851 fstrcpy(ts->queue[i].file, pjob.jobname);
858 /****************************************************************************
859 get a printer queue listing
860 ****************************************************************************/
861 int print_queue_status(int snum,
862 print_queue_struct **queue,
863 print_status_struct *status)
865 struct traverse_struct tstruct;
869 /* make sure the database is up to date */
870 if (print_cache_expired(snum)) print_queue_update(snum);
872 /* fill in the queue */
873 tstruct.queue = NULL;
877 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
879 /* also fetch the queue status */
880 ZERO_STRUCTP(status);
881 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
883 key.dsize = strlen(keystr);
884 data = tdb_fetch(tdb, key);
886 if (data.dsize == sizeof(*status)) {
887 memcpy(status, data.dptr, sizeof(*status));
892 *queue = tstruct.queue;
893 return tstruct.qcount;
897 /****************************************************************************
898 turn a queue name into a snum
899 ****************************************************************************/
900 int print_queue_snum(char *qname)
902 int snum = lp_servicenumber(qname);
903 if (snum == -1 || !lp_print_ok(snum)) return -1;
908 /****************************************************************************
910 ****************************************************************************/
911 BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
915 if (!user) return False;
917 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
918 *errcode = ERROR_ACCESS_DENIED;
922 ret = print_run_command(snum, lp_queuepausecommand(snum), NULL,
925 /* force update the database */
926 print_cache_flush(snum);
931 /****************************************************************************
933 ****************************************************************************/
934 BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
938 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
939 *errcode = ERROR_ACCESS_DENIED;
943 ret = print_run_command(snum, lp_queueresumecommand(snum), NULL,
946 /* force update the database */
947 print_cache_flush(snum);
952 /****************************************************************************
953 purge a queue - implemented by deleting all jobs that we can delete
954 ****************************************************************************/
955 BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
957 print_queue_struct *queue;
958 print_status_struct status;
961 njobs = print_queue_status(snum, &queue, &status);
962 for (i=0;i<njobs;i++) {
963 if (print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
964 print_job_delete1(queue[i].job);
968 print_cache_flush(snum);