]> git.ipfire.org Git - people/stevee/ipfire-3.x.git/blob - pkgs/cups/patches/cups-x-lspp.patch
380b55d02d54fa537d7b5cf40d38d4844259f3d8
[people/stevee/ipfire-3.x.git] / pkgs / cups / patches / cups-x-lspp.patch
1 diff -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
17 diff -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
57 diff -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=""
69 diff -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 */
95 diff -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 \
110 diff -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
375 diff -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
640 diff -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
905 diff -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 /*
1076 diff -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 /*
1234 diff -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:
1255 diff -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 */
1478 diff -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 /*
1516 diff -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.
1628 diff -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...
1654 diff -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 */
2254 diff -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 */
2651 diff -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 ****/
2679 diff -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
2749 diff -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 */