]> git.ipfire.org Git - people/stevee/ipfire-3.x.git/blame - cups/patches/cups-x-lspp.patch
Move all packages to root.
[people/stevee/ipfire-3.x.git] / cups / patches / cups-x-lspp.patch
CommitLineData
f92713d3
SS
1diff -up cups-1.4.5/config.h.in.lspp cups-1.4.5/config.h.in
2--- cups-1.4.5/config.h.in.lspp 2010-12-24 13:21:31.134859403 +0000
3+++ cups-1.4.5/config.h.in 2010-12-24 13:21:31.173858387 +0000
4@@ -672,6 +672,12 @@
5 #undef HAVE_SYS_STATVFS_H
6 #undef HAVE_SYS_VFS_H
7
8+/*
9+ * Are we trying to meet LSPP requirements?
10+ */
11+
12+#undef WITH_LSPP
13+
14
15 #endif /* !_CUPS_CONFIG_H_ */
16
17diff -up cups-1.4.5/config-scripts/cups-lspp.m4.lspp cups-1.4.5/config-scripts/cups-lspp.m4
18--- cups-1.4.5/config-scripts/cups-lspp.m4.lspp 2010-12-24 13:21:31.174858361 +0000
19+++ cups-1.4.5/config-scripts/cups-lspp.m4 2010-12-24 13:21:31.174858361 +0000
20@@ -0,0 +1,36 @@
21+dnl
22+dnl LSPP code for the Common UNIX Printing System (CUPS).
23+dnl
24+dnl Copyright 2005-2006 by Hewlett-Packard Development Company, L.P.
25+dnl
26+dnl This program is free software; you can redistribute it and/or modify
27+dnl it under the terms of the GNU General Public License as published by
28+dnl the Free Software Foundation; version 2.
29+dnl
30+dnl This program is distributed in the hope that it will be useful, but
31+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
32+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33+dnl General Public License for more details.
34+dnl
35+dnl You should have received a copy of the GNU General Public License
36+dnl along with this program; if not, write to the Free Software Foundation,
37+dnl Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA
38+dnl
39+
40+dnl Are we trying to meet LSPP requirements
41+AC_ARG_ENABLE(lspp, [ --enable-lspp turn on auditing and label support, default=no])
42+
43+if test x"$enable_lspp" != xno; then
44+ case "$uname" in
45+ Linux)
46+ AC_CHECK_LIB(audit,audit_log_user_message, [LIBAUDIT="-laudit" AC_SUBST(LIBAUDIT)])
47+ AC_CHECK_HEADER(libaudit.h)
48+ AC_CHECK_LIB(selinux,getpeercon, [LIBSELINUX="-lselinux" AC_SUBST(LIBSELINUX)])
49+ AC_CHECK_HEADER(selinux/selinux.h)
50+ AC_DEFINE(WITH_LSPP)
51+ ;;
52+ *)
53+ # All others
54+ ;;
55+ esac
56+fi
57diff -up cups-1.4.5/configure.in.lspp cups-1.4.5/configure.in
58--- cups-1.4.5/configure.in.lspp 2010-06-22 22:42:44.000000000 +0100
59+++ cups-1.4.5/configure.in 2010-12-24 13:21:31.174858362 +0000
60@@ -42,6 +42,8 @@ sinclude(config-scripts/cups-pap.m4)
61 sinclude(config-scripts/cups-pdf.m4)
62 sinclude(config-scripts/cups-scripting.m4)
63
64+sinclude(config-scripts/cups-lspp.m4)
65+
66 INSTALL_LANGUAGES=""
67 UNINSTALL_LANGUAGES=""
68 LANGFILES=""
69diff -up cups-1.4.5/cups/cups.h.lspp cups-1.4.5/cups/cups.h
70--- cups-1.4.5/cups/cups.h.lspp 2010-06-22 04:18:27.000000000 +0100
71+++ cups-1.4.5/cups/cups.h 2010-12-24 13:21:31.176858307 +0000
72@@ -15,6 +15,9 @@
73 * This file is subject to the Apple OS-Developed Software exception.
74 */
75
76+/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
77+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
78+
79 #ifndef _CUPS_CUPS_H_
80 # define _CUPS_CUPS_H_
81
82@@ -86,6 +89,12 @@ extern "C" {
83 # define CUPS_WHICHJOBS_COMPLETED 1
84
85
86+# ifdef WITH_LSPP
87+# define MLS_CONFIG "mls"
88+# define TE_CONFIG "te"
89+# define SELINUX_CONFIG "SELinux"
90+# define UNKNOWN_SL "UNKNOWN SL"
91+# endif /* WITH_LSPP */
92 /*
93 * Types and structures...
94 */
95diff -up cups-1.4.5/data/Makefile.lspp cups-1.4.5/data/Makefile
96--- cups-1.4.5/data/Makefile.lspp 2008-11-12 19:30:57.000000000 +0000
97+++ cups-1.4.5/data/Makefile 2010-12-24 13:21:31.177858282 +0000
98@@ -25,7 +25,10 @@ BANNERS = \
99 secret \
100 standard \
101 topsecret \
102- unclassified
103+ unclassified \
104+ selinux \
105+ mls \
106+ te
107
108 CHARMAPS = \
109 euc-cn.txt \
110diff -up cups-1.4.5/data/mls.lspp cups-1.4.5/data/mls
111--- cups-1.4.5/data/mls.lspp 2010-12-24 13:21:31.177858282 +0000
112+++ cups-1.4.5/data/mls 2010-12-24 13:21:31.178858258 +0000
113@@ -0,0 +1,261 @@
114+%!PS-Adobe-3.0
115+%%BoundingBox: 0 0 612 792
116+%%Pages: 1
117+%%LanguageLevel: 1
118+%%DocumentData: Clean7Bit
119+%%DocumentSuppliedResources: procset bannerprint/1.0
120+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
121+%%Creator: Michael Sweet, Easy Software Products
122+%%CreationDate: May 10, 2000
123+%%Title: Test Page
124+%%EndComments
125+%%BeginProlog
126+%%BeginResource procset bannerprint 1.1 0
127+%
128+% PostScript banner page for the Common UNIX Printing System ("CUPS").
129+%
130+% Copyright 1993-2005 by Easy Software Products
131+%
132+% These coded instructions, statements, and computer programs are the
133+% property of Easy Software Products and are protected by Federal
134+% copyright law. Distribution and use rights are outlined in the file
135+% "LICENSE.txt" which should have been included with this file. If this
136+% file is missing or damaged please contact Easy Software Products
137+% at:
138+%
139+% Attn: CUPS Licensing Information
140+% Easy Software Products
141+% 44141 Airport View Drive, Suite 204
142+% Hollywood, Maryland 20636 USA
143+%
144+% Voice: (301) 373-9600
145+% EMail: cups-info@cups.org
146+% WWW: http://www.cups.org
147+%
148+/CENTER { % Draw centered text
149+ % (name) CENTER -
150+ dup stringwidth pop % Get the width of the string
151+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
152+ show % Show the string
153+} bind def
154+/RIGHT { % Draw right-justified text
155+ % (name) RIGHT -
156+ dup stringwidth pop % Get the width of the string
157+ neg 0 rmoveto % Shift left the entire distance
158+ show % Show the string
159+} bind def
160+/NUMBER { % Draw a number
161+ % power n NUMBER -
162+ 1 index 1 eq { % power == 1?
163+ round cvi exch pop % Convert "n" to integer
164+ } {
165+ 1 index mul round exch div % Truncate extra decimal places
166+ } ifelse
167+ 100 string cvs show % Convert to a string and show it...
168+} bind def
169+/CUPSLOGO { % Draw the CUPS logo
170+ % height CUPSLOGO
171+ % Start with a big C...
172+ /Helvetica findfont 1 index scalefont setfont
173+ 0 setgray
174+ 0 0 moveto
175+ (C) show
176+
177+ % Then "UNIX Printing System" much smaller...
178+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
179+ 0.25 mul
180+ dup dup 2.0 mul moveto
181+ (UNIX) show
182+ dup dup 1.6 mul moveto
183+ (Printing) show
184+ dup 1.2 mul moveto
185+ (System) show
186+} bind def
187+/ESPLOGO { % Draw the ESP logo
188+ % height ESPLOGO
189+ % Compute the size of the logo...
190+ 0 0
191+ 2 index 1.5 mul 3 index
192+
193+ % Do the "metallic" fill from 10% black to 40% black...
194+ 1 -0.001 0 {
195+ dup % loopval
196+ -0.15 mul % loopval * -0.15
197+ 0.9 add % 0.9 - loopval * 0.15
198+ setgray % set gray shade
199+
200+ 0 % x
201+ 1 index neg % loopval
202+ 1 add % 1 - loopval
203+ 3 index % height
204+ mul % height * (1 - loopval)
205+ moveto % starting point
206+
207+ dup % loopval
208+ 3 index % width
209+ mul % loopval * width
210+ 2 index % height
211+ lineto % Next point
212+
213+ 0 % x
214+ 2 index % height
215+ lineto % Next point
216+
217+ closepath
218+ fill
219+
220+ dup % loopval
221+ 0.15 mul % loopval * 0.15
222+ 0.6 add % 0.6 + loopval * 0.15
223+ setgray
224+
225+ dup % loopval
226+ neg 1 add % 1 - loopval
227+ 3 index % width
228+ mul % (1 - loopval) * width
229+ 0 % y
230+ moveto % Starting point
231+
232+ 2 index % width
233+ exch % loopval
234+ 2 index % height
235+ mul % loopval * height
236+ lineto % Next point
237+
238+ 1 index % width
239+ 0 % y
240+ lineto % Next point
241+
242+ closepath
243+ fill
244+ } for
245+
246+ 0 setgray rectstroke
247+
248+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
249+ dup 40 div
250+
251+ dup 4 mul 1 index 25 mul moveto (E) show
252+ dup 10 mul 1 index 15 mul moveto (S) show
253+ dup 16 mul 1 index 5 mul moveto (P) show
254+
255+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
256+ dup 14 mul 1 index 29 mul moveto (asy) show
257+ dup 20 mul 1 index 19 mul moveto (oftware) show
258+ dup 26 mul 1 index 9 mul moveto (roducts) show
259+
260+ pop
261+} bind def
262+%%EndResource
263+%%EndProlog
264+%%Page: 1 1
265+gsave
266+
267+ % Determine the imageable area and device resolution...
268+ initclip newpath clippath pathbbox % Get bounding rectangle
269+ 72 div /pageTop exch def % Get top margin in inches
270+ 72 div /pageRight exch def % Get right margin in inches
271+ 72 div /pageBottom exch def % Get bottom margin in inches
272+ 72 div /pageLeft exch def % Get left margin in inches
273+
274+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
275+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
276+
277+ /boxWidth % width of text box
278+ pageWidth pageHeight lt
279+ { pageWidth 54 mul }
280+ { pageHeight 42 mul }
281+ ifelse def
282+
283+ newpath % Clear bounding path
284+
285+ % Create fonts...
286+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
287+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
288+
289+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
290+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
291+
292+ % Offset page to account for lower-left margin...
293+ pageLeft 72 mul
294+ pageBottom 72 mul
295+ translate
296+
297+ % Job information box...
298+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
299+ boxWidth 0.5 mul sub % x-= 1/2 box width
300+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
301+ boxWidth % w = box width
302+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
303+ 0.5 setgray rectfill % Draw a shadow
304+
305+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
306+ boxWidth 0.5 mul sub % x-= 1/2 box width
307+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
308+ boxWidth % w = box width
309+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
310+
311+ 4 copy 1 setgray rectfill % Clear the box to white
312+ 0 setgray rectstroke % Draw a black box around it...
313+
314+ % Job information text...
315+ mediumFont setfont % Medium sized font
316+
317+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
318+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
319+ pageHeight 5 mul add % y += 2 lines
320+ 2 copy % Copy X & Y
321+ moveto
322+ (Job ID: ) RIGHT
323+ moveto
324+ ({printer-name}-{job-id}) show
325+
326+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
327+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
328+ pageHeight 2 mul add % y += 1 line
329+ 2 copy % Copy X & Y
330+ moveto
331+ (Title: ) RIGHT
332+ moveto
333+ ({job-name}) show
334+
335+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
336+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
337+ pageHeight -1 mul add % y -= 1 line
338+ 2 copy % Copy X & Y
339+ moveto
340+ (Requesting User: ) RIGHT
341+ moveto
342+ ({job-originating-user-name}) show
343+
344+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
345+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
346+ pageHeight -4 mul add % y -= 2 lines
347+ 2 copy % Copy X & Y
348+ moveto
349+ (Billing Info: ) RIGHT
350+ moveto
351+ ({?job-billing}) show
352+
353+ % Then the CUPS logo....
354+ gsave
355+ pageWidth 4 mul
356+ pageWidth 6 mul
357+ translate
358+ pageWidth 9 mul CUPSLOGO
359+ grestore
360+
361+ % And the ESP logo....
362+ gsave
363+ pageWidth 59 mul
364+ pageWidth 6 mul
365+ translate
366+ pageWidth 6 mul ESPLOGO
367+ grestore
368+% Show the page...
369+grestore
370+showpage
371+%
372+% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $".
373+%
374+%%EOF
375diff -up cups-1.4.5/data/selinux.lspp cups-1.4.5/data/selinux
376--- cups-1.4.5/data/selinux.lspp 2010-12-24 13:21:31.178858258 +0000
377+++ cups-1.4.5/data/selinux 2010-12-24 13:21:31.179858233 +0000
378@@ -0,0 +1,261 @@
379+%!PS-Adobe-3.0
380+%%BoundingBox: 0 0 612 792
381+%%Pages: 1
382+%%LanguageLevel: 1
383+%%DocumentData: Clean7Bit
384+%%DocumentSuppliedResources: procset bannerprint/1.0
385+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
386+%%Creator: Michael Sweet, Easy Software Products
387+%%CreationDate: May 10, 2000
388+%%Title: Test Page
389+%%EndComments
390+%%BeginProlog
391+%%BeginResource procset bannerprint 1.1 0
392+%
393+% PostScript banner page for the Common UNIX Printing System ("CUPS").
394+%
395+% Copyright 1993-2005 by Easy Software Products
396+%
397+% These coded instructions, statements, and computer programs are the
398+% property of Easy Software Products and are protected by Federal
399+% copyright law. Distribution and use rights are outlined in the file
400+% "LICENSE.txt" which should have been included with this file. If this
401+% file is missing or damaged please contact Easy Software Products
402+% at:
403+%
404+% Attn: CUPS Licensing Information
405+% Easy Software Products
406+% 44141 Airport View Drive, Suite 204
407+% Hollywood, Maryland 20636 USA
408+%
409+% Voice: (301) 373-9600
410+% EMail: cups-info@cups.org
411+% WWW: http://www.cups.org
412+%
413+/CENTER { % Draw centered text
414+ % (name) CENTER -
415+ dup stringwidth pop % Get the width of the string
416+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
417+ show % Show the string
418+} bind def
419+/RIGHT { % Draw right-justified text
420+ % (name) RIGHT -
421+ dup stringwidth pop % Get the width of the string
422+ neg 0 rmoveto % Shift left the entire distance
423+ show % Show the string
424+} bind def
425+/NUMBER { % Draw a number
426+ % power n NUMBER -
427+ 1 index 1 eq { % power == 1?
428+ round cvi exch pop % Convert "n" to integer
429+ } {
430+ 1 index mul round exch div % Truncate extra decimal places
431+ } ifelse
432+ 100 string cvs show % Convert to a string and show it...
433+} bind def
434+/CUPSLOGO { % Draw the CUPS logo
435+ % height CUPSLOGO
436+ % Start with a big C...
437+ /Helvetica findfont 1 index scalefont setfont
438+ 0 setgray
439+ 0 0 moveto
440+ (C) show
441+
442+ % Then "UNIX Printing System" much smaller...
443+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
444+ 0.25 mul
445+ dup dup 2.0 mul moveto
446+ (UNIX) show
447+ dup dup 1.6 mul moveto
448+ (Printing) show
449+ dup 1.2 mul moveto
450+ (System) show
451+} bind def
452+/ESPLOGO { % Draw the ESP logo
453+ % height ESPLOGO
454+ % Compute the size of the logo...
455+ 0 0
456+ 2 index 1.5 mul 3 index
457+
458+ % Do the "metallic" fill from 10% black to 40% black...
459+ 1 -0.001 0 {
460+ dup % loopval
461+ -0.15 mul % loopval * -0.15
462+ 0.9 add % 0.9 - loopval * 0.15
463+ setgray % set gray shade
464+
465+ 0 % x
466+ 1 index neg % loopval
467+ 1 add % 1 - loopval
468+ 3 index % height
469+ mul % height * (1 - loopval)
470+ moveto % starting point
471+
472+ dup % loopval
473+ 3 index % width
474+ mul % loopval * width
475+ 2 index % height
476+ lineto % Next point
477+
478+ 0 % x
479+ 2 index % height
480+ lineto % Next point
481+
482+ closepath
483+ fill
484+
485+ dup % loopval
486+ 0.15 mul % loopval * 0.15
487+ 0.6 add % 0.6 + loopval * 0.15
488+ setgray
489+
490+ dup % loopval
491+ neg 1 add % 1 - loopval
492+ 3 index % width
493+ mul % (1 - loopval) * width
494+ 0 % y
495+ moveto % Starting point
496+
497+ 2 index % width
498+ exch % loopval
499+ 2 index % height
500+ mul % loopval * height
501+ lineto % Next point
502+
503+ 1 index % width
504+ 0 % y
505+ lineto % Next point
506+
507+ closepath
508+ fill
509+ } for
510+
511+ 0 setgray rectstroke
512+
513+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
514+ dup 40 div
515+
516+ dup 4 mul 1 index 25 mul moveto (E) show
517+ dup 10 mul 1 index 15 mul moveto (S) show
518+ dup 16 mul 1 index 5 mul moveto (P) show
519+
520+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
521+ dup 14 mul 1 index 29 mul moveto (asy) show
522+ dup 20 mul 1 index 19 mul moveto (oftware) show
523+ dup 26 mul 1 index 9 mul moveto (roducts) show
524+
525+ pop
526+} bind def
527+%%EndResource
528+%%EndProlog
529+%%Page: 1 1
530+gsave
531+
532+ % Determine the imageable area and device resolution...
533+ initclip newpath clippath pathbbox % Get bounding rectangle
534+ 72 div /pageTop exch def % Get top margin in inches
535+ 72 div /pageRight exch def % Get right margin in inches
536+ 72 div /pageBottom exch def % Get bottom margin in inches
537+ 72 div /pageLeft exch def % Get left margin in inches
538+
539+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
540+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
541+
542+ /boxWidth % width of text box
543+ pageWidth pageHeight lt
544+ { pageWidth 54 mul }
545+ { pageHeight 42 mul }
546+ ifelse def
547+
548+ newpath % Clear bounding path
549+
550+ % Create fonts...
551+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
552+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
553+
554+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
555+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
556+
557+ % Offset page to account for lower-left margin...
558+ pageLeft 72 mul
559+ pageBottom 72 mul
560+ translate
561+
562+ % Job information box...
563+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
564+ boxWidth 0.5 mul sub % x-= 1/2 box width
565+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
566+ boxWidth % w = box width
567+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
568+ 0.5 setgray rectfill % Draw a shadow
569+
570+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
571+ boxWidth 0.5 mul sub % x-= 1/2 box width
572+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
573+ boxWidth % w = box width
574+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
575+
576+ 4 copy 1 setgray rectfill % Clear the box to white
577+ 0 setgray rectstroke % Draw a black box around it...
578+
579+ % Job information text...
580+ mediumFont setfont % Medium sized font
581+
582+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
583+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
584+ pageHeight 5 mul add % y += 2 lines
585+ 2 copy % Copy X & Y
586+ moveto
587+ (Job ID: ) RIGHT
588+ moveto
589+ ({printer-name}-{job-id}) show
590+
591+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
592+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
593+ pageHeight 2 mul add % y += 1 line
594+ 2 copy % Copy X & Y
595+ moveto
596+ (Title: ) RIGHT
597+ moveto
598+ ({job-name}) show
599+
600+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
601+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
602+ pageHeight -1 mul add % y -= 1 line
603+ 2 copy % Copy X & Y
604+ moveto
605+ (Requesting User: ) RIGHT
606+ moveto
607+ ({job-originating-user-name}) show
608+
609+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
610+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
611+ pageHeight -4 mul add % y -= 2 lines
612+ 2 copy % Copy X & Y
613+ moveto
614+ (Billing Info: ) RIGHT
615+ moveto
616+ ({?job-billing}) show
617+
618+ % Then the CUPS logo....
619+ gsave
620+ pageWidth 4 mul
621+ pageWidth 6 mul
622+ translate
623+ pageWidth 9 mul CUPSLOGO
624+ grestore
625+
626+ % And the ESP logo....
627+ gsave
628+ pageWidth 59 mul
629+ pageWidth 6 mul
630+ translate
631+ pageWidth 6 mul ESPLOGO
632+ grestore
633+% Show the page...
634+grestore
635+showpage
636+%
637+% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $".
638+%
639+%%EOF
640diff -up cups-1.4.5/data/te.lspp cups-1.4.5/data/te
641--- cups-1.4.5/data/te.lspp 2010-12-24 13:21:31.179858233 +0000
642+++ cups-1.4.5/data/te 2010-12-24 13:21:31.180858207 +0000
643@@ -0,0 +1,261 @@
644+%!PS-Adobe-3.0
645+%%BoundingBox: 0 0 612 792
646+%%Pages: 1
647+%%LanguageLevel: 1
648+%%DocumentData: Clean7Bit
649+%%DocumentSuppliedResources: procset bannerprint/1.0
650+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
651+%%Creator: Michael Sweet, Easy Software Products
652+%%CreationDate: May 10, 2000
653+%%Title: Test Page
654+%%EndComments
655+%%BeginProlog
656+%%BeginResource procset bannerprint 1.1 0
657+%
658+% PostScript banner page for the Common UNIX Printing System ("CUPS").
659+%
660+% Copyright 1993-2005 by Easy Software Products
661+%
662+% These coded instructions, statements, and computer programs are the
663+% property of Easy Software Products and are protected by Federal
664+% copyright law. Distribution and use rights are outlined in the file
665+% "LICENSE.txt" which should have been included with this file. If this
666+% file is missing or damaged please contact Easy Software Products
667+% at:
668+%
669+% Attn: CUPS Licensing Information
670+% Easy Software Products
671+% 44141 Airport View Drive, Suite 204
672+% Hollywood, Maryland 20636 USA
673+%
674+% Voice: (301) 373-9600
675+% EMail: cups-info@cups.org
676+% WWW: http://www.cups.org
677+%
678+/CENTER { % Draw centered text
679+ % (name) CENTER -
680+ dup stringwidth pop % Get the width of the string
681+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
682+ show % Show the string
683+} bind def
684+/RIGHT { % Draw right-justified text
685+ % (name) RIGHT -
686+ dup stringwidth pop % Get the width of the string
687+ neg 0 rmoveto % Shift left the entire distance
688+ show % Show the string
689+} bind def
690+/NUMBER { % Draw a number
691+ % power n NUMBER -
692+ 1 index 1 eq { % power == 1?
693+ round cvi exch pop % Convert "n" to integer
694+ } {
695+ 1 index mul round exch div % Truncate extra decimal places
696+ } ifelse
697+ 100 string cvs show % Convert to a string and show it...
698+} bind def
699+/CUPSLOGO { % Draw the CUPS logo
700+ % height CUPSLOGO
701+ % Start with a big C...
702+ /Helvetica findfont 1 index scalefont setfont
703+ 0 setgray
704+ 0 0 moveto
705+ (C) show
706+
707+ % Then "UNIX Printing System" much smaller...
708+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
709+ 0.25 mul
710+ dup dup 2.0 mul moveto
711+ (UNIX) show
712+ dup dup 1.6 mul moveto
713+ (Printing) show
714+ dup 1.2 mul moveto
715+ (System) show
716+} bind def
717+/ESPLOGO { % Draw the ESP logo
718+ % height ESPLOGO
719+ % Compute the size of the logo...
720+ 0 0
721+ 2 index 1.5 mul 3 index
722+
723+ % Do the "metallic" fill from 10% black to 40% black...
724+ 1 -0.001 0 {
725+ dup % loopval
726+ -0.15 mul % loopval * -0.15
727+ 0.9 add % 0.9 - loopval * 0.15
728+ setgray % set gray shade
729+
730+ 0 % x
731+ 1 index neg % loopval
732+ 1 add % 1 - loopval
733+ 3 index % height
734+ mul % height * (1 - loopval)
735+ moveto % starting point
736+
737+ dup % loopval
738+ 3 index % width
739+ mul % loopval * width
740+ 2 index % height
741+ lineto % Next point
742+
743+ 0 % x
744+ 2 index % height
745+ lineto % Next point
746+
747+ closepath
748+ fill
749+
750+ dup % loopval
751+ 0.15 mul % loopval * 0.15
752+ 0.6 add % 0.6 + loopval * 0.15
753+ setgray
754+
755+ dup % loopval
756+ neg 1 add % 1 - loopval
757+ 3 index % width
758+ mul % (1 - loopval) * width
759+ 0 % y
760+ moveto % Starting point
761+
762+ 2 index % width
763+ exch % loopval
764+ 2 index % height
765+ mul % loopval * height
766+ lineto % Next point
767+
768+ 1 index % width
769+ 0 % y
770+ lineto % Next point
771+
772+ closepath
773+ fill
774+ } for
775+
776+ 0 setgray rectstroke
777+
778+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
779+ dup 40 div
780+
781+ dup 4 mul 1 index 25 mul moveto (E) show
782+ dup 10 mul 1 index 15 mul moveto (S) show
783+ dup 16 mul 1 index 5 mul moveto (P) show
784+
785+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
786+ dup 14 mul 1 index 29 mul moveto (asy) show
787+ dup 20 mul 1 index 19 mul moveto (oftware) show
788+ dup 26 mul 1 index 9 mul moveto (roducts) show
789+
790+ pop
791+} bind def
792+%%EndResource
793+%%EndProlog
794+%%Page: 1 1
795+gsave
796+
797+ % Determine the imageable area and device resolution...
798+ initclip newpath clippath pathbbox % Get bounding rectangle
799+ 72 div /pageTop exch def % Get top margin in inches
800+ 72 div /pageRight exch def % Get right margin in inches
801+ 72 div /pageBottom exch def % Get bottom margin in inches
802+ 72 div /pageLeft exch def % Get left margin in inches
803+
804+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
805+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
806+
807+ /boxWidth % width of text box
808+ pageWidth pageHeight lt
809+ { pageWidth 54 mul }
810+ { pageHeight 42 mul }
811+ ifelse def
812+
813+ newpath % Clear bounding path
814+
815+ % Create fonts...
816+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
817+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
818+
819+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
820+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
821+
822+ % Offset page to account for lower-left margin...
823+ pageLeft 72 mul
824+ pageBottom 72 mul
825+ translate
826+
827+ % Job information box...
828+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
829+ boxWidth 0.5 mul sub % x-= 1/2 box width
830+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
831+ boxWidth % w = box width
832+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
833+ 0.5 setgray rectfill % Draw a shadow
834+
835+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
836+ boxWidth 0.5 mul sub % x-= 1/2 box width
837+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
838+ boxWidth % w = box width
839+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
840+
841+ 4 copy 1 setgray rectfill % Clear the box to white
842+ 0 setgray rectstroke % Draw a black box around it...
843+
844+ % Job information text...
845+ mediumFont setfont % Medium sized font
846+
847+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
848+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
849+ pageHeight 5 mul add % y += 2 lines
850+ 2 copy % Copy X & Y
851+ moveto
852+ (Job ID: ) RIGHT
853+ moveto
854+ ({printer-name}-{job-id}) show
855+
856+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
857+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
858+ pageHeight 2 mul add % y += 1 line
859+ 2 copy % Copy X & Y
860+ moveto
861+ (Title: ) RIGHT
862+ moveto
863+ ({job-name}) show
864+
865+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
866+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
867+ pageHeight -1 mul add % y -= 1 line
868+ 2 copy % Copy X & Y
869+ moveto
870+ (Requesting User: ) RIGHT
871+ moveto
872+ ({job-originating-user-name}) show
873+
874+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
875+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
876+ pageHeight -4 mul add % y -= 2 lines
877+ 2 copy % Copy X & Y
878+ moveto
879+ (Billing Info: ) RIGHT
880+ moveto
881+ ({?job-billing}) show
882+
883+ % Then the CUPS logo....
884+ gsave
885+ pageWidth 4 mul
886+ pageWidth 6 mul
887+ translate
888+ pageWidth 9 mul CUPSLOGO
889+ grestore
890+
891+ % And the ESP logo....
892+ gsave
893+ pageWidth 59 mul
894+ pageWidth 6 mul
895+ translate
896+ pageWidth 6 mul ESPLOGO
897+ grestore
898+% Show the page...
899+grestore
900+showpage
901+%
902+% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $".
903+%
904+%%EOF
905diff -up cups-1.4.5/filter/common.c.lspp cups-1.4.5/filter/common.c
906--- cups-1.4.5/filter/common.c.lspp 2007-07-11 22:46:42.000000000 +0100
907+++ cups-1.4.5/filter/common.c 2010-12-24 13:21:31.181858180 +0000
908@@ -30,6 +30,12 @@
909 * Include necessary headers...
910 */
911
912+#include "config.h"
913+#ifdef WITH_LSPP
914+#define _GNU_SOURCE
915+#include <string.h>
916+#endif /* WITH_LSPP */
917+
918 #include "common.h"
919 #include <locale.h>
920
921@@ -312,6 +318,18 @@ WriteLabelProlog(const char *label, /* I
922 {
923 const char *classification; /* CLASSIFICATION environment variable */
924 const char *ptr; /* Temporary string pointer */
925+#ifdef WITH_LSPP
926+ int i, /* counter */
927+ n, /* counter */
928+ lines, /* number of lines needed */
929+ line_len, /* index into tmp_label */
930+ label_len, /* length of the label in characters */
931+ label_index, /* index into the label */
932+ longest, /* length of the longest line */
933+ longest_line, /* index to the longest line */
934+ max_width; /* maximum width in characters */
935+ char **wrapped_label; /* label with line breaks */
936+#endif /* WITH_LSPP */
937
938
939 /*
940@@ -334,6 +352,124 @@ WriteLabelProlog(const char *label, /* I
941 return;
942 }
943
944+#ifdef WITH_LSPP
945+ if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
946+ {
947+ /*
948+ * Based on the 12pt fixed width font below determine the max_width
949+ */
950+ max_width = width / 8;
951+ longest_line = 0;
952+ longest = 0;
953+ classification += 5; // Skip the "LSPP:"
954+ label_len = strlen(classification);
955+
956+ if (label_len > max_width)
957+ {
958+ lines = 1 + (int)(label_len / max_width);
959+ line_len = (int)(label_len / lines);
960+ wrapped_label = malloc(sizeof(wrapped_label) * lines);
961+ label_index = i = n = 0;
962+ while (classification[label_index])
963+ {
964+ if ((label_index + line_len) > label_len)
965+ break;
966+ switch (classification[label_index + line_len + i])
967+ {
968+ case ':':
969+ case ',':
970+ case '-':
971+ i++;
972+ wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
973+ label_index += line_len + i;
974+ i = 0;
975+ break;
976+ default:
977+ i++;
978+ break;
979+ }
980+ if ((i + line_len) == max_width)
981+ {
982+ wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
983+ label_index = label_index + line_len + i;
984+ i = 0;
985+ }
986+ }
987+ wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
988+ }
989+ else
990+ {
991+ lines = 1;
992+ wrapped_label = malloc(sizeof(wrapped_label));
993+ wrapped_label[0] = (char*)classification;
994+ }
995+
996+ for (n = 0; n < lines; n++ )
997+ {
998+ printf("userdict/ESPp%c(", ('a' + n));
999+ for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
1000+ if (*ptr < 32 || *ptr > 126)
1001+ printf("\\%03o", *ptr);
1002+ else
1003+ {
1004+ if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
1005+ putchar('\\');
1006+
1007+ printf("%c", *ptr);
1008+ }
1009+ if (i > longest)
1010+ {
1011+ longest = i;
1012+ longest_line = n;
1013+ }
1014+ printf(")put\n");
1015+ }
1016+
1017+ /*
1018+ * For LSPP use a fixed width font so that line wrapping can be calculated
1019+ */
1020+
1021+ puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
1022+
1023+ /*
1024+ * Finally, the procedure to write the labels on the page...
1025+ */
1026+
1027+ printf("userdict/ESPwl{\n"
1028+ " ESPlf setfont\n");
1029+ printf(" ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
1030+ 'a' + longest_line, width * 0.5f);
1031+ for (n = 1; n < lines; n++)
1032+ printf(" dup");
1033+ printf("\n 1 setgray\n");
1034+ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
1035+ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
1036+ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
1037+ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
1038+ printf(" 0 setgray\n");
1039+ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
1040+ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
1041+ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
1042+ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
1043+ for (n = 0; n < lines; n ++)
1044+ {
1045+ printf(" dup %.0f moveto ESPp%c show\n",
1046+ bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
1047+ printf(" %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
1048+ }
1049+ printf(" pop\n"
1050+ "}bind put\n");
1051+
1052+ /*
1053+ * Do some clean up at the end of the LSPP special case
1054+ */
1055+ free(wrapped_label);
1056+
1057+ }
1058+ else
1059+ {
1060+#endif /* !WITH_LSPP */
1061+
1062 /*
1063 * Set the classification + page label string...
1064 */
1065@@ -414,7 +550,10 @@ WriteLabelProlog(const char *label, /* I
1066 printf(" %.0f moveto ESPpl show\n", top - 14.0);
1067 puts("pop");
1068 puts("}bind put");
1069+ }
1070+#ifdef WITH_LSPP
1071 }
1072+#endif /* WITH_LSPP */
1073
1074
1075 /*
1076diff -up cups-1.4.5/filter/pstops.c.lspp cups-1.4.5/filter/pstops.c
1077--- cups-1.4.5/filter/pstops.c.lspp 2010-12-24 13:21:30.960863932 +0000
1078+++ cups-1.4.5/filter/pstops.c 2010-12-24 13:21:31.186858049 +0000
1079@@ -3335,6 +3335,18 @@ write_label_prolog(pstops_doc_t *doc, /*
1080 {
1081 const char *classification; /* CLASSIFICATION environment variable */
1082 const char *ptr; /* Temporary string pointer */
1083+#ifdef WITH_LSPP
1084+ int i, /* counter */
1085+ n, /* counter */
1086+ lines, /* number of lines needed */
1087+ line_len, /* index into tmp_label */
1088+ label_len, /* length of the label in characters */
1089+ label_index, /* index into the label */
1090+ longest, /* length of the longest line */
1091+ longest_line, /* index to the longest line */
1092+ max_width; /* maximum width in characters */
1093+ char **wrapped_label; /* label with line breaks */
1094+#endif /* WITH_LSPP */
1095
1096
1097 /*
1098@@ -3357,6 +3369,124 @@ write_label_prolog(pstops_doc_t *doc, /*
1099 return;
1100 }
1101
1102+#ifdef WITH_LSPP
1103+ if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
1104+ {
1105+ /*
1106+ * Based on the 12pt fixed width font below determine the max_width
1107+ */
1108+ max_width = width / 8;
1109+ longest_line = 0;
1110+ longest = 0;
1111+ classification += 5; // Skip the "LSPP:"
1112+ label_len = strlen(classification);
1113+
1114+ if (label_len > max_width)
1115+ {
1116+ lines = 1 + (int)(label_len / max_width);
1117+ line_len = (int)(label_len / lines);
1118+ wrapped_label = malloc(sizeof(wrapped_label) * lines);
1119+ label_index = i = n = 0;
1120+ while (classification[label_index])
1121+ {
1122+ if ((label_index + line_len) > label_len)
1123+ break;
1124+ switch (classification[label_index + line_len + i])
1125+ {
1126+ case ':':
1127+ case ',':
1128+ case '-':
1129+ i++;
1130+ wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
1131+ label_index += line_len + i;
1132+ i = 0;
1133+ break;
1134+ default:
1135+ i++;
1136+ break;
1137+ }
1138+ if ((i + line_len) == max_width)
1139+ {
1140+ wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
1141+ label_index = label_index + line_len + i;
1142+ i = 0;
1143+ }
1144+ }
1145+ wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
1146+ }
1147+ else
1148+ {
1149+ lines = 1;
1150+ wrapped_label = malloc(sizeof(wrapped_label));
1151+ wrapped_label[0] = (char*)classification;
1152+ }
1153+
1154+ for (n = 0; n < lines; n++ )
1155+ {
1156+ printf("userdict/ESPp%c(", ('a' + n));
1157+ for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
1158+ if (*ptr < 32 || *ptr > 126)
1159+ printf("\\%03o", *ptr);
1160+ else
1161+ {
1162+ if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
1163+ putchar('\\');
1164+
1165+ printf("%c", *ptr);
1166+ }
1167+ if (i > longest)
1168+ {
1169+ longest = i;
1170+ longest_line = n;
1171+ }
1172+ printf(")put\n");
1173+ }
1174+
1175+ /*
1176+ * For LSPP use a fixed width font so that line wrapping can be calculated
1177+ */
1178+
1179+ puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
1180+
1181+ /*
1182+ * Finally, the procedure to write the labels on the page...
1183+ */
1184+
1185+ printf("userdict/ESPwl{\n"
1186+ " ESPlf setfont\n");
1187+ printf(" ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
1188+ 'a' + longest_line, width * 0.5f);
1189+ for (n = 1; n < lines; n++)
1190+ printf(" dup");
1191+ printf("\n 1 setgray\n");
1192+ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
1193+ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
1194+ printf(" dup 6 sub %.0f %d index %.0f ESPrf\n",
1195+ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
1196+ printf(" 0 setgray\n");
1197+ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
1198+ (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
1199+ printf(" dup 6 sub %.0f %d index %.0f ESPrs\n",
1200+ (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
1201+ for (n = 0; n < lines; n ++)
1202+ {
1203+ printf(" dup %.0f moveto ESPp%c show\n",
1204+ bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
1205+ printf(" %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
1206+ }
1207+ printf(" pop\n"
1208+ "}bind put\n");
1209+
1210+ /*
1211+ * Do some clean up at the end of the LSPP special case
1212+ */
1213+ free(wrapped_label);
1214+
1215+ }
1216+ else
1217+ {
1218+#endif /* !WITH_LSPP */
1219+
1220 /*
1221 * Set the classification + page label string...
1222 */
1223@@ -3435,7 +3565,10 @@ write_label_prolog(pstops_doc_t *doc, /*
1224 doc_printf(doc, " %.0f moveto ESPpl show\n", top - 14.0);
1225 doc_puts(doc, "pop\n");
1226 doc_puts(doc, "}bind put\n");
1227+ }
1228+#ifdef WITH_LSPP
1229 }
1230+#endif /* WITH_LSPP */
1231
1232
1233 /*
1234diff -up cups-1.4.5/Makedefs.in.lspp cups-1.4.5/Makedefs.in
1235--- cups-1.4.5/Makedefs.in.lspp 2010-12-24 13:21:31.073860989 +0000
1236+++ cups-1.4.5/Makedefs.in 2010-12-24 13:21:31.187858023 +0000
1237@@ -146,7 +146,7 @@ LIBCUPSORDER = @LIBCUPSORDER@
1238 LIBCUPSIMAGEORDER = @LIBCUPSIMAGEORDER@
1239 LINKCUPS = @LINKCUPS@ $(SSLLIBS) $(DNSSDLIBS)
1240 LINKCUPSIMAGE = @LINKCUPSIMAGE@
1241-LIBS = $(LINKCUPS) $(COMMONLIBS)
1242+LIBS = $(LINKCUPS) $(COMMONLIBS) @LIBAUDIT@ @LIBSELINUX@
1243 OPTIM = @OPTIM@
1244 OPTIONS =
1245 PAMLIBS = @PAMLIBS@
1246@@ -258,7 +258,7 @@ DBUSDIR = @DBUSDIR@
1247 # Rules...
1248 #
1249
1250-.SILENT:
1251+
1252 .SUFFIXES: .1 .1.gz .1m .1m.gz .3 .3.gz .5 .5.gz .7 .7.gz .8 .8.gz .a .c .cxx .h .man .o .32.o .64.o .gz
1253
1254 .c.o:
1255diff -up cups-1.4.5/scheduler/client.c.lspp cups-1.4.5/scheduler/client.c
1256--- cups-1.4.5/scheduler/client.c.lspp 2010-10-17 05:13:56.000000000 +0100
1257+++ cups-1.4.5/scheduler/client.c 2010-12-24 13:21:31.194857839 +0000
1258@@ -44,6 +44,7 @@
1259 * valid_host() - Is the Host: field valid?
1260 * write_file() - Send a file via HTTP.
1261 * write_pipe() - Flag that data is available on the CGI pipe.
1262+ * client_pid_to_auid() - Get the audit login uid of the client.
1263 */
1264
1265 /*
1266@@ -52,6 +53,7 @@
1267
1268 #include "cupsd.h"
1269
1270+#define _GNU_SOURCE
1271 #ifdef HAVE_CDSASSL
1272 # include <Security/Security.h>
1273 # include <Security/SecItem.h>
1274@@ -90,6 +92,12 @@ extern const char *cssmErrorString(int e
1275 # include <tcpd.h>
1276 #endif /* HAVE_TCPD_H */
1277
1278+#ifdef WITH_LSPP
1279+#include <selinux/selinux.h>
1280+#include <selinux/context.h>
1281+#include <fcntl.h>
1282+#endif /* WITH_LSPP */
1283+
1284
1285 /*
1286 * Local functions...
1287@@ -391,6 +399,57 @@ cupsdAcceptClient(cupsd_listener_t *lis)
1288 }
1289 #endif /* HAVE_TCPD_H */
1290
1291+#ifdef WITH_LSPP
1292+ if (is_lspp_config())
1293+ {
1294+ struct ucred cr;
1295+ unsigned int cl=sizeof(cr);
1296+
1297+ if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0)
1298+ {
1299+ /*
1300+ * client_pid_to_auid() can be racey
1301+ * In this case the pid is based on a socket connected to the client
1302+ */
1303+ if ((con->auid = client_pid_to_auid(cr.pid)) == -1)
1304+ {
1305+ close(con->http.fd);
1306+ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: "
1307+ "unable to determine client auid for client pid=%d", cr.pid);
1308+ free(con);
1309+ return;
1310+ }
1311+ cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: peer's pid=%d, uid=%d, gid=%d, auid=%d",
1312+ cr.pid, cr.uid, cr.gid, con->auid);
1313+ }
1314+ else
1315+ {
1316+ close(con->http.fd);
1317+ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getsockopt() failed");
1318+ free(con);
1319+ return;
1320+ }
1321+
1322+ /*
1323+ * get the context of the peer connection
1324+ */
1325+ if (getpeercon(con->http.fd, &con->scon))
1326+ {
1327+ close(con->http.fd);
1328+ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getpeercon() failed");
1329+ free(con);
1330+ return;
1331+ }
1332+
1333+ cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: client context=%s", con->scon);
1334+ }
1335+ else
1336+ {
1337+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: skipping getpeercon()");
1338+ cupsdSetString(&con->scon, UNKNOWN_SL);
1339+ }
1340+#endif /* WITH_LSPP */
1341+
1342 #ifdef AF_INET6
1343 if (con->http.hostaddr->addr.sa_family == AF_INET6)
1344 cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv6)",
1345@@ -781,6 +840,13 @@ cupsdReadClient(cupsd_client_t *con) /*
1346 mime_type_t *type; /* MIME type of file */
1347 cupsd_printer_t *p; /* Printer */
1348 static unsigned request_id = 0; /* Request ID for temp files */
1349+#ifdef WITH_LSPP
1350+ security_context_t spoolcon; /* context of the job file */
1351+ context_t clicon; /* contex_t container for con->scon */
1352+ context_t tmpcon; /* temp context to swap the level */
1353+ char *clirange; /* SELinux sensitivity range */
1354+ char *cliclearance; /* SELinux low end clearance */
1355+#endif /* WITH_LSPP */
1356
1357
1358 status = HTTP_CONTINUE;
1359@@ -2135,6 +2201,67 @@ cupsdReadClient(cupsd_client_t *con) /*
1360 fchmod(con->file, 0640);
1361 fchown(con->file, RunUser, Group);
1362 fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
1363+#ifdef WITH_LSPP
1364+ if (strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
1365+ {
1366+ if (getfilecon(con->filename, &spoolcon) == -1)
1367+ {
1368+ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
1369+ return (cupsdCloseClient(con));
1370+ }
1371+ clicon = context_new(con->scon);
1372+ tmpcon = context_new(spoolcon);
1373+ freecon(spoolcon);
1374+ if (!clicon || !tmpcon)
1375+ {
1376+ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
1377+ if (clicon)
1378+ context_free(clicon);
1379+ if (tmpcon)
1380+ context_free(tmpcon);
1381+ return (cupsdCloseClient(con));
1382+ }
1383+ clirange = context_range_get(clicon);
1384+ if (clirange)
1385+ {
1386+ clirange = strdup(clirange);
1387+ if ((cliclearance = strtok(clirange, "-")) != NULL)
1388+ {
1389+ if (context_range_set(tmpcon, cliclearance) == -1)
1390+ {
1391+ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
1392+ free(clirange);
1393+ context_free(tmpcon);
1394+ context_free(clicon);
1395+ return (cupsdCloseClient(con));
1396+ }
1397+ }
1398+ else
1399+ {
1400+ if (context_range_set(tmpcon, (context_range_get(clicon))) == -1)
1401+ {
1402+ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
1403+ free(clirange);
1404+ context_free(tmpcon);
1405+ context_free(clicon);
1406+ return (cupsdCloseClient(con));
1407+ }
1408+ }
1409+ free(clirange);
1410+ }
1411+ if (setfilecon(con->filename, context_str(tmpcon)) == -1)
1412+ {
1413+ cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
1414+ context_free(tmpcon);
1415+ context_free(clicon);
1416+ return (cupsdCloseClient(con));
1417+ }
1418+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: %s set to %s",
1419+ con->filename, context_str(tmpcon));
1420+ context_free(tmpcon);
1421+ context_free(clicon);
1422+ }
1423+#endif /* WITH_LSPP */
1424 }
1425
1426 if (con->http.state != HTTP_POST_SEND)
1427@@ -4641,6 +4768,50 @@ make_certificate(cupsd_client_t *con) /*
1428 #endif /* HAVE_SSL */
1429
1430
1431+#ifdef WITH_LSPP
1432+/*
1433+ * 'client_pid_to_auid()' - Using the client's pid, read /proc and determine the loginuid.
1434+ */
1435+
1436+uid_t client_pid_to_auid(pid_t clipid)
1437+{
1438+ uid_t uid;
1439+ int len, in;
1440+ char buf[16] = {0};
1441+ char fname[32] = {0};
1442+
1443+
1444+ /*
1445+ * Hopefully this pid is still the one we are interested in.
1446+ */
1447+ snprintf(fname, 32, "/proc/%d/loginuid", clipid);
1448+ in = open(fname, O_NOFOLLOW|O_RDONLY);
1449+
1450+ if (in < 0)
1451+ return -1;
1452+
1453+ errno = 0;
1454+
1455+ do {
1456+ len = read(in, buf, sizeof(buf));
1457+ } while (len < 0 && errno == EINTR);
1458+
1459+ close(in);
1460+
1461+ if (len < 0 || len >= sizeof(buf))
1462+ return -1;
1463+
1464+ errno = 0;
1465+ buf[len] = 0;
1466+ uid = strtol(buf, 0, 10);
1467+
1468+ if (errno != 0)
1469+ return -1;
1470+ else
1471+ return uid;
1472+}
1473+#endif /* WITH_LSPP */
1474+
1475 /*
1476 * 'pipe_command()' - Pipe the output of a command to the remote client.
1477 */
1478diff -up cups-1.4.5/scheduler/client.h.lspp cups-1.4.5/scheduler/client.h
1479--- cups-1.4.5/scheduler/client.h.lspp 2009-05-26 23:01:23.000000000 +0100
1480+++ cups-1.4.5/scheduler/client.h 2010-12-24 13:21:31.195857813 +0000
1481@@ -18,6 +18,13 @@
1482 #endif /* HAVE_AUTHORIZATION_H */
1483
1484
1485+/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
1486+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
1487+
1488+#ifdef WITH_LSPP
1489+#include <selinux/selinux.h>
1490+#endif /* WITH_LSPP */
1491+
1492 /*
1493 * HTTP client structure...
1494 */
1495@@ -64,6 +71,10 @@ struct cupsd_client_s
1496 #ifdef HAVE_AUTHORIZATION_H
1497 AuthorizationRef authref; /* Authorization ref */
1498 #endif /* HAVE_AUTHORIZATION_H */
1499+#ifdef WITH_LSPP
1500+ security_context_t scon; /* Security context of connection */
1501+ uid_t auid; /* Audit loginuid of the client */
1502+#endif /* WITH_LSPP */
1503 };
1504
1505 #define HTTP(con) &((con)->http)
1506@@ -133,6 +144,9 @@ extern void cupsdStartListening(void);
1507 extern void cupsdStopListening(void);
1508 extern void cupsdUpdateCGI(void);
1509 extern void cupsdWriteClient(cupsd_client_t *con);
1510+#ifdef WITH_LSPP
1511+extern uid_t client_pid_to_auid(pid_t clipid);
1512+#endif /* WITH_LSPP */
1513
1514
1515 /*
1516diff -up cups-1.4.5/scheduler/conf.c.lspp cups-1.4.5/scheduler/conf.c
1517--- cups-1.4.5/scheduler/conf.c.lspp 2010-12-24 13:21:30.897865572 +0000
1518+++ cups-1.4.5/scheduler/conf.c 2010-12-24 13:21:31.200857684 +0000
1519@@ -29,6 +29,7 @@
1520 * read_configuration() - Read a configuration file.
1521 * read_location() - Read a <Location path> definition.
1522 * read_policy() - Read a <Policy name> definition.
1523+ * is_lspp_config() - Is the system configured for LSPP
1524 */
1525
1526 /*
1527@@ -54,6 +55,9 @@
1528 # define INADDR_NONE 0xffffffff
1529 #endif /* !INADDR_NONE */
1530
1531+#ifdef WITH_LSPP
1532+# include <libaudit.h>
1533+#endif /* WITH_LSPP */
1534
1535 /*
1536 * Configuration variable structure...
1537@@ -172,6 +176,10 @@ static const cupsd_var_t variables[] =
1538 # if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
1539 { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME },
1540 # endif /* HAVE_LIBSSL || HAVE_GNUTLS */
1541+#ifdef WITH_LSPP
1542+ { "AuditLog", &AuditLog, CUPSD_VARTYPE_INTEGER },
1543+ { "PerPageLabels", &PerPageLabels, CUPSD_VARTYPE_BOOLEAN },
1544+#endif /* WITH_LSPP */
1545 #endif /* HAVE_SSL */
1546 { "ServerName", &ServerName, CUPSD_VARTYPE_STRING },
1547 { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME },
1548@@ -430,6 +438,9 @@ cupsdReadConfiguration(void)
1549 const char *tmpdir; /* TMPDIR environment variable */
1550 struct stat tmpinfo; /* Temporary directory info */
1551 cupsd_policy_t *p; /* Policy */
1552+#ifdef WITH_LSPP
1553+ char *audit_message; /* Audit message string */
1554+#endif /* WITH_LSPP */
1555
1556
1557 /*
1558@@ -713,6 +724,25 @@ cupsdReadConfiguration(void)
1559
1560 RunUser = getuid();
1561
1562+#ifdef WITH_LSPP
1563+ if (AuditLog != -1)
1564+ {
1565+ /*
1566+ * ClassifyOverride is set during read_configuration, if its ON, report it now
1567+ */
1568+ if (ClassifyOverride)
1569+ audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
1570+ "[Config] ClassifyOverride=enabled Users can override print banners",
1571+ ServerName, NULL, NULL, 1);
1572+ /*
1573+ * PerPageLabel is set during read_configuration, if its OFF, report it now
1574+ */
1575+ if (!PerPageLabels)
1576+ audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
1577+ "[Config] PerPageLabels=disabled", ServerName, NULL, NULL, 1);
1578+ }
1579+#endif /* WITH_LSPP */
1580+
1581 cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
1582 RemotePort ? "enabled" : "disabled");
1583
1584@@ -1081,11 +1111,23 @@ cupsdReadConfiguration(void)
1585 * Update classification setting as needed...
1586 */
1587
1588- if (Classification && !strcasecmp(Classification, "none"))
1589+ if (Classification && strcasecmp(Classification, "none") == 0)
1590 cupsdClearString(&Classification);
1591
1592 if (Classification)
1593+ {
1594 cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
1595+#ifdef WITH_LSPP
1596+ if (AuditLog != -1)
1597+ {
1598+ audit_message = NULL;
1599+ cupsdSetStringf(&audit_message, "[Config] Classification=%s", Classification);
1600+ audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
1601+ ServerName, NULL, NULL, 1);
1602+ cupsdClearString(&audit_message);
1603+ }
1604+#endif /* WITH_LSPP */
1605+ }
1606
1607 /*
1608 * Check the MaxClients setting, and then allocate memory for it...
1609@@ -3657,6 +3699,18 @@ read_location(cups_file_t *fp, /* I - C
1610 return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
1611 }
1612
1613+#ifdef WITH_LSPP
1614+int is_lspp_config()
1615+{
1616+ if (Classification != NULL)
1617+ return ((strcasecmp(Classification, MLS_CONFIG) == 0)
1618+ || (strcasecmp(Classification, TE_CONFIG) == 0)
1619+ || (strcasecmp(Classification, SELINUX_CONFIG) == 0));
1620+ else
1621+ return 0;
1622+}
1623+#endif /* WITH_LSPP */
1624+
1625
1626 /*
1627 * 'read_policy()' - Read a <Policy name> definition.
1628diff -up cups-1.4.5/scheduler/conf.h.lspp cups-1.4.5/scheduler/conf.h
1629--- cups-1.4.5/scheduler/conf.h.lspp 2010-12-24 13:21:30.897865572 +0000
1630+++ cups-1.4.5/scheduler/conf.h 2010-12-24 13:21:31.202857632 +0000
1631@@ -250,6 +250,12 @@ VAR char *ServerKey VALUE(NULL);
1632 VAR int SSLOptions VALUE(CUPSD_SSL_NONE);
1633 /* SSL/TLS options */
1634 #endif /* HAVE_SSL */
1635+#ifdef WITH_LSPP
1636+VAR int AuditLog VALUE(-1),
1637+ /* File descriptor for audit */
1638+ PerPageLabels VALUE(TRUE);
1639+ /* Put the label on each page */
1640+#endif /* WITH_LSPP */
1641
1642 #ifdef HAVE_LAUNCHD
1643 VAR int LaunchdTimeout VALUE(DEFAULT_KEEPALIVE);
1644@@ -266,6 +272,9 @@ VAR char *SystemGroupAuthKey VALUE(NULL
1645 /* System group auth key */
1646 #endif /* HAVE_AUTHORIZATION_H */
1647
1648+#ifdef WITH_LSPP
1649+extern int is_lspp_config(void);
1650+#endif /* WITH_LSPP */
1651
1652 /*
1653 * Prototypes...
1654diff -up cups-1.4.5/scheduler/ipp.c.lspp cups-1.4.5/scheduler/ipp.c
1655--- cups-1.4.5/scheduler/ipp.c.lspp 2010-12-24 13:21:31.114859924 +0000
1656+++ cups-1.4.5/scheduler/ipp.c 2010-12-24 13:21:31.217857242 +0000
1657@@ -41,6 +41,7 @@
1658 * cancel_all_jobs() - Cancel all print jobs.
1659 * cancel_job() - Cancel a print job.
1660 * cancel_subscription() - Cancel a subscription.
1661+ * check_context() - Check the SELinux context for a user and job
1662 * check_quotas() - Check quotas for a printer and user.
1663 * check_rss_recipient() - Check that we do not have a duplicate RSS
1664 * feed URI.
1665@@ -102,6 +103,9 @@
1666 * validate_user() - Validate the user for the request.
1667 */
1668
1669+/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
1670+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
1671+
1672 /*
1673 * Include necessary headers...
1674 */
1675@@ -124,6 +128,14 @@ extern int mbr_check_membership_by_id(uu
1676 # endif /* HAVE_MEMBERSHIPPRIV_H */
1677 #endif /* __APPLE__ */
1678
1679+#ifdef WITH_LSPP
1680+#include <libaudit.h>
1681+#include <selinux/selinux.h>
1682+#include <selinux/context.h>
1683+#include <selinux/avc.h>
1684+#include <selinux/flask.h>
1685+#include <selinux/av_permissions.h>
1686+#endif /* WITH_LSPP */
1687
1688 /*
1689 * Local functions...
1690@@ -157,6 +169,9 @@ static void cancel_all_jobs(cupsd_client
1691 static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
1692 static void cancel_subscription(cupsd_client_t *con, int id);
1693 static int check_rss_recipient(const char *recipient);
1694+#ifdef WITH_LSPP
1695+static int check_context(cupsd_client_t *con, cupsd_job_t *job);
1696+#endif /* WITH_LSPP */
1697 static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
1698 static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
1699 int quickcopy);
1700@@ -1354,6 +1369,21 @@ add_job(cupsd_client_t *con, /* I - Cl
1701 ipp_attribute_t *media_col, /* media-col attribute */
1702 *media_margin; /* media-*-margin attribute */
1703 ipp_t *unsup_col; /* media-col in unsupported response */
1704+#ifdef WITH_LSPP
1705+ char *audit_message; /* Audit message string */
1706+ char *printerfile; /* device file pointed to by the printer */
1707+ char *userheader = NULL; /* User supplied job-sheets[0] */
1708+ char *userfooter = NULL; /* User supplied job-sheets[1] */
1709+ int override = 0; /* Was a banner overrode on a job */
1710+ security_id_t clisid; /* SELinux SID for the client */
1711+ security_id_t psid; /* SELinux SID for the printer */
1712+ context_t printercon; /* Printer's context string */
1713+ struct stat printerstat; /* Printer's stat buffer */
1714+ security_context_t devcon; /* Printer's SELinux context */
1715+ struct avc_entry_ref avcref; /* Pointer to the access vector cache */
1716+ security_class_t tclass; /* Object class for the SELinux check */
1717+ access_vector_t avr; /* Access method being requested */
1718+#endif /* WITH_LSPP */
1719
1720
1721 cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
1722@@ -1612,6 +1642,106 @@ add_job(cupsd_client_t *con, /* I - Cl
1723 ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
1724 "Untitled");
1725
1726+#ifdef WITH_LSPP
1727+ if (is_lspp_config())
1728+ {
1729+ if (!con->scon || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
1730+ {
1731+ cupsdLogMessage(CUPSD_LOG_ERROR, "add_job: missing classification for connection \'%s\'!", printer->name);
1732+ send_ipp_status(con, IPP_INTERNAL_ERROR, _("Missing required security attributes."));
1733+ return (NULL);
1734+ }
1735+
1736+ /*
1737+ * Perform an access check so that if the user gets feedback at enqueue time
1738+ */
1739+
1740+ printerfile = strstr(printer->device_uri, "/dev/");
1741+ if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
1742+ printerfile = printer->device_uri + strlen("file:");
1743+
1744+ if (printerfile != NULL)
1745+ {
1746+ cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: Attempting an access check on printer device %s",
1747+ printerfile);
1748+
1749+ if (lstat(printerfile, &printerstat) < 0)
1750+ {
1751+ if (errno != ENOENT)
1752+ {
1753+ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to stat the printer"));
1754+ return (NULL);
1755+ }
1756+ /*
1757+ * The printer does not exist, so for now assume it's a FileDevice
1758+ */
1759+ tclass = SECCLASS_FILE;
1760+ avr = FILE__WRITE;
1761+ }
1762+ else if (S_ISCHR(printerstat.st_mode))
1763+ {
1764+ tclass = SECCLASS_CHR_FILE;
1765+ avr = CHR_FILE__WRITE;
1766+ }
1767+ else if (S_ISREG(printerstat.st_mode))
1768+ {
1769+ tclass = SECCLASS_FILE;
1770+ avr = FILE__WRITE;
1771+ }
1772+ else
1773+ {
1774+ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer is not a character device or regular file"));
1775+ return (NULL);
1776+ }
1777+ static avc_initialized = 0;
1778+ if (!avc_initialized++)
1779+ avc_init("cupsd_enqueue_", NULL, NULL, NULL, NULL);
1780+ avc_entry_ref_init(&avcref);
1781+ if (avc_context_to_sid(con->scon, &clisid) != 0)
1782+ {
1783+ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the client"));
1784+ return (NULL);
1785+ }
1786+ if (getfilecon(printerfile, &devcon) == -1)
1787+ {
1788+ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux context of the printer"));
1789+ return (NULL);
1790+ }
1791+ printercon = context_new(devcon);
1792+ cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: printer context %s client context %s",
1793+ context_str(printercon), con->scon);
1794+ context_free(printercon);
1795+
1796+ if (avc_context_to_sid(devcon, &psid) != 0)
1797+ {
1798+ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the printer"));
1799+ freecon(devcon);
1800+ return (NULL);
1801+ }
1802+ freecon(devcon);
1803+ if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
1804+ {
1805+ /*
1806+ * The access check failed, so cancel the job and send an audit message
1807+ */
1808+ if (AuditLog != -1)
1809+ {
1810+ audit_message = NULL;
1811+ cupsdSetStringf(&audit_message, "job=? auid=%u acct=%s obj=%s refused"
1812+ " unable to access printer=%s", con->auid,
1813+ con->username, con->scon, printer->name);
1814+ audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
1815+ ServerName, NULL, NULL, 0);
1816+ cupsdClearString(&audit_message);
1817+ }
1818+
1819+ send_ipp_status(con, IPP_NOT_AUTHORIZED, _("SELinux prohibits access to the printer"));
1820+ return (NULL);
1821+ }
1822+ }
1823+ }
1824+#endif /* WITH_LSPP */
1825+
1826 if ((job = cupsdAddJob(priority, printer->name)) == NULL)
1827 {
1828 send_ipp_status(con, IPP_INTERNAL_ERROR,
1829@@ -1620,6 +1750,32 @@ add_job(cupsd_client_t *con, /* I - Cl
1830 return (NULL);
1831 }
1832
1833+#ifdef WITH_LSPP
1834+ if (is_lspp_config())
1835+ {
1836+ /*
1837+ * duplicate the security context and auid of the connection into the job structure
1838+ */
1839+ job->scon = strdup(con->scon);
1840+ job->auid = con->auid;
1841+
1842+ /*
1843+ * add the security context to the request so that on a restart the security
1844+ * attributes will be able to be restored
1845+ */
1846+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "security-context",
1847+ NULL, job->scon);
1848+ }
1849+ else
1850+ {
1851+ /*
1852+ * Fill in the security context of the job as unlabeled
1853+ */
1854+ cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: setting context of job to %s", UNKNOWN_SL);
1855+ cupsdSetString(&job->scon, UNKNOWN_SL);
1856+ }
1857+#endif /* WITH_LSPP */
1858+
1859 job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
1860 CUPS_PRINTER_REMOTE);
1861 job->attrs = con->request;
1862@@ -1825,6 +1981,29 @@ add_job(cupsd_client_t *con, /* I - Cl
1863 attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
1864 attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]);
1865 }
1866+#ifdef WITH_LSPP
1867+ else
1868+ {
1869+ /*
1870+ * The option was present, so capture the user supplied strings
1871+ */
1872+ userheader = strdup(attr->values[0].string.text);
1873+
1874+ if (attr->num_values > 1)
1875+ userfooter = strdup(attr->values[1].string.text);
1876+
1877+ if (Classification != NULL && (strcmp(userheader, Classification) == 0)
1878+ && userfooter &&(strcmp(userfooter, Classification) == 0))
1879+ {
1880+ /*
1881+ * Since both values are Classification, the user is not trying to Override
1882+ */
1883+ free(userheader);
1884+ if (userfooter) free(userfooter);
1885+ userheader = userfooter = NULL;
1886+ }
1887+ }
1888+#endif /* WITH_LSPP */
1889
1890 job->job_sheets = attr;
1891
1892@@ -1855,6 +2034,9 @@ add_job(cupsd_client_t *con, /* I - Cl
1893 "job-sheets=\"%s,none\", "
1894 "job-originating-user-name=\"%s\"",
1895 Classification, job->username);
1896+#ifdef WITH_LSPP
1897+ override = 1;
1898+#endif /* WITH_LSPP */
1899 }
1900 else if (attr->num_values == 2 &&
1901 strcmp(attr->values[0].string.text,
1902@@ -1873,6 +2055,9 @@ add_job(cupsd_client_t *con, /* I - Cl
1903 "job-originating-user-name=\"%s\"",
1904 attr->values[0].string.text,
1905 attr->values[1].string.text, job->username);
1906+#ifdef WITH_LSPP
1907+ override = 1;
1908+#endif /* WITH_LSPP */
1909 }
1910 else if (strcmp(attr->values[0].string.text, Classification) &&
1911 strcmp(attr->values[0].string.text, "none") &&
1912@@ -1893,6 +2078,9 @@ add_job(cupsd_client_t *con, /* I - Cl
1913 "job-originating-user-name=\"%s\"",
1914 attr->values[0].string.text,
1915 attr->values[1].string.text, job->username);
1916+#ifdef WITH_LSPP
1917+ override = 1;
1918+#endif /* WITH_LSPP */
1919 }
1920 }
1921 else if (strcmp(attr->values[0].string.text, Classification) &&
1922@@ -1933,8 +2121,52 @@ add_job(cupsd_client_t *con, /* I - Cl
1923 "job-sheets=\"%s\", "
1924 "job-originating-user-name=\"%s\"",
1925 Classification, job->username);
1926+#ifdef WITH_LSPP
1927+ override = 1;
1928+#endif /* WITH_LSPP */
1929+ }
1930+#ifdef WITH_LSPP
1931+ if (is_lspp_config() && AuditLog != -1)
1932+ {
1933+ audit_message = NULL;
1934+
1935+ if (userheader || userfooter)
1936+ {
1937+ if (!override)
1938+ {
1939+ /*
1940+ * The user overrode the banner, so audit it
1941+ */
1942+ cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
1943+ " using banners=%s,%s", job->id, userheader,
1944+ userfooter, attr->values[0].string.text,
1945+ (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
1946+ audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
1947+ ServerName, NULL, NULL, 1);
1948+ }
1949+ else
1950+ {
1951+ /*
1952+ * The user tried to override the banner, audit the failure
1953+ */
1954+ cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
1955+ " ignored banners=%s,%s", job->id, userheader,
1956+ userfooter, attr->values[0].string.text,
1957+ (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
1958+ audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
1959+ ServerName, NULL, NULL, 0);
1960+ }
1961+ cupsdClearString(&audit_message);
1962+ }
1963 }
1964+
1965+ if (userheader)
1966+ free(userheader);
1967+ if (userfooter)
1968+ free(userfooter);
1969+#endif /* WITH_LSPP */
1970 }
1971+
1972
1973 /*
1974 * See if we need to add the starting sheet...
1975@@ -4289,6 +4521,107 @@ check_rss_recipient(
1976 }
1977
1978
1979+#ifdef WITH_LSPP
1980+/*
1981+ * 'check_context()' - Check SELinux security context of a user and job
1982+ */
1983+
1984+static int /* O - 1 if OK, 0 if not, -1 on error */
1985+check_context(cupsd_client_t *con, /* I - Client connection */
1986+ cupsd_job_t *job) /* I - Job */
1987+{
1988+ int enforcing; /* is SELinux in enforcing mode */
1989+ char filename[1024]; /* Filename of the spool file */
1990+ security_id_t clisid; /* SELinux SID of the client */
1991+ security_id_t jobsid; /* SELinux SID of the job */
1992+ security_id_t filesid; /* SELinux SID of the spool file */
1993+ struct avc_entry_ref avcref; /* AVC entry cache pointer */
1994+ security_class_t tclass; /* SELinux security class */
1995+ access_vector_t avr; /* SELinux access being queried */
1996+ security_context_t spoolfilecon; /* SELinux context of the spool file */
1997+
1998+
1999+ /*
2000+ * Validate the input to be sure there are contexts to work with...
2001+ */
2002+
2003+ if (con->scon == NULL || job->scon == NULL
2004+ || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0
2005+ || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
2006+ return -1;
2007+
2008+ if ((enforcing = security_getenforce()) == -1)
2009+ {
2010+ cupsdLogMessage(CUPSD_LOG_ERROR, "Error while determining SELinux enforcement");
2011+ return -1;
2012+ }
2013+ cupsdLogMessage(CUPSD_LOG_DEBUG, "check_context: client context %s job context %s", con->scon, job->scon);
2014+
2015+
2016+ /*
2017+ * Initialize the avc engine...
2018+ */
2019+
2020+ static avc_initialized = 0;
2021+ if (! avc_initialized++)
2022+ {
2023+ if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0)
2024+ {
2025+ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable avc_init");
2026+ return -1;
2027+ }
2028+ }
2029+ if (avc_context_to_sid(con->scon, &clisid) != 0)
2030+ {
2031+ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", con->scon);
2032+ return -1;
2033+ }
2034+ avc_context_to_sid(job->scon, &jobsid);
2035+ avc_entry_ref_init(&avcref);
2036+ tclass = SECCLASS_FILE;
2037+ avr = FILE__READ;
2038+
2039+ /*
2040+ * Perform the check with the client as the subject, first with the job as the object
2041+ * if that fails then with the spool file as the object...
2042+ */
2043+
2044+ if (avc_has_perm_noaudit(clisid, jobsid, tclass, avr, &avcref, NULL) != 0)
2045+ {
2046+ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access based on the client context");
2047+
2048+ snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
2049+ if (getfilecon(filename, &spoolfilecon) == -1)
2050+ {
2051+ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to get spoolfile context");
2052+ return -1;
2053+ }
2054+ if (avc_context_to_sid(spoolfilecon, &filesid) != 0)
2055+ {
2056+ cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to determine the SELinux sid for the spool file");
2057+ freecon(spoolfilecon);
2058+ return -1;
2059+ }
2060+ freecon(spoolfilecon);
2061+ if (avc_has_perm_noaudit(clisid, filesid, tclass, avr, &avcref, NULL) != 0)
2062+ {
2063+ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access to the spool file");
2064+ return 0;
2065+ }
2066+ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access to the spool file");
2067+ return 1;
2068+ }
2069+ else
2070+ if (enforcing == 0)
2071+ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: allowing operation due to permissive mode");
2072+ else
2073+ cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access based on the client context");
2074+
2075+ return 1;
2076+}
2077+#endif /* WITH_LSPP */
2078+
2079+
2080 /*
2081 * 'check_quotas()' - Check quotas for a printer and user.
2082 */
2083@@ -4843,6 +5176,15 @@ copy_banner(cupsd_client_t *con, /* I -
2084 char attrname[255], /* Name of attribute */
2085 *s; /* Pointer into name */
2086 ipp_attribute_t *attr; /* Attribute */
2087+#ifdef WITH_LSPP
2088+ const char *mls_label; /* SL of print job */
2089+ char *jobrange; /* SELinux sensitivity range */
2090+ char *jobclearance; /* SELinux low end clearance */
2091+ context_t jobcon; /* SELinux context of the job */
2092+ context_t tmpcon; /* Temp context to set the level */
2093+ security_context_t spoolcon; /* Context of the file in the spool */
2094+#endif /* WITH_LSPP */
2095+
2096
2097
2098 cupsdLogMessage(CUPSD_LOG_DEBUG2,
2099@@ -4878,6 +5220,82 @@ copy_banner(cupsd_client_t *con, /* I -
2100
2101 fchmod(cupsFileNumber(out), 0640);
2102 fchown(cupsFileNumber(out), RunUser, Group);
2103+#ifdef WITH_LSPP
2104+ if (job->scon != NULL &&
2105+ strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
2106+ {
2107+ if (getfilecon(filename, &spoolcon) == -1)
2108+ {
2109+ cupsdLogMessage(CUPSD_LOG_ERROR,
2110+ "copy_banner: Unable to get the context of the banner file %s - %s",
2111+ filename, strerror(errno));
2112+ job->num_files --;
2113+ return (0);
2114+ }
2115+ tmpcon = context_new(spoolcon);
2116+ jobcon = context_new(job->scon);
2117+ freecon(spoolcon);
2118+ if (!tmpcon || !jobcon)
2119+ {
2120+ if (tmpcon)
2121+ context_free(tmpcon);
2122+ if (jobcon)
2123+ context_free(jobcon);
2124+ cupsdLogMessage(CUPSD_LOG_ERROR,
2125+ "copy_banner: Unable to get the SELinux contexts");
2126+ job->num_files --;
2127+ return (0);
2128+ }
2129+ jobrange = context_range_get(jobcon);
2130+ if (jobrange)
2131+ {
2132+ jobrange = strdup(jobrange);
2133+ if ((jobclearance = strtok(jobrange, "-")) != NULL)
2134+ {
2135+ if (context_range_set(tmpcon, jobclearance) == -1)
2136+ {
2137+ cupsdLogMessage(CUPSD_LOG_ERROR,
2138+ "copy_banner: Unable to set the level of the context for file %s - %s",
2139+ filename, strerror(errno));
2140+ free(jobrange);
2141+ context_free(jobcon);
2142+ context_free(tmpcon);
2143+ job->num_files --;
2144+ return (0);
2145+ }
2146+ }
2147+ else
2148+ {
2149+ if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
2150+ {
2151+ cupsdLogMessage(CUPSD_LOG_ERROR,
2152+ "copy_banner: Unable to set the level of the context for file %s - %s",
2153+ filename, strerror(errno));
2154+ free(jobrange);
2155+ context_free(jobcon);
2156+ context_free(tmpcon);
2157+ job->num_files --;
2158+ return (0);
2159+ }
2160+ }
2161+ free(jobrange);
2162+ }
2163+ if (setfilecon(filename, context_str(tmpcon)) == -1)
2164+ {
2165+ cupsdLogMessage(CUPSD_LOG_ERROR,
2166+ "copy_banner: Unable to set the context of the banner file %s - %s",
2167+ filename, strerror(errno));
2168+ context_free(jobcon);
2169+ context_free(tmpcon);
2170+ job->num_files --;
2171+ return (0);
2172+ }
2173+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner: %s set to %s",
2174+ filename, context_str(tmpcon));
2175+ context_free(jobcon);
2176+ context_free(tmpcon);
2177+ }
2178+#endif /* WITH_LSPP */
2179
2180 /*
2181 * Try the localized banner file under the subdirectory...
2182@@ -4972,6 +5390,24 @@ copy_banner(cupsd_client_t *con, /* I -
2183 else
2184 s = attrname;
2185
2186+#ifdef WITH_LSPP
2187+ if (strcmp(s, "mls-label") == 0)
2188+ {
2189+ if (job->scon != NULL && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
2190+ {
2191+ jobcon = context_new(job->scon);
2192+ if (strcasecmp(name, MLS_CONFIG) == 0)
2193+ mls_label = context_range_get(jobcon);
2194+ else if (strcasecmp(name, TE_CONFIG) == 0)
2195+ mls_label = context_type_get(jobcon);
2196+ else // default to using the whole context string
2197+ mls_label = context_str(jobcon);
2198+ cupsFilePuts(out, mls_label);
2199+ context_free(jobcon);
2200+ }
2201+ continue;
2202+ }
2203+#endif /* WITH_LSPP */
2204 if (!strcmp(s, "printer-name"))
2205 {
2206 cupsFilePuts(out, job->dest);
2207@@ -6945,6 +7381,22 @@ get_job_attrs(cupsd_client_t *con, /* I
2208 return;
2209 }
2210
2211+
2212+#ifdef WITH_LSPP
2213+ /*
2214+ * Check SELinux...
2215+ */
2216+ if (is_lspp_config() && check_context(con, job) != 1)
2217+ {
2218+ /*
2219+ * Unfortunately we have to lie to the user...
2220+ */
2221+ send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
2222+ return;
2223+ }
2224+#endif /* WITH_LSPP */
2225+
2226+
2227 /*
2228 * Copy attributes...
2229 */
2230@@ -7175,6 +7627,11 @@ get_jobs(cupsd_client_t *con, /* I - C
2231 if (username[0] && strcasecmp(username, job->username))
2232 continue;
2233
2234+#ifdef WITH_LSPP
2235+ if (is_lspp_config() && check_context(con, job) != 1)
2236+ continue;
2237+#endif /* WITH_LSPP */
2238+
2239 if (count > 0)
2240 ippAddSeparator(con->response);
2241
2242@@ -11594,6 +12051,11 @@ validate_user(cupsd_job_t *job, /* I
2243
2244 strlcpy(username, get_username(con), userlen);
2245
2246+#ifdef WITH_LSPP
2247+ if (is_lspp_config() && check_context(con, job) != 1)
2248+ return 0;
2249+#endif /* WITH_LSPP */
2250+
2251 /*
2252 * Check the username against the owner...
2253 */
2254diff -up cups-1.4.5/scheduler/job.c.lspp cups-1.4.5/scheduler/job.c
2255--- cups-1.4.5/scheduler/job.c.lspp 2010-12-24 13:21:31.028862162 +0000
2256+++ cups-1.4.5/scheduler/job.c 2010-12-24 13:21:31.224857060 +0000
2257@@ -66,6 +66,9 @@
2258 * update_job_attrs() - Update the job-printer-* attributes.
2259 */
2260
2261+/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
2262+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
2263+
2264 /*
2265 * Include necessary headers...
2266 */
2267@@ -75,6 +78,14 @@
2268 #include <cups/backend.h>
2269 #include <cups/dir.h>
2270
2271+#ifdef WITH_LSPP
2272+#include <libaudit.h>
2273+#include <selinux/selinux.h>
2274+#include <selinux/context.h>
2275+#include <selinux/avc.h>
2276+#include <selinux/flask.h>
2277+#include <selinux/av_permissions.h>
2278+#endif /* WITH_LSPP */
2279
2280 /*
2281 * Design Notes for Job Management
2282@@ -505,6 +516,14 @@ cupsdContinueJob(cupsd_job_t *job) /* I
2283 /* PRINTER env variable */
2284 rip_max_cache[255];
2285 /* RIP_MAX_CACHE env variable */
2286+#ifdef WITH_LSPP
2287+ char *audit_message = NULL; /* Audit message string */
2288+ context_t jobcon; /* SELinux context of the job */
2289+ char *label_template = NULL; /* SL to put in classification
2290+ env var */
2291+ const char *mls_label = NULL; /* SL to put in classification
2292+ env var */
2293+#endif /* WITH_LSPP */
2294
2295
2296 cupsdLogMessage(CUPSD_LOG_DEBUG2,
2297@@ -929,6 +948,67 @@ cupsdContinueJob(cupsd_job_t *job) /* I
2298 }
2299 }
2300
2301+#ifdef WITH_LSPP
2302+ if (is_lspp_config())
2303+ {
2304+ if (!job->scon || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
2305+ {
2306+ if (AuditLog != -1)
2307+ {
2308+ audit_message = NULL;
2309+ cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s",
2310+ job->id, job->auid, job->username, job->printer->name, title);
2311+ audit_log_user_message(AuditLog, AUDIT_USER_UNLABELED_EXPORT, audit_message,
2312+ ServerName, NULL, NULL, 1);
2313+ cupsdClearString(&audit_message);
2314+ }
2315+ }
2316+ else
2317+ {
2318+ jobcon = context_new(job->scon);
2319+
2320+ if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME)) == NULL)
2321+ label_template = strdup(Classification);
2322+ else if (attr->num_values > 1 &&
2323+ strcmp(attr->values[1].string.text, "none") != 0)
2324+ label_template = strdup(attr->values[1].string.text);
2325+ else
2326+ label_template = strdup(attr->values[0].string.text);
2327+
2328+ if (strcasecmp(label_template, MLS_CONFIG) == 0)
2329+ mls_label = context_range_get(jobcon);
2330+ else if (strcasecmp(label_template, TE_CONFIG) == 0)
2331+ mls_label = context_type_get(jobcon);
2332+ else if (strcasecmp(label_template, SELINUX_CONFIG) == 0)
2333+ mls_label = context_str(jobcon);
2334+ else
2335+ mls_label = label_template;
2336+
2337+ if (mls_label && (PerPageLabels || banner_page))
2338+ {
2339+ snprintf(classification, sizeof(classification), "CLASSIFICATION=LSPP:%s", mls_label);
2340+ envp[envc ++] = classification;
2341+ }
2342+
2343+ if ((AuditLog != -1) && !banner_page)
2344+ {
2345+ audit_message = NULL;
2346+ cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s"
2347+ " obj=%s label=%s", job->id, job->auid, job->username,
2348+ job->printer->name, title, job->scon, mls_label?mls_label:"none");
2349+ audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
2350+ ServerName, NULL, NULL, 1);
2351+ cupsdClearString(&audit_message);
2352+ }
2353+ context_free(jobcon);
2354+ free(label_template);
2355+ }
2356+ }
2357+ else
2358+ /*
2359+ * Fall through to the non-LSPP behavior
2360+ */
2361+#endif /* WITH_LSPP */
2362 if (Classification && !banner_page)
2363 {
2364 if ((attr = ippFindAttribute(job->attrs, "job-sheets",
2365@@ -1165,13 +1245,13 @@ cupsdContinueJob(cupsd_job_t *job) /* I
2366 if (access(command, F_OK))
2367 {
2368 snprintf(command, sizeof(command), "%s/backend/%s", ServerBin_compat,
2369- method);
2370+ scheme);
2371 if (!access(command, F_OK))
2372 {
2373 /* Not in the correct directory, but we found it in the compat
2374 * directory. Issue a warning. */
2375 cupsdLogMessage(CUPSD_LOG_INFO,
2376- "Backend '%s' not in %s/backend!", method,
2377+ "Backend '%s' not in %s/backend!", scheme,
2378 ServerBin);
2379 }
2380 else
2381@@ -1179,7 +1259,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I
2382 /* Not in the compat directory either; make any error
2383 messages use the correct directory name then. */
2384 snprintf(command, sizeof(command), "%s/backend/%s", ServerBin,
2385- method);
2386+ scheme);
2387 }
2388 }
2389 #endif /* __x86_64__ */
2390@@ -1626,6 +1706,20 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J
2391 goto error;
2392 }
2393
2394+#ifdef WITH_LSPP
2395+ if ((attr = ippFindAttribute(job->attrs, "security-context", IPP_TAG_NAME)) != NULL)
2396+ cupsdSetString(&job->scon, attr->values[0].string.text);
2397+ else if (is_lspp_config())
2398+ {
2399+ /*
2400+ * There was no security context so delete the job
2401+ */
2402+ cupsdLogMessage(CUPSD_LOG_ERROR, "LoadAllJobs: Missing or bad security-context attribute in control file \"%s\"!",
2403+ jobfile);
2404+ goto error;
2405+ }
2406+#endif /* WITH_LSPP */
2407+
2408 job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed",
2409 IPP_TAG_INTEGER);
2410 job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
2411@@ -2013,6 +2107,14 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J
2412 {
2413 char filename[1024]; /* Job control filename */
2414 cups_file_t *fp; /* Job file */
2415+#ifdef WITH_LSPP
2416+ security_context_t spoolcon; /* context of the job control file */
2417+ context_t jobcon; /* contex_t container for job->scon */
2418+ context_t tmpcon; /* Temp context to swap the level */
2419+ char *jobclearance; /* SELinux low end clearance */
2420+ const char *jobrange; /* SELinux sensitivity range */
2421+ char *jobrange_copy; /* SELinux sensitivity range */
2422+#endif /* WITH_LSPP */
2423
2424
2425 cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
2426@@ -2031,6 +2133,76 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J
2427 fchmod(cupsFileNumber(fp), 0600);
2428 fchown(cupsFileNumber(fp), RunUser, Group);
2429
2430+#ifdef WITH_LSPP
2431+ if (job->scon && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
2432+ {
2433+ if (getfilecon(filename, &spoolcon) == -1)
2434+ {
2435+ cupsdLogMessage(CUPSD_LOG_ERROR,
2436+ "Unable to get context of job control file \"%s\" - %s.",
2437+ filename, strerror(errno));
2438+ return;
2439+ }
2440+ jobcon = context_new(job->scon);
2441+ tmpcon = context_new(spoolcon);
2442+ freecon(spoolcon);
2443+ if (!jobcon || !tmpcon)
2444+ {
2445+ if (jobcon)
2446+ context_free(jobcon);
2447+ if (tmpcon)
2448+ context_free(tmpcon);
2449+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get SELinux contexts");
2450+ return;
2451+ }
2452+ jobrange = context_range_get(jobcon);
2453+ if (jobrange)
2454+ {
2455+ jobrange_copy = strdup(jobrange);
2456+ if ((jobclearance = strtok(jobrange_copy, "-")) != NULL)
2457+ {
2458+ if (context_range_set(tmpcon, jobclearance) == -1)
2459+ {
2460+ cupsdLogMessage(CUPSD_LOG_ERROR,
2461+ "Unable to set the range for job control file \"%s\" - %s.",
2462+ filename, strerror(errno));
2463+ free(jobrange_copy);
2464+ context_free(tmpcon);
2465+ context_free(jobcon);
2466+ return;
2467+ }
2468+ }
2469+ else
2470+ {
2471+ if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
2472+ {
2473+ cupsdLogMessage(CUPSD_LOG_ERROR,
2474+ "Unable to set the range for job control file \"%s\" - %s.",
2475+ filename, strerror(errno));
2476+ free(jobrange_copy);
2477+ context_free(tmpcon);
2478+ context_free(jobcon);
2479+ return;
2480+ }
2481+ }
2482+ free(jobrange_copy);
2483+ }
2484+ if (setfilecon(filename, context_str(tmpcon)) == -1)
2485+ {
2486+ cupsdLogMessage(CUPSD_LOG_ERROR,
2487+ "Unable to set context of job control file \"%s\" - %s.",
2488+ filename, strerror(errno));
2489+ context_free(tmpcon);
2490+ context_free(jobcon);
2491+ return;
2492+ }
2493+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p): new spool file context=%s",
2494+ job, context_str(tmpcon));
2495+ context_free(tmpcon);
2496+ context_free(jobcon);
2497+ }
2498+#endif /* WITH_LSPP */
2499+
2500 job->attrs->state = IPP_IDLE;
2501
2502 if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
2503@@ -3332,6 +3504,18 @@ get_options(cupsd_job_t *job, /* I - Jo
2504 banner_page)
2505 continue;
2506
2507+#ifdef WITH_LSPP
2508+ /*
2509+ * In LSPP mode refuse to honor the page-label
2510+ */
2511+ if (is_lspp_config() &&
2512+ !strcmp(attr->name, "page-label"))
2513+ {
2514+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Ignoring page-label option due to LSPP mode");
2515+ continue;
2516+ }
2517+#endif /* WITH_LSPP */
2518+
2519 /*
2520 * Otherwise add them to the list...
2521 */
2522@@ -4020,6 +4204,19 @@ static void
2523 start_job(cupsd_job_t *job, /* I - Job ID */
2524 cupsd_printer_t *printer) /* I - Printer to print job */
2525 {
2526+#ifdef WITH_LSPP
2527+ char *audit_message = NULL; /* Audit message string */
2528+ char *printerfile = NULL; /* Device file pointed to by the printer */
2529+ security_id_t clisid; /* SELinux SID for the client */
2530+ security_id_t psid; /* SELinux SID for the printer */
2531+ context_t printercon; /* Printer's context string */
2532+ struct stat printerstat; /* Printer's stat buffer */
2533+ security_context_t devcon; /* Printer's SELinux context */
2534+ struct avc_entry_ref avcref; /* Pointer to the access vector cache */
2535+ security_class_t tclass; /* Object class for the SELinux check */
2536+ access_vector_t avr; /* Access method being requested */
2537+#endif /* WITH_LSPP */
2538+
2539 cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))",
2540 job, job->id, printer, printer->name);
2541
2542@@ -4142,6 +4339,108 @@ start_job(cupsd_job_t *job, /* I -
2543 fcntl(job->side_pipes[1], F_SETFD,
2544 fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC);
2545
2546+#ifdef WITH_LSPP
2547+ if (is_lspp_config())
2548+ {
2549+ /*
2550+ * Perform an access check before printing, but only if the printer starts with /dev/
2551+ */
2552+ printerfile = strstr(printer->device_uri, "/dev/");
2553+ if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
2554+ printerfile = printer->device_uri + strlen("file:");
2555+
2556+ if (printerfile != NULL)
2557+ {
2558+ cupsdLogMessage(CUPSD_LOG_DEBUG,
2559+ "StartJob: Attempting to check access on printer device %s", printerfile);
2560+ if (lstat(printerfile, &printerstat) < 0)
2561+ {
2562+ if (errno != ENOENT)
2563+ {
2564+ cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to stat the printer");
2565+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
2566+ return ;
2567+ }
2568+ /*
2569+ * The printer does not exist, so for now assume it's a FileDevice
2570+ */
2571+ tclass = SECCLASS_FILE;
2572+ avr = FILE__WRITE;
2573+ }
2574+ else if (S_ISCHR(printerstat.st_mode))
2575+ {
2576+ tclass = SECCLASS_CHR_FILE;
2577+ avr = CHR_FILE__WRITE;
2578+ }
2579+ else if (S_ISREG(printerstat.st_mode))
2580+ {
2581+ tclass = SECCLASS_FILE;
2582+ avr = FILE__WRITE;
2583+ }
2584+ else
2585+ {
2586+ cupsdLogMessage(CUPSD_LOG_ERROR,
2587+ "StartJob: Printer is not a character device or regular file");
2588+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
2589+ return ;
2590+ }
2591+ static avc_initialized = 0;
2592+ if (!avc_initialized++)
2593+ avc_init("cupsd_dequeue_", NULL, NULL, NULL, NULL);
2594+ avc_entry_ref_init(&avcref);
2595+ if (avc_context_to_sid(job->scon, &clisid) != 0)
2596+ {
2597+ cupsdLogMessage(CUPSD_LOG_ERROR,
2598+ "StartJob: Unable to determine the SELinux sid for the job");
2599+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
2600+ return ;
2601+ }
2602+ if (getfilecon(printerfile, &devcon) == -1)
2603+ {
2604+ cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to get the SELinux context of %s",
2605+ printerfile);
2606+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
2607+ return ;
2608+ }
2609+ printercon = context_new(devcon);
2610+ cupsdLogMessage(CUPSD_LOG_DEBUG, "StartJob: printer context %s client context %s",
2611+ context_str(printercon), job->scon);
2612+ context_free(printercon);
2613+
2614+ if (avc_context_to_sid(devcon, &psid) != 0)
2615+ {
2616+ cupsdLogMessage(CUPSD_LOG_ERROR,
2617+ "StartJob: Unable to determine the SELinux sid for the printer");
2618+ freecon(devcon);
2619+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
2620+ return ;
2621+ }
2622+ freecon(devcon);
2623+
2624+ if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
2625+ {
2626+ /*
2627+ * The access check failed, so cancel the job and send an audit message
2628+ */
2629+ if (AuditLog != -1)
2630+ {
2631+ audit_message = NULL;
2632+ cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s obj=%s canceled"
2633+ " unable to access printer=%s", job->id,
2634+ job->auid, (job->username)?job->username:"?", job->scon, printer->name);
2635+ audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
2636+ ServerName, NULL, NULL, 0);
2637+ cupsdClearString(&audit_message);
2638+ }
2639+
2640+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
2641+
2642+ return ;
2643+ }
2644+ }
2645+ }
2646+#endif /* WITH_LSPP */
2647+
2648 /*
2649 * Now start the first file in the job...
2650 */
2651diff -up cups-1.4.5/scheduler/job.h.lspp cups-1.4.5/scheduler/job.h
2652--- cups-1.4.5/scheduler/job.h.lspp 2009-05-11 23:46:01.000000000 +0100
2653+++ cups-1.4.5/scheduler/job.h 2010-12-24 13:21:31.225857034 +0000
2654@@ -13,6 +13,13 @@
2655 * file is missing or damaged, see the license at "http://www.cups.org/".
2656 */
2657
2658+/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
2659+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
2660+
2661+#ifdef WITH_LSPP
2662+#include <selinux/selinux.h>
2663+#endif /* WITH_LSPP */
2664+
2665 /*
2666 * Constants...
2667 */
2668@@ -83,6 +90,10 @@ struct cupsd_job_s /**** Job request *
2669 krb5_ccache ccache; /* Kerberos credential cache */
2670 char *ccname; /* KRB5CCNAME environment variable */
2671 #endif /* HAVE_GSSAPI */
2672+#ifdef WITH_LSPP
2673+ security_context_t scon; /* Security context of job */
2674+ uid_t auid; /* Audit loginuid for this job */
2675+#endif /* WITH_LSPP */
2676 };
2677
2678 typedef struct cupsd_joblog_s /**** Job log message ****/
2679diff -up cups-1.4.5/scheduler/main.c.lspp cups-1.4.5/scheduler/main.c
2680--- cups-1.4.5/scheduler/main.c.lspp 2010-12-24 13:21:31.158858778 +0000
2681+++ cups-1.4.5/scheduler/main.c 2010-12-24 13:22:10.827825881 +0000
2682@@ -37,6 +37,8 @@
2683 * usage() - Show scheduler usage.
2684 */
2685
2686+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
2687+
2688 /*
2689 * Include necessary headers...
2690 */
2691@@ -76,6 +78,9 @@
2692 # include <dlfcn.h>
2693 #endif /* __APPLE__ && HAVE_DLFCN_H */
2694
2695+#ifdef WITH_LSPP
2696+# include <libaudit.h>
2697+#endif /* WITH_LSPP */
2698
2699 /*
2700 * Local functions...
2701@@ -145,6 +150,9 @@ main(int argc, /* I - Number of comm
2702 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
2703 struct sigaction action; /* Actions for POSIX signals */
2704 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
2705+#if WITH_LSPP
2706+ auditfail_t failmode; /* Action for audit_open failure */
2707+#endif /* WITH_LSPP */
2708 #ifdef __sgi
2709 cups_file_t *fp; /* Fake lpsched lock file */
2710 struct stat statbuf; /* Needed for checking lpsched FIFO */
2711@@ -474,6 +482,25 @@ main(int argc, /* I - Number of comm
2712 #endif /* DEBUG */
2713 }
2714
2715+#ifdef WITH_LSPP
2716+ if ((AuditLog = audit_open()) < 0 )
2717+ {
2718+ if (get_auditfail_action(&failmode) == 0)
2719+ {
2720+ if (failmode == FAIL_LOG)
2721+ {
2722+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to connect to audit subsystem.");
2723+ AuditLog = -1;
2724+ }
2725+ else if (failmode == FAIL_TERMINATE)
2726+ {
2727+ fprintf(stderr, "cupsd: unable to start auditing, terminating");
2728+ return -1;
2729+ }
2730+ }
2731+ }
2732+#endif /* WITH_LSPP */
2733+
2734 /*
2735 * Set the timezone info...
2736 */
2737@@ -1241,6 +1268,11 @@ main(int argc, /* I - Number of comm
2738
2739 cupsdStopSelect();
2740
2741+#ifdef WITH_LSPP
2742+ if (AuditLog != -1)
2743+ audit_close(AuditLog);
2744+#endif /* WITH_LSPP */
2745+
2746 return (!stop_scheduler);
2747 }
2748
2749diff -up cups-1.4.5/scheduler/printers.c.lspp cups-1.4.5/scheduler/printers.c
2750--- cups-1.4.5/scheduler/printers.c.lspp 2010-12-24 13:21:31.168858518 +0000
2751+++ cups-1.4.5/scheduler/printers.c 2010-12-24 13:21:31.236856747 +0000
2752@@ -59,6 +59,8 @@
2753 * write_xml_string() - Write a string with XML escaping.
2754 */
2755
2756+/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
2757+
2758 /*
2759 * Include necessary headers...
2760 */
2761@@ -103,6 +105,10 @@ static void write_irix_state(cupsd_print
2762 #endif /* __sgi */
2763 static void write_xml_string(cups_file_t *fp, const char *s);
2764
2765+#ifdef WITH_LSPP
2766+# include <libaudit.h>
2767+# include <selinux/context.h>
2768+#endif /* WITH_LSPP */
2769
2770 /*
2771 * 'cupsdAddPrinter()' - Add a printer to the system.
2772@@ -2267,6 +2273,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
2773 "username",
2774 "password"
2775 };
2776+#ifdef WITH_LSPP
2777+ char *audit_message; /* Audit message string */
2778+ char *printerfile; /* Path to a local printer dev */
2779+ char *rangestr; /* Printer's range if its available */
2780+ security_context_t devcon; /* Printer SELinux context */
2781+ context_t printercon; /* context_t for the printer */
2782+#endif /* WITH_LSPP */
2783
2784
2785 DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
2786@@ -2397,6 +2410,45 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
2787 attr->values[1].string.text = _cupsStrAlloc(Classification ?
2788 Classification : p->job_sheets[1]);
2789 }
2790+#ifdef WITH_LSPP
2791+ if (AuditLog != -1)
2792+ {
2793+ audit_message = NULL;
2794+ rangestr = NULL;
2795+ printercon = 0;
2796+ printerfile = strstr(p->device_uri, "/dev/");
2797+ if (printerfile == NULL && (strncmp(p->device_uri, "file:/", 6) == 0))
2798+ printerfile = p->device_uri + strlen("file:");
2799+
2800+ if (printerfile != NULL)
2801+ {
2802+ if (getfilecon(printerfile, &devcon) == -1)
2803+ {
2804+ if(is_selinux_enabled())
2805+ cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdSetPrinterAttrs: Unable to get printer context");
2806+ }
2807+ else
2808+ {
2809+ printercon = context_new(devcon);
2810+ freecon(devcon);
2811+ }
2812+ }
2813+
2814+ if (printercon && context_range_get(printercon))
2815+ rangestr = strdup(context_range_get(printercon));
2816+ else
2817+ rangestr = strdup("unknown");
2818+
2819+ cupsdSetStringf(&audit_message, "printer=%s uri=%s banners=%s,%s range=%s",
2820+ p->name, p->sanitized_device_uri, p->job_sheets[0], p->job_sheets[1], rangestr);
2821+ audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
2822+ ServerName, NULL, NULL, 1);
2823+ if (printercon)
2824+ context_free(printercon);
2825+ free(rangestr);
2826+ cupsdClearString(&audit_message);
2827+ }
2828+#endif /* WITH_LSPP */
2829 }
2830
2831 p->raw = 0;
2832@@ -5536,7 +5588,6 @@ write_irix_state(cupsd_printer_t *p) /*
2833 }
2834 #endif /* __sgi */
2835
2836-
2837 /*
2838 * 'write_xml_string()' - Write a string with XML escaping.
2839 */