]>
Commit | Line | Data |
---|---|---|
1f9b7ef8 KB |
1 | diff -up cups-1.6b1/config.h.in.lspp cups-1.6b1/config.h.in |
2 | --- cups-1.6b1/config.h.in.lspp 2012-05-25 17:01:32.000000000 +0200 | |
3 | +++ cups-1.6b1/config.h.in 2012-05-25 17:03:16.889043298 +0200 | |
4 | @@ -768,6 +768,13 @@ static __inline int _cups_abs(int i) { r | |
5 | # endif /* __GNUC__ || __STDC_VERSION__ */ | |
6 | #endif /* !HAVE_ABS && !abs */ | |
f92713d3 SS |
7 | |
8 | +/* | |
9 | + * Are we trying to meet LSPP requirements? | |
10 | + */ | |
11 | + | |
12 | +#undef WITH_LSPP | |
13 | + | |
1f9b7ef8 | 14 | + |
f92713d3 SS |
15 | #endif /* !_CUPS_CONFIG_H_ */ |
16 | ||
1f9b7ef8 KB |
17 | /* |
18 | diff -up cups-1.6b1/config-scripts/cups-lspp.m4.lspp cups-1.6b1/config-scripts/cups-lspp.m4 | |
19 | --- cups-1.6b1/config-scripts/cups-lspp.m4.lspp 2012-05-25 17:01:32.852768495 +0200 | |
20 | +++ cups-1.6b1/config-scripts/cups-lspp.m4 2012-05-25 17:01:32.853768488 +0200 | |
f92713d3 SS |
21 | @@ -0,0 +1,36 @@ |
22 | +dnl | |
23 | +dnl LSPP code for the Common UNIX Printing System (CUPS). | |
24 | +dnl | |
25 | +dnl Copyright 2005-2006 by Hewlett-Packard Development Company, L.P. | |
26 | +dnl | |
27 | +dnl This program is free software; you can redistribute it and/or modify | |
28 | +dnl it under the terms of the GNU General Public License as published by | |
29 | +dnl the Free Software Foundation; version 2. | |
30 | +dnl | |
31 | +dnl This program is distributed in the hope that it will be useful, but | |
32 | +dnl WITHOUT ANY WARRANTY; without even the implied warranty of | |
33 | +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
34 | +dnl General Public License for more details. | |
35 | +dnl | |
36 | +dnl You should have received a copy of the GNU General Public License | |
37 | +dnl along with this program; if not, write to the Free Software Foundation, | |
38 | +dnl Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA | |
39 | +dnl | |
40 | + | |
41 | +dnl Are we trying to meet LSPP requirements | |
42 | +AC_ARG_ENABLE(lspp, [ --enable-lspp turn on auditing and label support, default=no]) | |
43 | + | |
44 | +if test x"$enable_lspp" != xno; then | |
45 | + case "$uname" in | |
46 | + Linux) | |
47 | + AC_CHECK_LIB(audit,audit_log_user_message, [LIBAUDIT="-laudit" AC_SUBST(LIBAUDIT)]) | |
48 | + AC_CHECK_HEADER(libaudit.h) | |
49 | + AC_CHECK_LIB(selinux,getpeercon, [LIBSELINUX="-lselinux" AC_SUBST(LIBSELINUX)]) | |
50 | + AC_CHECK_HEADER(selinux/selinux.h) | |
51 | + AC_DEFINE(WITH_LSPP) | |
52 | + ;; | |
53 | + *) | |
54 | + # All others | |
55 | + ;; | |
56 | + esac | |
57 | +fi | |
1f9b7ef8 KB |
58 | diff -up cups-1.6b1/configure.in.lspp cups-1.6b1/configure.in |
59 | --- cups-1.6b1/configure.in.lspp 2012-05-25 17:01:32.000000000 +0200 | |
60 | +++ cups-1.6b1/configure.in 2012-05-25 17:04:03.994714943 +0200 | |
61 | @@ -37,6 +37,8 @@ sinclude(config-scripts/cups-systemd.m4) | |
62 | sinclude(config-scripts/cups-defaults.m4) | |
f92713d3 SS |
63 | sinclude(config-scripts/cups-scripting.m4) |
64 | ||
65 | +sinclude(config-scripts/cups-lspp.m4) | |
66 | + | |
67 | INSTALL_LANGUAGES="" | |
68 | UNINSTALL_LANGUAGES="" | |
69 | LANGFILES="" | |
1f9b7ef8 KB |
70 | diff -up cups-1.6b1/filter/common.c.lspp cups-1.6b1/filter/common.c |
71 | --- cups-1.6b1/filter/common.c.lspp 2011-05-20 05:49:49.000000000 +0200 | |
72 | +++ cups-1.6b1/filter/common.c 2012-05-25 17:01:32.854768481 +0200 | |
f92713d3 SS |
73 | @@ -30,6 +30,12 @@ |
74 | * Include necessary headers... | |
75 | */ | |
76 | ||
77 | +#include "config.h" | |
78 | +#ifdef WITH_LSPP | |
79 | +#define _GNU_SOURCE | |
80 | +#include <string.h> | |
81 | +#endif /* WITH_LSPP */ | |
82 | + | |
83 | #include "common.h" | |
84 | #include <locale.h> | |
85 | ||
86 | @@ -312,6 +318,18 @@ WriteLabelProlog(const char *label, /* I | |
87 | { | |
88 | const char *classification; /* CLASSIFICATION environment variable */ | |
89 | const char *ptr; /* Temporary string pointer */ | |
90 | +#ifdef WITH_LSPP | |
91 | + int i, /* counter */ | |
92 | + n, /* counter */ | |
93 | + lines, /* number of lines needed */ | |
94 | + line_len, /* index into tmp_label */ | |
95 | + label_len, /* length of the label in characters */ | |
96 | + label_index, /* index into the label */ | |
97 | + longest, /* length of the longest line */ | |
98 | + longest_line, /* index to the longest line */ | |
99 | + max_width; /* maximum width in characters */ | |
100 | + char **wrapped_label; /* label with line breaks */ | |
101 | +#endif /* WITH_LSPP */ | |
102 | ||
103 | ||
104 | /* | |
105 | @@ -334,6 +352,124 @@ WriteLabelProlog(const char *label, /* I | |
106 | return; | |
107 | } | |
108 | ||
109 | +#ifdef WITH_LSPP | |
110 | + if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL) | |
111 | + { | |
112 | + /* | |
113 | + * Based on the 12pt fixed width font below determine the max_width | |
114 | + */ | |
115 | + max_width = width / 8; | |
116 | + longest_line = 0; | |
117 | + longest = 0; | |
118 | + classification += 5; // Skip the "LSPP:" | |
119 | + label_len = strlen(classification); | |
120 | + | |
121 | + if (label_len > max_width) | |
122 | + { | |
123 | + lines = 1 + (int)(label_len / max_width); | |
124 | + line_len = (int)(label_len / lines); | |
1f9b7ef8 | 125 | + wrapped_label = malloc(sizeof(*wrapped_label) * lines); |
f92713d3 SS |
126 | + label_index = i = n = 0; |
127 | + while (classification[label_index]) | |
128 | + { | |
129 | + if ((label_index + line_len) > label_len) | |
130 | + break; | |
131 | + switch (classification[label_index + line_len + i]) | |
132 | + { | |
133 | + case ':': | |
134 | + case ',': | |
135 | + case '-': | |
136 | + i++; | |
137 | + wrapped_label[n++] = strndup(&classification[label_index], (line_len + i)); | |
138 | + label_index += line_len + i; | |
139 | + i = 0; | |
140 | + break; | |
141 | + default: | |
142 | + i++; | |
143 | + break; | |
144 | + } | |
145 | + if ((i + line_len) == max_width) | |
146 | + { | |
147 | + wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i)); | |
148 | + label_index = label_index + line_len + i; | |
149 | + i = 0; | |
150 | + } | |
151 | + } | |
152 | + wrapped_label[n] = strndup(&classification[label_index], label_len - label_index); | |
153 | + } | |
154 | + else | |
155 | + { | |
156 | + lines = 1; | |
1f9b7ef8 | 157 | + wrapped_label = malloc(sizeof(*wrapped_label)); |
f92713d3 SS |
158 | + wrapped_label[0] = (char*)classification; |
159 | + } | |
160 | + | |
161 | + for (n = 0; n < lines; n++ ) | |
162 | + { | |
163 | + printf("userdict/ESPp%c(", ('a' + n)); | |
164 | + for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++) | |
165 | + if (*ptr < 32 || *ptr > 126) | |
166 | + printf("\\%03o", *ptr); | |
167 | + else | |
168 | + { | |
169 | + if (*ptr == '(' || *ptr == ')' || *ptr == '\\') | |
170 | + putchar('\\'); | |
171 | + | |
172 | + printf("%c", *ptr); | |
173 | + } | |
174 | + if (i > longest) | |
175 | + { | |
176 | + longest = i; | |
177 | + longest_line = n; | |
178 | + } | |
179 | + printf(")put\n"); | |
180 | + } | |
181 | + | |
182 | + /* | |
183 | + * For LSPP use a fixed width font so that line wrapping can be calculated | |
184 | + */ | |
185 | + | |
186 | + puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put"); | |
187 | + | |
188 | + /* | |
189 | + * Finally, the procedure to write the labels on the page... | |
190 | + */ | |
191 | + | |
192 | + printf("userdict/ESPwl{\n" | |
193 | + " ESPlf setfont\n"); | |
194 | + printf(" ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ", | |
195 | + 'a' + longest_line, width * 0.5f); | |
196 | + for (n = 1; n < lines; n++) | |
197 | + printf(" dup"); | |
198 | + printf("\n 1 setgray\n"); | |
199 | + printf(" dup 6 sub %.0f %d index %.0f ESPrf\n", | |
200 | + (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines)); | |
201 | + printf(" dup 6 sub %.0f %d index %.0f ESPrf\n", | |
202 | + (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines)); | |
203 | + printf(" 0 setgray\n"); | |
204 | + printf(" dup 6 sub %.0f %d index %.0f ESPrs\n", | |
205 | + (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines)); | |
206 | + printf(" dup 6 sub %.0f %d index %.0f ESPrs\n", | |
207 | + (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines)); | |
208 | + for (n = 0; n < lines; n ++) | |
209 | + { | |
210 | + printf(" dup %.0f moveto ESPp%c show\n", | |
211 | + bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n); | |
212 | + printf(" %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n); | |
213 | + } | |
214 | + printf(" pop\n" | |
215 | + "}bind put\n"); | |
216 | + | |
217 | + /* | |
218 | + * Do some clean up at the end of the LSPP special case | |
219 | + */ | |
220 | + free(wrapped_label); | |
221 | + | |
222 | + } | |
223 | + else | |
224 | + { | |
225 | +#endif /* !WITH_LSPP */ | |
226 | + | |
227 | /* | |
228 | * Set the classification + page label string... | |
229 | */ | |
230 | @@ -414,7 +550,10 @@ WriteLabelProlog(const char *label, /* I | |
231 | printf(" %.0f moveto ESPpl show\n", top - 14.0); | |
232 | puts("pop"); | |
233 | puts("}bind put"); | |
234 | + } | |
235 | +#ifdef WITH_LSPP | |
236 | } | |
237 | +#endif /* WITH_LSPP */ | |
238 | ||
239 | ||
240 | /* | |
1f9b7ef8 KB |
241 | diff -up cups-1.6b1/filter/pstops.c.lspp cups-1.6b1/filter/pstops.c |
242 | --- cups-1.6b1/filter/pstops.c.lspp 2012-04-23 21:19:19.000000000 +0200 | |
243 | +++ cups-1.6b1/filter/pstops.c 2012-05-25 17:01:32.855768474 +0200 | |
244 | @@ -3202,6 +3202,18 @@ write_label_prolog(pstops_doc_t *doc, /* | |
f92713d3 SS |
245 | { |
246 | const char *classification; /* CLASSIFICATION environment variable */ | |
247 | const char *ptr; /* Temporary string pointer */ | |
248 | +#ifdef WITH_LSPP | |
249 | + int i, /* counter */ | |
250 | + n, /* counter */ | |
251 | + lines, /* number of lines needed */ | |
252 | + line_len, /* index into tmp_label */ | |
253 | + label_len, /* length of the label in characters */ | |
254 | + label_index, /* index into the label */ | |
255 | + longest, /* length of the longest line */ | |
256 | + longest_line, /* index to the longest line */ | |
257 | + max_width; /* maximum width in characters */ | |
258 | + char **wrapped_label; /* label with line breaks */ | |
259 | +#endif /* WITH_LSPP */ | |
260 | ||
261 | ||
262 | /* | |
1f9b7ef8 | 263 | @@ -3224,6 +3236,124 @@ write_label_prolog(pstops_doc_t *doc, /* |
f92713d3 SS |
264 | return; |
265 | } | |
266 | ||
267 | +#ifdef WITH_LSPP | |
268 | + if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL) | |
269 | + { | |
270 | + /* | |
271 | + * Based on the 12pt fixed width font below determine the max_width | |
272 | + */ | |
273 | + max_width = width / 8; | |
274 | + longest_line = 0; | |
275 | + longest = 0; | |
276 | + classification += 5; // Skip the "LSPP:" | |
277 | + label_len = strlen(classification); | |
278 | + | |
279 | + if (label_len > max_width) | |
280 | + { | |
281 | + lines = 1 + (int)(label_len / max_width); | |
282 | + line_len = (int)(label_len / lines); | |
1f9b7ef8 | 283 | + wrapped_label = malloc(sizeof(*wrapped_label) * lines); |
f92713d3 SS |
284 | + label_index = i = n = 0; |
285 | + while (classification[label_index]) | |
286 | + { | |
287 | + if ((label_index + line_len) > label_len) | |
288 | + break; | |
289 | + switch (classification[label_index + line_len + i]) | |
290 | + { | |
291 | + case ':': | |
292 | + case ',': | |
293 | + case '-': | |
294 | + i++; | |
295 | + wrapped_label[n++] = strndup(&classification[label_index], (line_len + i)); | |
296 | + label_index += line_len + i; | |
297 | + i = 0; | |
298 | + break; | |
299 | + default: | |
300 | + i++; | |
301 | + break; | |
302 | + } | |
303 | + if ((i + line_len) == max_width) | |
304 | + { | |
305 | + wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i)); | |
306 | + label_index = label_index + line_len + i; | |
307 | + i = 0; | |
308 | + } | |
309 | + } | |
310 | + wrapped_label[n] = strndup(&classification[label_index], label_len - label_index); | |
311 | + } | |
312 | + else | |
313 | + { | |
314 | + lines = 1; | |
1f9b7ef8 | 315 | + wrapped_label = malloc(sizeof(*wrapped_label)); |
f92713d3 SS |
316 | + wrapped_label[0] = (char*)classification; |
317 | + } | |
318 | + | |
319 | + for (n = 0; n < lines; n++ ) | |
320 | + { | |
321 | + printf("userdict/ESPp%c(", ('a' + n)); | |
322 | + for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++) | |
323 | + if (*ptr < 32 || *ptr > 126) | |
324 | + printf("\\%03o", *ptr); | |
325 | + else | |
326 | + { | |
327 | + if (*ptr == '(' || *ptr == ')' || *ptr == '\\') | |
328 | + putchar('\\'); | |
329 | + | |
330 | + printf("%c", *ptr); | |
331 | + } | |
332 | + if (i > longest) | |
333 | + { | |
334 | + longest = i; | |
335 | + longest_line = n; | |
336 | + } | |
337 | + printf(")put\n"); | |
338 | + } | |
339 | + | |
340 | + /* | |
341 | + * For LSPP use a fixed width font so that line wrapping can be calculated | |
342 | + */ | |
343 | + | |
344 | + puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put"); | |
345 | + | |
346 | + /* | |
347 | + * Finally, the procedure to write the labels on the page... | |
348 | + */ | |
349 | + | |
350 | + printf("userdict/ESPwl{\n" | |
351 | + " ESPlf setfont\n"); | |
352 | + printf(" ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ", | |
353 | + 'a' + longest_line, width * 0.5f); | |
354 | + for (n = 1; n < lines; n++) | |
355 | + printf(" dup"); | |
356 | + printf("\n 1 setgray\n"); | |
357 | + printf(" dup 6 sub %.0f %d index %.0f ESPrf\n", | |
358 | + (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines)); | |
359 | + printf(" dup 6 sub %.0f %d index %.0f ESPrf\n", | |
360 | + (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines)); | |
361 | + printf(" 0 setgray\n"); | |
362 | + printf(" dup 6 sub %.0f %d index %.0f ESPrs\n", | |
363 | + (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines)); | |
364 | + printf(" dup 6 sub %.0f %d index %.0f ESPrs\n", | |
365 | + (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines)); | |
366 | + for (n = 0; n < lines; n ++) | |
367 | + { | |
368 | + printf(" dup %.0f moveto ESPp%c show\n", | |
369 | + bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n); | |
370 | + printf(" %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n); | |
371 | + } | |
372 | + printf(" pop\n" | |
373 | + "}bind put\n"); | |
374 | + | |
375 | + /* | |
376 | + * Do some clean up at the end of the LSPP special case | |
377 | + */ | |
378 | + free(wrapped_label); | |
379 | + | |
380 | + } | |
381 | + else | |
382 | + { | |
383 | +#endif /* !WITH_LSPP */ | |
384 | + | |
385 | /* | |
386 | * Set the classification + page label string... | |
387 | */ | |
1f9b7ef8 | 388 | @@ -3302,7 +3432,10 @@ write_label_prolog(pstops_doc_t *doc, /* |
f92713d3 SS |
389 | doc_printf(doc, " %.0f moveto ESPpl show\n", top - 14.0); |
390 | doc_puts(doc, "pop\n"); | |
391 | doc_puts(doc, "}bind put\n"); | |
392 | + } | |
393 | +#ifdef WITH_LSPP | |
394 | } | |
395 | +#endif /* WITH_LSPP */ | |
396 | ||
397 | ||
398 | /* | |
1f9b7ef8 KB |
399 | diff -up cups-1.6b1/Makedefs.in.lspp cups-1.6b1/Makedefs.in |
400 | --- cups-1.6b1/Makedefs.in.lspp 2012-05-25 17:01:32.000000000 +0200 | |
401 | +++ cups-1.6b1/Makedefs.in 2012-05-25 17:07:57.325088484 +0200 | |
402 | @@ -146,7 +146,7 @@ LDFLAGS = -L../cgi-bin -L../cups -L../f | |
403 | @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM) | |
404 | LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ) | |
f92713d3 SS |
405 | LINKCUPSIMAGE = @LINKCUPSIMAGE@ |
406 | -LIBS = $(LINKCUPS) $(COMMONLIBS) | |
407 | +LIBS = $(LINKCUPS) $(COMMONLIBS) @LIBAUDIT@ @LIBSELINUX@ | |
408 | OPTIM = @OPTIM@ | |
409 | OPTIONS = | |
410 | PAMLIBS = @PAMLIBS@ | |
1f9b7ef8 KB |
411 | diff -up cups-1.6b1/scheduler/client.c.lspp cups-1.6b1/scheduler/client.c |
412 | --- cups-1.6b1/scheduler/client.c.lspp 2012-05-08 00:41:30.000000000 +0200 | |
413 | +++ cups-1.6b1/scheduler/client.c 2012-05-25 17:13:38.947707163 +0200 | |
414 | @@ -41,6 +41,7 @@ | |
415 | * valid_host() - Is the Host: field valid? | |
416 | * write_file() - Send a file via HTTP. | |
417 | * write_pipe() - Flag that data is available on the CGI pipe. | |
f92713d3 SS |
418 | + * client_pid_to_auid() - Get the audit login uid of the client. |
419 | */ | |
420 | ||
421 | /* | |
1f9b7ef8 | 422 | @@ -49,10 +50,16 @@ |
f92713d3 SS |
423 | |
424 | #include "cupsd.h" | |
425 | ||
426 | +#define _GNU_SOURCE | |
1f9b7ef8 | 427 | #ifdef HAVE_TCPD_H |
f92713d3 SS |
428 | # include <tcpd.h> |
429 | #endif /* HAVE_TCPD_H */ | |
430 | ||
431 | +#ifdef WITH_LSPP | |
432 | +#include <selinux/selinux.h> | |
433 | +#include <selinux/context.h> | |
434 | +#include <fcntl.h> | |
435 | +#endif /* WITH_LSPP */ | |
f92713d3 SS |
436 | |
437 | /* | |
1f9b7ef8 KB |
438 | * Local globals... |
439 | @@ -371,6 +378,57 @@ cupsdAcceptClient(cupsd_listener_t *lis) | |
f92713d3 SS |
440 | } |
441 | #endif /* HAVE_TCPD_H */ | |
442 | ||
443 | +#ifdef WITH_LSPP | |
444 | + if (is_lspp_config()) | |
445 | + { | |
446 | + struct ucred cr; | |
447 | + unsigned int cl=sizeof(cr); | |
448 | + | |
449 | + if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0) | |
450 | + { | |
451 | + /* | |
452 | + * client_pid_to_auid() can be racey | |
453 | + * In this case the pid is based on a socket connected to the client | |
454 | + */ | |
455 | + if ((con->auid = client_pid_to_auid(cr.pid)) == -1) | |
456 | + { | |
457 | + close(con->http.fd); | |
458 | + cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: " | |
459 | + "unable to determine client auid for client pid=%d", cr.pid); | |
460 | + free(con); | |
461 | + return; | |
462 | + } | |
463 | + cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: peer's pid=%d, uid=%d, gid=%d, auid=%d", | |
464 | + cr.pid, cr.uid, cr.gid, con->auid); | |
465 | + } | |
466 | + else | |
467 | + { | |
468 | + close(con->http.fd); | |
469 | + cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getsockopt() failed"); | |
470 | + free(con); | |
471 | + return; | |
472 | + } | |
473 | + | |
474 | + /* | |
475 | + * get the context of the peer connection | |
476 | + */ | |
477 | + if (getpeercon(con->http.fd, &con->scon)) | |
478 | + { | |
479 | + close(con->http.fd); | |
480 | + cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getpeercon() failed"); | |
481 | + free(con); | |
482 | + return; | |
483 | + } | |
484 | + | |
485 | + cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: client context=%s", con->scon); | |
486 | + } | |
487 | + else | |
488 | + { | |
489 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: skipping getpeercon()"); | |
490 | + cupsdSetString(&con->scon, UNKNOWN_SL); | |
491 | + } | |
492 | +#endif /* WITH_LSPP */ | |
493 | + | |
1f9b7ef8 KB |
494 | #ifdef AF_LOCAL |
495 | if (con->http.hostaddr->addr.sa_family == AF_LOCAL) | |
496 | cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)", | |
497 | @@ -678,6 +736,13 @@ cupsdReadClient(cupsd_client_t *con) /* | |
f92713d3 SS |
498 | mime_type_t *type; /* MIME type of file */ |
499 | cupsd_printer_t *p; /* Printer */ | |
500 | static unsigned request_id = 0; /* Request ID for temp files */ | |
501 | +#ifdef WITH_LSPP | |
502 | + security_context_t spoolcon; /* context of the job file */ | |
503 | + context_t clicon; /* contex_t container for con->scon */ | |
504 | + context_t tmpcon; /* temp context to swap the level */ | |
505 | + char *clirange; /* SELinux sensitivity range */ | |
506 | + char *cliclearance; /* SELinux low end clearance */ | |
507 | +#endif /* WITH_LSPP */ | |
508 | ||
509 | ||
510 | status = HTTP_CONTINUE; | |
1f9b7ef8 | 511 | @@ -2126,6 +2191,67 @@ cupsdReadClient(cupsd_client_t *con) /* |
f92713d3 SS |
512 | fchmod(con->file, 0640); |
513 | fchown(con->file, RunUser, Group); | |
514 | fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); | |
515 | +#ifdef WITH_LSPP | |
516 | + if (strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0) | |
517 | + { | |
518 | + if (getfilecon(con->filename, &spoolcon) == -1) | |
519 | + { | |
520 | + cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE); | |
521 | + return (cupsdCloseClient(con)); | |
522 | + } | |
523 | + clicon = context_new(con->scon); | |
524 | + tmpcon = context_new(spoolcon); | |
525 | + freecon(spoolcon); | |
526 | + if (!clicon || !tmpcon) | |
527 | + { | |
528 | + cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE); | |
529 | + if (clicon) | |
530 | + context_free(clicon); | |
531 | + if (tmpcon) | |
532 | + context_free(tmpcon); | |
533 | + return (cupsdCloseClient(con)); | |
534 | + } | |
535 | + clirange = context_range_get(clicon); | |
536 | + if (clirange) | |
537 | + { | |
538 | + clirange = strdup(clirange); | |
539 | + if ((cliclearance = strtok(clirange, "-")) != NULL) | |
540 | + { | |
541 | + if (context_range_set(tmpcon, cliclearance) == -1) | |
542 | + { | |
543 | + cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE); | |
544 | + free(clirange); | |
545 | + context_free(tmpcon); | |
546 | + context_free(clicon); | |
547 | + return (cupsdCloseClient(con)); | |
548 | + } | |
549 | + } | |
550 | + else | |
551 | + { | |
552 | + if (context_range_set(tmpcon, (context_range_get(clicon))) == -1) | |
553 | + { | |
554 | + cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE); | |
555 | + free(clirange); | |
556 | + context_free(tmpcon); | |
557 | + context_free(clicon); | |
558 | + return (cupsdCloseClient(con)); | |
559 | + } | |
560 | + } | |
561 | + free(clirange); | |
562 | + } | |
563 | + if (setfilecon(con->filename, context_str(tmpcon)) == -1) | |
564 | + { | |
565 | + cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE); | |
566 | + context_free(tmpcon); | |
567 | + context_free(clicon); | |
568 | + return (cupsdCloseClient(con)); | |
569 | + } | |
570 | + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: %s set to %s", | |
571 | + con->filename, context_str(tmpcon)); | |
572 | + context_free(tmpcon); | |
573 | + context_free(clicon); | |
574 | + } | |
575 | +#endif /* WITH_LSPP */ | |
576 | } | |
577 | ||
578 | if (con->http.state != HTTP_POST_SEND) | |
1f9b7ef8 KB |
579 | @@ -3581,6 +3707,49 @@ is_path_absolute(const char *path) /* I |
580 | return (1); | |
581 | } | |
f92713d3 SS |
582 | |
583 | +#ifdef WITH_LSPP | |
584 | +/* | |
585 | + * 'client_pid_to_auid()' - Using the client's pid, read /proc and determine the loginuid. | |
586 | + */ | |
587 | + | |
588 | +uid_t client_pid_to_auid(pid_t clipid) | |
589 | +{ | |
590 | + uid_t uid; | |
591 | + int len, in; | |
592 | + char buf[16] = {0}; | |
593 | + char fname[32] = {0}; | |
594 | + | |
595 | + | |
596 | + /* | |
597 | + * Hopefully this pid is still the one we are interested in. | |
598 | + */ | |
599 | + snprintf(fname, 32, "/proc/%d/loginuid", clipid); | |
600 | + in = open(fname, O_NOFOLLOW|O_RDONLY); | |
601 | + | |
602 | + if (in < 0) | |
603 | + return -1; | |
604 | + | |
605 | + errno = 0; | |
606 | + | |
607 | + do { | |
608 | + len = read(in, buf, sizeof(buf)); | |
609 | + } while (len < 0 && errno == EINTR); | |
610 | + | |
611 | + close(in); | |
612 | + | |
613 | + if (len < 0 || len >= sizeof(buf)) | |
614 | + return -1; | |
615 | + | |
616 | + errno = 0; | |
617 | + buf[len] = 0; | |
618 | + uid = strtol(buf, 0, 10); | |
619 | + | |
620 | + if (errno != 0) | |
621 | + return -1; | |
622 | + else | |
623 | + return uid; | |
624 | +} | |
625 | +#endif /* WITH_LSPP */ | |
1f9b7ef8 | 626 | |
f92713d3 SS |
627 | /* |
628 | * 'pipe_command()' - Pipe the output of a command to the remote client. | |
1f9b7ef8 KB |
629 | diff -up cups-1.6b1/scheduler/client.h.lspp cups-1.6b1/scheduler/client.h |
630 | --- cups-1.6b1/scheduler/client.h.lspp 2012-05-25 17:01:32.847768530 +0200 | |
631 | +++ cups-1.6b1/scheduler/client.h 2012-05-25 17:14:12.963470050 +0200 | |
f92713d3 SS |
632 | @@ -18,6 +18,13 @@ |
633 | #endif /* HAVE_AUTHORIZATION_H */ | |
634 | ||
635 | ||
636 | +/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */ | |
637 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
638 | + | |
639 | +#ifdef WITH_LSPP | |
640 | +#include <selinux/selinux.h> | |
641 | +#endif /* WITH_LSPP */ | |
642 | + | |
643 | /* | |
644 | * HTTP client structure... | |
645 | */ | |
1f9b7ef8 | 646 | @@ -63,6 +70,10 @@ struct cupsd_client_s |
f92713d3 SS |
647 | #ifdef HAVE_AUTHORIZATION_H |
648 | AuthorizationRef authref; /* Authorization ref */ | |
649 | #endif /* HAVE_AUTHORIZATION_H */ | |
650 | +#ifdef WITH_LSPP | |
651 | + security_context_t scon; /* Security context of connection */ | |
652 | + uid_t auid; /* Audit loginuid of the client */ | |
653 | +#endif /* WITH_LSPP */ | |
654 | }; | |
655 | ||
656 | #define HTTP(con) &((con)->http) | |
1f9b7ef8 | 657 | @@ -135,6 +146,9 @@ extern void cupsdStartListening(void); |
f92713d3 SS |
658 | extern void cupsdStopListening(void); |
659 | extern void cupsdUpdateCGI(void); | |
660 | extern void cupsdWriteClient(cupsd_client_t *con); | |
661 | +#ifdef WITH_LSPP | |
662 | +extern uid_t client_pid_to_auid(pid_t clipid); | |
663 | +#endif /* WITH_LSPP */ | |
664 | ||
1f9b7ef8 KB |
665 | #ifdef HAVE_SSL |
666 | extern int cupsdEndTLS(cupsd_client_t *con); | |
667 | diff -up cups-1.6b1/scheduler/conf.c.lspp cups-1.6b1/scheduler/conf.c | |
668 | --- cups-1.6b1/scheduler/conf.c.lspp 2012-05-25 17:01:32.778769011 +0200 | |
669 | +++ cups-1.6b1/scheduler/conf.c 2012-05-25 17:01:32.860768439 +0200 | |
670 | @@ -32,6 +32,7 @@ | |
f92713d3 SS |
671 | * read_location() - Read a <Location path> definition. |
672 | * read_policy() - Read a <Policy name> definition. | |
1f9b7ef8 | 673 | * set_policy_defaults() - Set default policy values as needed. |
f92713d3 SS |
674 | + * is_lspp_config() - Is the system configured for LSPP |
675 | */ | |
676 | ||
677 | /* | |
1f9b7ef8 | 678 | @@ -57,6 +58,9 @@ |
f92713d3 SS |
679 | # define INADDR_NONE 0xffffffff |
680 | #endif /* !INADDR_NONE */ | |
681 | ||
682 | +#ifdef WITH_LSPP | |
683 | +# include <libaudit.h> | |
684 | +#endif /* WITH_LSPP */ | |
685 | ||
686 | /* | |
687 | * Configuration variable structure... | |
1f9b7ef8 | 688 | @@ -164,6 +168,10 @@ static const cupsd_var_t variables[] = |
f92713d3 SS |
689 | # if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) |
690 | { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME }, | |
691 | # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ | |
692 | +#ifdef WITH_LSPP | |
693 | + { "AuditLog", &AuditLog, CUPSD_VARTYPE_INTEGER }, | |
694 | + { "PerPageLabels", &PerPageLabels, CUPSD_VARTYPE_BOOLEAN }, | |
695 | +#endif /* WITH_LSPP */ | |
696 | #endif /* HAVE_SSL */ | |
697 | { "ServerName", &ServerName, CUPSD_VARTYPE_STRING }, | |
698 | { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME }, | |
1f9b7ef8 | 699 | @@ -537,6 +545,9 @@ cupsdReadConfiguration(void) |
f92713d3 SS |
700 | const char *tmpdir; /* TMPDIR environment variable */ |
701 | struct stat tmpinfo; /* Temporary directory info */ | |
702 | cupsd_policy_t *p; /* Policy */ | |
703 | +#ifdef WITH_LSPP | |
704 | + char *audit_message; /* Audit message string */ | |
705 | +#endif /* WITH_LSPP */ | |
706 | ||
707 | ||
708 | /* | |
1f9b7ef8 | 709 | @@ -801,6 +812,25 @@ cupsdReadConfiguration(void) |
f92713d3 SS |
710 | |
711 | RunUser = getuid(); | |
712 | ||
713 | +#ifdef WITH_LSPP | |
714 | + if (AuditLog != -1) | |
715 | + { | |
716 | + /* | |
717 | + * ClassifyOverride is set during read_configuration, if its ON, report it now | |
718 | + */ | |
719 | + if (ClassifyOverride) | |
720 | + audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG, | |
721 | + "[Config] ClassifyOverride=enabled Users can override print banners", | |
722 | + ServerName, NULL, NULL, 1); | |
723 | + /* | |
724 | + * PerPageLabel is set during read_configuration, if its OFF, report it now | |
725 | + */ | |
726 | + if (!PerPageLabels) | |
727 | + audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG, | |
728 | + "[Config] PerPageLabels=disabled", ServerName, NULL, NULL, 1); | |
729 | + } | |
730 | +#endif /* WITH_LSPP */ | |
731 | + | |
732 | cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.", | |
733 | RemotePort ? "enabled" : "disabled"); | |
734 | ||
1f9b7ef8 | 735 | @@ -1185,7 +1215,19 @@ cupsdReadConfiguration(void) |
f92713d3 SS |
736 | cupsdClearString(&Classification); |
737 | ||
738 | if (Classification) | |
739 | + { | |
740 | cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification); | |
741 | +#ifdef WITH_LSPP | |
742 | + if (AuditLog != -1) | |
743 | + { | |
744 | + audit_message = NULL; | |
745 | + cupsdSetStringf(&audit_message, "[Config] Classification=%s", Classification); | |
746 | + audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message, | |
747 | + ServerName, NULL, NULL, 1); | |
748 | + cupsdClearString(&audit_message); | |
749 | + } | |
750 | +#endif /* WITH_LSPP */ | |
751 | + } | |
752 | ||
753 | /* | |
754 | * Check the MaxClients setting, and then allocate memory for it... | |
1f9b7ef8 | 755 | @@ -3423,6 +3465,18 @@ read_location(cups_file_t *fp, /* I - C |
f92713d3 SS |
756 | return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum); |
757 | } | |
758 | ||
759 | +#ifdef WITH_LSPP | |
760 | +int is_lspp_config() | |
761 | +{ | |
762 | + if (Classification != NULL) | |
1f9b7ef8 KB |
763 | + return ((_cups_strcasecmp(Classification, MLS_CONFIG) == 0) |
764 | + || (_cups_strcasecmp(Classification, TE_CONFIG) == 0) | |
765 | + || (_cups_strcasecmp(Classification, SELINUX_CONFIG) == 0)); | |
f92713d3 SS |
766 | + else |
767 | + return 0; | |
768 | +} | |
769 | +#endif /* WITH_LSPP */ | |
770 | + | |
771 | ||
772 | /* | |
773 | * 'read_policy()' - Read a <Policy name> definition. | |
1f9b7ef8 KB |
774 | diff -up cups-1.6b1/scheduler/conf.h.lspp cups-1.6b1/scheduler/conf.h |
775 | --- cups-1.6b1/scheduler/conf.h.lspp 2012-05-25 17:01:32.000000000 +0200 | |
776 | +++ cups-1.6b1/scheduler/conf.h 2012-05-25 17:16:20.522580884 +0200 | |
777 | @@ -247,6 +247,13 @@ VAR int SSLOptions VALUE(CUPSD_SSL_NO | |
f92713d3 SS |
778 | /* SSL/TLS options */ |
779 | #endif /* HAVE_SSL */ | |
1f9b7ef8 | 780 | |
f92713d3 SS |
781 | +#ifdef WITH_LSPP |
782 | +VAR int AuditLog VALUE(-1), | |
783 | + /* File descriptor for audit */ | |
784 | + PerPageLabels VALUE(TRUE); | |
785 | + /* Put the label on each page */ | |
786 | +#endif /* WITH_LSPP */ | |
1f9b7ef8 | 787 | + |
f92713d3 | 788 | #ifdef HAVE_LAUNCHD |
1f9b7ef8 KB |
789 | VAR int LaunchdTimeout VALUE(10); |
790 | /* Time after which an idle cupsd will exit */ | |
791 | @@ -265,6 +272,9 @@ int HaveServerCreds VALUE(0); | |
792 | gss_cred_id_t ServerCreds; /* Server's GSS credentials */ | |
793 | #endif /* HAVE_GSSAPI */ | |
f92713d3 SS |
794 | |
795 | +#ifdef WITH_LSPP | |
1f9b7ef8 | 796 | +extern int is_lspp_config(void); |
f92713d3 SS |
797 | +#endif /* WITH_LSPP */ |
798 | ||
799 | /* | |
800 | * Prototypes... | |
1f9b7ef8 KB |
801 | diff -up cups-1.6b1/scheduler/cupsd.h.lspp cups-1.6b1/scheduler/cupsd.h |
802 | --- cups-1.6b1/scheduler/cupsd.h.lspp 2012-05-21 19:40:22.000000000 +0200 | |
803 | +++ cups-1.6b1/scheduler/cupsd.h 2012-05-25 17:01:32.861768432 +0200 | |
804 | @@ -13,6 +13,8 @@ | |
805 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
806 | */ | |
807 | ||
808 | +/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */ | |
809 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
810 | ||
811 | /* | |
812 | * Include necessary headers. | |
813 | @@ -37,13 +39,20 @@ | |
814 | # include <unistd.h> | |
815 | #endif /* WIN32 */ | |
816 | ||
817 | +#include "config.h" | |
818 | +#ifdef WITH_LSPP | |
819 | +# define MLS_CONFIG "mls" | |
820 | +# define TE_CONFIG "te" | |
821 | +# define SELINUX_CONFIG "SELinux" | |
822 | +# define UNKNOWN_SL "UNKNOWN SL" | |
823 | +#endif /* WITH_LSPP */ | |
824 | + | |
825 | #include "mime.h" | |
826 | ||
827 | #if defined(HAVE_CDSASSL) | |
828 | # include <CoreFoundation/CoreFoundation.h> | |
829 | #endif /* HAVE_CDSASSL */ | |
830 | ||
831 | - | |
832 | /* | |
833 | * Some OS's don't have hstrerror(), most notably Solaris... | |
834 | */ | |
835 | diff -up cups-1.6b1/scheduler/ipp.c.lspp cups-1.6b1/scheduler/ipp.c | |
836 | --- cups-1.6b1/scheduler/ipp.c.lspp 2012-05-25 17:01:32.810768787 +0200 | |
837 | +++ cups-1.6b1/scheduler/ipp.c 2012-05-25 17:18:06.620841313 +0200 | |
838 | @@ -35,6 +35,7 @@ | |
839 | * cancel_all_jobs() - Cancel all or selected print jobs. | |
f92713d3 SS |
840 | * cancel_job() - Cancel a print job. |
841 | * cancel_subscription() - Cancel a subscription. | |
842 | + * check_context() - Check the SELinux context for a user and job | |
f92713d3 SS |
843 | * check_rss_recipient() - Check that we do not have a duplicate RSS |
844 | * feed URI. | |
1f9b7ef8 KB |
845 | * check_quotas() - Check quotas for a printer and user. |
846 | @@ -99,6 +100,9 @@ | |
f92713d3 SS |
847 | * validate_user() - Validate the user for the request. |
848 | */ | |
849 | ||
850 | +/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */ | |
851 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
852 | + | |
853 | /* | |
854 | * Include necessary headers... | |
855 | */ | |
1f9b7ef8 | 856 | @@ -122,6 +126,14 @@ extern int mbr_check_membership_by_id(uu |
f92713d3 SS |
857 | # endif /* HAVE_MEMBERSHIPPRIV_H */ |
858 | #endif /* __APPLE__ */ | |
859 | ||
860 | +#ifdef WITH_LSPP | |
861 | +#include <libaudit.h> | |
862 | +#include <selinux/selinux.h> | |
863 | +#include <selinux/context.h> | |
864 | +#include <selinux/avc.h> | |
865 | +#include <selinux/flask.h> | |
866 | +#include <selinux/av_permissions.h> | |
867 | +#endif /* WITH_LSPP */ | |
868 | ||
869 | /* | |
870 | * Local functions... | |
1f9b7ef8 | 871 | @@ -146,6 +158,9 @@ static void cancel_all_jobs(cupsd_client |
f92713d3 SS |
872 | static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri); |
873 | static void cancel_subscription(cupsd_client_t *con, int id); | |
874 | static int check_rss_recipient(const char *recipient); | |
875 | +#ifdef WITH_LSPP | |
876 | +static int check_context(cupsd_client_t *con, cupsd_job_t *job); | |
877 | +#endif /* WITH_LSPP */ | |
878 | static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p); | |
1f9b7ef8 KB |
879 | static void close_job(cupsd_client_t *con, ipp_attribute_t *uri); |
880 | static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra, | |
881 | @@ -1285,6 +1300,21 @@ add_job(cupsd_client_t *con, /* I - Cl | |
f92713d3 SS |
882 | ipp_attribute_t *media_col, /* media-col attribute */ |
883 | *media_margin; /* media-*-margin attribute */ | |
884 | ipp_t *unsup_col; /* media-col in unsupported response */ | |
885 | +#ifdef WITH_LSPP | |
886 | + char *audit_message; /* Audit message string */ | |
887 | + char *printerfile; /* device file pointed to by the printer */ | |
888 | + char *userheader = NULL; /* User supplied job-sheets[0] */ | |
889 | + char *userfooter = NULL; /* User supplied job-sheets[1] */ | |
890 | + int override = 0; /* Was a banner overrode on a job */ | |
891 | + security_id_t clisid; /* SELinux SID for the client */ | |
892 | + security_id_t psid; /* SELinux SID for the printer */ | |
893 | + context_t printercon; /* Printer's context string */ | |
894 | + struct stat printerstat; /* Printer's stat buffer */ | |
895 | + security_context_t devcon; /* Printer's SELinux context */ | |
896 | + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ | |
897 | + security_class_t tclass; /* Object class for the SELinux check */ | |
898 | + access_vector_t avr; /* Access method being requested */ | |
899 | +#endif /* WITH_LSPP */ | |
900 | ||
901 | ||
902 | cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", | |
1f9b7ef8 | 903 | @@ -1542,6 +1572,106 @@ add_job(cupsd_client_t *con, /* I - Cl |
f92713d3 SS |
904 | ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, |
905 | "Untitled"); | |
906 | ||
907 | +#ifdef WITH_LSPP | |
908 | + if (is_lspp_config()) | |
909 | + { | |
910 | + if (!con->scon || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0) | |
911 | + { | |
912 | + cupsdLogMessage(CUPSD_LOG_ERROR, "add_job: missing classification for connection \'%s\'!", printer->name); | |
913 | + send_ipp_status(con, IPP_INTERNAL_ERROR, _("Missing required security attributes.")); | |
914 | + return (NULL); | |
915 | + } | |
916 | + | |
917 | + /* | |
918 | + * Perform an access check so that if the user gets feedback at enqueue time | |
919 | + */ | |
920 | + | |
921 | + printerfile = strstr(printer->device_uri, "/dev/"); | |
922 | + if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0)) | |
923 | + printerfile = printer->device_uri + strlen("file:"); | |
924 | + | |
925 | + if (printerfile != NULL) | |
926 | + { | |
927 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: Attempting an access check on printer device %s", | |
928 | + printerfile); | |
929 | + | |
930 | + if (lstat(printerfile, &printerstat) < 0) | |
931 | + { | |
932 | + if (errno != ENOENT) | |
933 | + { | |
934 | + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to stat the printer")); | |
935 | + return (NULL); | |
936 | + } | |
937 | + /* | |
938 | + * The printer does not exist, so for now assume it's a FileDevice | |
939 | + */ | |
940 | + tclass = SECCLASS_FILE; | |
941 | + avr = FILE__WRITE; | |
942 | + } | |
943 | + else if (S_ISCHR(printerstat.st_mode)) | |
944 | + { | |
945 | + tclass = SECCLASS_CHR_FILE; | |
946 | + avr = CHR_FILE__WRITE; | |
947 | + } | |
948 | + else if (S_ISREG(printerstat.st_mode)) | |
949 | + { | |
950 | + tclass = SECCLASS_FILE; | |
951 | + avr = FILE__WRITE; | |
952 | + } | |
953 | + else | |
954 | + { | |
955 | + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer is not a character device or regular file")); | |
956 | + return (NULL); | |
957 | + } | |
958 | + static avc_initialized = 0; | |
959 | + if (!avc_initialized++) | |
960 | + avc_init("cupsd_enqueue_", NULL, NULL, NULL, NULL); | |
961 | + avc_entry_ref_init(&avcref); | |
962 | + if (avc_context_to_sid(con->scon, &clisid) != 0) | |
963 | + { | |
964 | + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the client")); | |
965 | + return (NULL); | |
966 | + } | |
967 | + if (getfilecon(printerfile, &devcon) == -1) | |
968 | + { | |
969 | + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux context of the printer")); | |
970 | + return (NULL); | |
971 | + } | |
972 | + printercon = context_new(devcon); | |
973 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: printer context %s client context %s", | |
974 | + context_str(printercon), con->scon); | |
975 | + context_free(printercon); | |
976 | + | |
977 | + if (avc_context_to_sid(devcon, &psid) != 0) | |
978 | + { | |
979 | + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the printer")); | |
980 | + freecon(devcon); | |
981 | + return (NULL); | |
982 | + } | |
983 | + freecon(devcon); | |
984 | + if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0) | |
985 | + { | |
986 | + /* | |
987 | + * The access check failed, so cancel the job and send an audit message | |
988 | + */ | |
989 | + if (AuditLog != -1) | |
990 | + { | |
991 | + audit_message = NULL; | |
992 | + cupsdSetStringf(&audit_message, "job=? auid=%u acct=%s obj=%s refused" | |
993 | + " unable to access printer=%s", con->auid, | |
994 | + con->username, con->scon, printer->name); | |
995 | + audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message, | |
996 | + ServerName, NULL, NULL, 0); | |
997 | + cupsdClearString(&audit_message); | |
998 | + } | |
999 | + | |
1000 | + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("SELinux prohibits access to the printer")); | |
1001 | + return (NULL); | |
1002 | + } | |
1003 | + } | |
1004 | + } | |
1005 | +#endif /* WITH_LSPP */ | |
1006 | + | |
1007 | if ((job = cupsdAddJob(priority, printer->name)) == NULL) | |
1008 | { | |
1009 | send_ipp_status(con, IPP_INTERNAL_ERROR, | |
1f9b7ef8 | 1010 | @@ -1550,6 +1680,32 @@ add_job(cupsd_client_t *con, /* I - Cl |
f92713d3 SS |
1011 | return (NULL); |
1012 | } | |
1013 | ||
1014 | +#ifdef WITH_LSPP | |
1015 | + if (is_lspp_config()) | |
1016 | + { | |
1017 | + /* | |
1018 | + * duplicate the security context and auid of the connection into the job structure | |
1019 | + */ | |
1020 | + job->scon = strdup(con->scon); | |
1021 | + job->auid = con->auid; | |
1022 | + | |
1023 | + /* | |
1024 | + * add the security context to the request so that on a restart the security | |
1025 | + * attributes will be able to be restored | |
1026 | + */ | |
1027 | + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "security-context", | |
1028 | + NULL, job->scon); | |
1029 | + } | |
1030 | + else | |
1031 | + { | |
1032 | + /* | |
1033 | + * Fill in the security context of the job as unlabeled | |
1034 | + */ | |
1035 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: setting context of job to %s", UNKNOWN_SL); | |
1036 | + cupsdSetString(&job->scon, UNKNOWN_SL); | |
1037 | + } | |
1038 | +#endif /* WITH_LSPP */ | |
1039 | + | |
1f9b7ef8 | 1040 | job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE); |
f92713d3 | 1041 | job->attrs = con->request; |
1f9b7ef8 KB |
1042 | job->dirty = 1; |
1043 | @@ -1759,6 +1915,29 @@ add_job(cupsd_client_t *con, /* I - Cl | |
f92713d3 SS |
1044 | attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]); |
1045 | attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]); | |
1046 | } | |
1047 | +#ifdef WITH_LSPP | |
1048 | + else | |
1049 | + { | |
1050 | + /* | |
1051 | + * The option was present, so capture the user supplied strings | |
1052 | + */ | |
1053 | + userheader = strdup(attr->values[0].string.text); | |
1054 | + | |
1055 | + if (attr->num_values > 1) | |
1056 | + userfooter = strdup(attr->values[1].string.text); | |
1057 | + | |
1058 | + if (Classification != NULL && (strcmp(userheader, Classification) == 0) | |
1059 | + && userfooter &&(strcmp(userfooter, Classification) == 0)) | |
1060 | + { | |
1061 | + /* | |
1062 | + * Since both values are Classification, the user is not trying to Override | |
1063 | + */ | |
1064 | + free(userheader); | |
1065 | + if (userfooter) free(userfooter); | |
1066 | + userheader = userfooter = NULL; | |
1067 | + } | |
1068 | + } | |
1069 | +#endif /* WITH_LSPP */ | |
1070 | ||
1071 | job->job_sheets = attr; | |
1072 | ||
1f9b7ef8 | 1073 | @@ -1789,6 +1968,9 @@ add_job(cupsd_client_t *con, /* I - Cl |
f92713d3 SS |
1074 | "job-sheets=\"%s,none\", " |
1075 | "job-originating-user-name=\"%s\"", | |
1076 | Classification, job->username); | |
1077 | +#ifdef WITH_LSPP | |
1078 | + override = 1; | |
1079 | +#endif /* WITH_LSPP */ | |
1080 | } | |
1081 | else if (attr->num_values == 2 && | |
1082 | strcmp(attr->values[0].string.text, | |
1f9b7ef8 | 1083 | @@ -1807,6 +1989,9 @@ add_job(cupsd_client_t *con, /* I - Cl |
f92713d3 SS |
1084 | "job-originating-user-name=\"%s\"", |
1085 | attr->values[0].string.text, | |
1086 | attr->values[1].string.text, job->username); | |
1087 | +#ifdef WITH_LSPP | |
1088 | + override = 1; | |
1089 | +#endif /* WITH_LSPP */ | |
1090 | } | |
1091 | else if (strcmp(attr->values[0].string.text, Classification) && | |
1092 | strcmp(attr->values[0].string.text, "none") && | |
1f9b7ef8 | 1093 | @@ -1827,6 +2012,9 @@ add_job(cupsd_client_t *con, /* I - Cl |
f92713d3 SS |
1094 | "job-originating-user-name=\"%s\"", |
1095 | attr->values[0].string.text, | |
1096 | attr->values[1].string.text, job->username); | |
1097 | +#ifdef WITH_LSPP | |
1098 | + override = 1; | |
1099 | +#endif /* WITH_LSPP */ | |
1100 | } | |
1101 | } | |
1102 | else if (strcmp(attr->values[0].string.text, Classification) && | |
1f9b7ef8 | 1103 | @@ -1867,8 +2055,52 @@ add_job(cupsd_client_t *con, /* I - Cl |
f92713d3 SS |
1104 | "job-sheets=\"%s\", " |
1105 | "job-originating-user-name=\"%s\"", | |
1106 | Classification, job->username); | |
1107 | +#ifdef WITH_LSPP | |
1108 | + override = 1; | |
1109 | +#endif /* WITH_LSPP */ | |
1110 | + } | |
1111 | +#ifdef WITH_LSPP | |
1112 | + if (is_lspp_config() && AuditLog != -1) | |
1113 | + { | |
1114 | + audit_message = NULL; | |
1115 | + | |
1116 | + if (userheader || userfooter) | |
1117 | + { | |
1118 | + if (!override) | |
1119 | + { | |
1120 | + /* | |
1121 | + * The user overrode the banner, so audit it | |
1122 | + */ | |
1123 | + cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s" | |
1124 | + " using banners=%s,%s", job->id, userheader, | |
1125 | + userfooter, attr->values[0].string.text, | |
1126 | + (attr->num_values > 1) ? attr->values[1].string.text : "(null)"); | |
1127 | + audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message, | |
1128 | + ServerName, NULL, NULL, 1); | |
1129 | + } | |
1130 | + else | |
1131 | + { | |
1132 | + /* | |
1133 | + * The user tried to override the banner, audit the failure | |
1134 | + */ | |
1135 | + cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s" | |
1136 | + " ignored banners=%s,%s", job->id, userheader, | |
1137 | + userfooter, attr->values[0].string.text, | |
1138 | + (attr->num_values > 1) ? attr->values[1].string.text : "(null)"); | |
1139 | + audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message, | |
1140 | + ServerName, NULL, NULL, 0); | |
1141 | + } | |
1142 | + cupsdClearString(&audit_message); | |
1143 | + } | |
1144 | } | |
1145 | + | |
1146 | + if (userheader) | |
1147 | + free(userheader); | |
1148 | + if (userfooter) | |
1149 | + free(userfooter); | |
1150 | +#endif /* WITH_LSPP */ | |
1151 | } | |
1152 | + | |
1153 | ||
1154 | /* | |
1155 | * See if we need to add the starting sheet... | |
1f9b7ef8 | 1156 | @@ -3615,6 +3847,111 @@ check_rss_recipient( |
f92713d3 SS |
1157 | } |
1158 | ||
1159 | ||
1160 | +#ifdef WITH_LSPP | |
1161 | +/* | |
1162 | + * 'check_context()' - Check SELinux security context of a user and job | |
1163 | + */ | |
1164 | + | |
1165 | +static int /* O - 1 if OK, 0 if not, -1 on error */ | |
1166 | +check_context(cupsd_client_t *con, /* I - Client connection */ | |
1167 | + cupsd_job_t *job) /* I - Job */ | |
1168 | +{ | |
1169 | + int enforcing; /* is SELinux in enforcing mode */ | |
1170 | + char filename[1024]; /* Filename of the spool file */ | |
1171 | + security_id_t clisid; /* SELinux SID of the client */ | |
1172 | + security_id_t jobsid; /* SELinux SID of the job */ | |
1173 | + security_id_t filesid; /* SELinux SID of the spool file */ | |
1174 | + struct avc_entry_ref avcref; /* AVC entry cache pointer */ | |
1175 | + security_class_t tclass; /* SELinux security class */ | |
1176 | + access_vector_t avr; /* SELinux access being queried */ | |
1177 | + security_context_t spoolfilecon; /* SELinux context of the spool file */ | |
1178 | + | |
1179 | + | |
1180 | + /* | |
1181 | + * Validate the input to be sure there are contexts to work with... | |
1182 | + */ | |
1183 | + | |
1184 | + if (con->scon == NULL || job->scon == NULL | |
1185 | + || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0 | |
1186 | + || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0) | |
1187 | + return -1; | |
1188 | + | |
1189 | + if ((enforcing = security_getenforce()) == -1) | |
1190 | + { | |
1191 | + cupsdLogMessage(CUPSD_LOG_ERROR, "Error while determining SELinux enforcement"); | |
1192 | + return -1; | |
1193 | + } | |
1194 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "check_context: client context %s job context %s", con->scon, job->scon); | |
1195 | + | |
1196 | + | |
1197 | + /* | |
1198 | + * Initialize the avc engine... | |
1199 | + */ | |
1200 | + | |
1201 | + static avc_initialized = 0; | |
1202 | + if (! avc_initialized++) | |
1203 | + { | |
1204 | + if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0) | |
1205 | + { | |
1206 | + cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable avc_init"); | |
1207 | + return -1; | |
1208 | + } | |
1209 | + } | |
1210 | + if (avc_context_to_sid(con->scon, &clisid) != 0) | |
1211 | + { | |
1212 | + cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", con->scon); | |
1213 | + return -1; | |
1214 | + } | |
1f9b7ef8 KB |
1215 | + if (avc_context_to_sid(job->scon, &jobsid) != 0) |
1216 | + { | |
1217 | + cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", job->scon); | |
1218 | + return -1; | |
1219 | + } | |
f92713d3 SS |
1220 | + avc_entry_ref_init(&avcref); |
1221 | + tclass = SECCLASS_FILE; | |
1222 | + avr = FILE__READ; | |
1223 | + | |
1224 | + /* | |
1225 | + * Perform the check with the client as the subject, first with the job as the object | |
1226 | + * if that fails then with the spool file as the object... | |
1227 | + */ | |
1228 | + | |
1229 | + if (avc_has_perm_noaudit(clisid, jobsid, tclass, avr, &avcref, NULL) != 0) | |
1230 | + { | |
1231 | + cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access based on the client context"); | |
1232 | + | |
1233 | + snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id); | |
1234 | + if (getfilecon(filename, &spoolfilecon) == -1) | |
1235 | + { | |
1236 | + cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to get spoolfile context"); | |
1237 | + return -1; | |
1238 | + } | |
1239 | + if (avc_context_to_sid(spoolfilecon, &filesid) != 0) | |
1240 | + { | |
1241 | + cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to determine the SELinux sid for the spool file"); | |
1242 | + freecon(spoolfilecon); | |
1243 | + return -1; | |
1244 | + } | |
1245 | + freecon(spoolfilecon); | |
1246 | + if (avc_has_perm_noaudit(clisid, filesid, tclass, avr, &avcref, NULL) != 0) | |
1247 | + { | |
1248 | + cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access to the spool file"); | |
1249 | + return 0; | |
1250 | + } | |
1251 | + cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access to the spool file"); | |
1252 | + return 1; | |
1253 | + } | |
1254 | + else | |
1255 | + if (enforcing == 0) | |
1256 | + cupsdLogMessage(CUPSD_LOG_INFO, "check_context: allowing operation due to permissive mode"); | |
1257 | + else | |
1258 | + cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access based on the client context"); | |
1259 | + | |
1260 | + return 1; | |
1261 | +} | |
1262 | +#endif /* WITH_LSPP */ | |
1263 | + | |
1264 | + | |
1265 | /* | |
1266 | * 'check_quotas()' - Check quotas for a printer and user. | |
1267 | */ | |
1f9b7ef8 | 1268 | @@ -4067,6 +4404,15 @@ copy_banner(cupsd_client_t *con, /* I - |
f92713d3 SS |
1269 | char attrname[255], /* Name of attribute */ |
1270 | *s; /* Pointer into name */ | |
1271 | ipp_attribute_t *attr; /* Attribute */ | |
1272 | +#ifdef WITH_LSPP | |
1273 | + const char *mls_label; /* SL of print job */ | |
1274 | + char *jobrange; /* SELinux sensitivity range */ | |
1275 | + char *jobclearance; /* SELinux low end clearance */ | |
1276 | + context_t jobcon; /* SELinux context of the job */ | |
1277 | + context_t tmpcon; /* Temp context to set the level */ | |
1278 | + security_context_t spoolcon; /* Context of the file in the spool */ | |
1279 | +#endif /* WITH_LSPP */ | |
1280 | + | |
1281 | ||
1282 | ||
1283 | cupsdLogMessage(CUPSD_LOG_DEBUG2, | |
1f9b7ef8 | 1284 | @@ -4102,6 +4448,82 @@ copy_banner(cupsd_client_t *con, /* I - |
f92713d3 SS |
1285 | |
1286 | fchmod(cupsFileNumber(out), 0640); | |
1287 | fchown(cupsFileNumber(out), RunUser, Group); | |
1288 | +#ifdef WITH_LSPP | |
1289 | + if (job->scon != NULL && | |
1290 | + strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0) | |
1291 | + { | |
1292 | + if (getfilecon(filename, &spoolcon) == -1) | |
1293 | + { | |
1294 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1295 | + "copy_banner: Unable to get the context of the banner file %s - %s", | |
1296 | + filename, strerror(errno)); | |
1297 | + job->num_files --; | |
1298 | + return (0); | |
1299 | + } | |
1300 | + tmpcon = context_new(spoolcon); | |
1301 | + jobcon = context_new(job->scon); | |
1302 | + freecon(spoolcon); | |
1303 | + if (!tmpcon || !jobcon) | |
1304 | + { | |
1305 | + if (tmpcon) | |
1306 | + context_free(tmpcon); | |
1307 | + if (jobcon) | |
1308 | + context_free(jobcon); | |
1309 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1310 | + "copy_banner: Unable to get the SELinux contexts"); | |
1311 | + job->num_files --; | |
1312 | + return (0); | |
1313 | + } | |
1314 | + jobrange = context_range_get(jobcon); | |
1315 | + if (jobrange) | |
1316 | + { | |
1317 | + jobrange = strdup(jobrange); | |
1318 | + if ((jobclearance = strtok(jobrange, "-")) != NULL) | |
1319 | + { | |
1320 | + if (context_range_set(tmpcon, jobclearance) == -1) | |
1321 | + { | |
1322 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1323 | + "copy_banner: Unable to set the level of the context for file %s - %s", | |
1324 | + filename, strerror(errno)); | |
1325 | + free(jobrange); | |
1326 | + context_free(jobcon); | |
1327 | + context_free(tmpcon); | |
1328 | + job->num_files --; | |
1329 | + return (0); | |
1330 | + } | |
1331 | + } | |
1332 | + else | |
1333 | + { | |
1334 | + if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1) | |
1335 | + { | |
1336 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1337 | + "copy_banner: Unable to set the level of the context for file %s - %s", | |
1338 | + filename, strerror(errno)); | |
1339 | + free(jobrange); | |
1340 | + context_free(jobcon); | |
1341 | + context_free(tmpcon); | |
1342 | + job->num_files --; | |
1343 | + return (0); | |
1344 | + } | |
1345 | + } | |
1346 | + free(jobrange); | |
1347 | + } | |
1348 | + if (setfilecon(filename, context_str(tmpcon)) == -1) | |
1349 | + { | |
1350 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1351 | + "copy_banner: Unable to set the context of the banner file %s - %s", | |
1352 | + filename, strerror(errno)); | |
1353 | + context_free(jobcon); | |
1354 | + context_free(tmpcon); | |
1355 | + job->num_files --; | |
1356 | + return (0); | |
1357 | + } | |
1358 | + cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner: %s set to %s", | |
1359 | + filename, context_str(tmpcon)); | |
1360 | + context_free(jobcon); | |
1361 | + context_free(tmpcon); | |
1362 | + } | |
1363 | +#endif /* WITH_LSPP */ | |
1364 | ||
1365 | /* | |
1366 | * Try the localized banner file under the subdirectory... | |
1f9b7ef8 | 1367 | @@ -4196,6 +4618,24 @@ copy_banner(cupsd_client_t *con, /* I - |
f92713d3 SS |
1368 | else |
1369 | s = attrname; | |
1370 | ||
1371 | +#ifdef WITH_LSPP | |
1372 | + if (strcmp(s, "mls-label") == 0) | |
1373 | + { | |
1374 | + if (job->scon != NULL && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0) | |
1375 | + { | |
1376 | + jobcon = context_new(job->scon); | |
1f9b7ef8 | 1377 | + if (_cups_strcasecmp(name, MLS_CONFIG) == 0) |
f92713d3 | 1378 | + mls_label = context_range_get(jobcon); |
1f9b7ef8 | 1379 | + else if (_cups_strcasecmp(name, TE_CONFIG) == 0) |
f92713d3 SS |
1380 | + mls_label = context_type_get(jobcon); |
1381 | + else // default to using the whole context string | |
1382 | + mls_label = context_str(jobcon); | |
1383 | + cupsFilePuts(out, mls_label); | |
1384 | + context_free(jobcon); | |
1385 | + } | |
1386 | + continue; | |
1387 | + } | |
1388 | +#endif /* WITH_LSPP */ | |
1389 | if (!strcmp(s, "printer-name")) | |
1390 | { | |
1391 | cupsFilePuts(out, job->dest); | |
1f9b7ef8 KB |
1392 | @@ -6273,6 +6713,22 @@ get_job_attrs(cupsd_client_t *con, /* I |
1393 | ||
1394 | exclude = cupsdGetPrivateAttrs(policy, con, printer, job->username); | |
f92713d3 SS |
1395 | |
1396 | + | |
1397 | +#ifdef WITH_LSPP | |
1398 | + /* | |
1399 | + * Check SELinux... | |
1400 | + */ | |
1401 | + if (is_lspp_config() && check_context(con, job) != 1) | |
1402 | + { | |
1403 | + /* | |
1404 | + * Unfortunately we have to lie to the user... | |
1405 | + */ | |
1406 | + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); | |
1407 | + return; | |
1408 | + } | |
1409 | +#endif /* WITH_LSPP */ | |
1410 | + | |
1411 | + | |
1412 | /* | |
1413 | * Copy attributes... | |
1414 | */ | |
1f9b7ef8 KB |
1415 | @@ -6626,6 +7082,11 @@ get_jobs(cupsd_client_t *con, /* I - C |
1416 | if (username[0] && _cups_strcasecmp(username, job->username)) | |
1417 | continue; | |
f92713d3 SS |
1418 | |
1419 | +#ifdef WITH_LSPP | |
1f9b7ef8 KB |
1420 | + if (is_lspp_config() && check_context(con, job) != 1) |
1421 | + continue; | |
f92713d3 SS |
1422 | +#endif /* WITH_LSPP */ |
1423 | + | |
1f9b7ef8 KB |
1424 | if (count > 0) |
1425 | ippAddSeparator(con->response); | |
f92713d3 | 1426 | |
1f9b7ef8 | 1427 | @@ -11106,6 +11567,11 @@ validate_user(cupsd_job_t *job, /* I |
f92713d3 SS |
1428 | |
1429 | strlcpy(username, get_username(con), userlen); | |
1430 | ||
1431 | +#ifdef WITH_LSPP | |
1432 | + if (is_lspp_config() && check_context(con, job) != 1) | |
1433 | + return 0; | |
1434 | +#endif /* WITH_LSPP */ | |
1435 | + | |
1436 | /* | |
1437 | * Check the username against the owner... | |
1438 | */ | |
1f9b7ef8 KB |
1439 | diff -up cups-1.6b1/scheduler/job.c.lspp cups-1.6b1/scheduler/job.c |
1440 | --- cups-1.6b1/scheduler/job.c.lspp 2012-05-25 17:01:32.824768691 +0200 | |
1441 | +++ cups-1.6b1/scheduler/job.c 2012-05-25 17:22:50.856860012 +0200 | |
1442 | @@ -68,6 +68,9 @@ | |
1443 | * update_job_attrs() - Update the job-printer-* attributes. | |
f92713d3 SS |
1444 | */ |
1445 | ||
1446 | +/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */ | |
1447 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
1448 | + | |
1449 | /* | |
1450 | * Include necessary headers... | |
1451 | */ | |
1f9b7ef8 KB |
1452 | @@ -83,6 +86,14 @@ |
1453 | # endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */ | |
1454 | #endif /* __APPLE__ */ | |
f92713d3 SS |
1455 | |
1456 | +#ifdef WITH_LSPP | |
1457 | +#include <libaudit.h> | |
1458 | +#include <selinux/selinux.h> | |
1459 | +#include <selinux/context.h> | |
1460 | +#include <selinux/avc.h> | |
1461 | +#include <selinux/flask.h> | |
1462 | +#include <selinux/av_permissions.h> | |
1463 | +#endif /* WITH_LSPP */ | |
1464 | ||
1465 | /* | |
1466 | * Design Notes for Job Management | |
1f9b7ef8 KB |
1467 | @@ -580,6 +591,14 @@ cupsdContinueJob(cupsd_job_t *job) /* I |
1468 | /* PRINTER_STATE_REASONS env var */ | |
f92713d3 SS |
1469 | rip_max_cache[255]; |
1470 | /* RIP_MAX_CACHE env variable */ | |
1471 | +#ifdef WITH_LSPP | |
1472 | + char *audit_message = NULL; /* Audit message string */ | |
1473 | + context_t jobcon; /* SELinux context of the job */ | |
1474 | + char *label_template = NULL; /* SL to put in classification | |
1475 | + env var */ | |
1476 | + const char *mls_label = NULL; /* SL to put in classification | |
1477 | + env var */ | |
1478 | +#endif /* WITH_LSPP */ | |
1479 | ||
1480 | ||
1481 | cupsdLogMessage(CUPSD_LOG_DEBUG2, | |
1f9b7ef8 | 1482 | @@ -1071,6 +1090,67 @@ cupsdContinueJob(cupsd_job_t *job) /* I |
f92713d3 SS |
1483 | } |
1484 | } | |
1485 | ||
1486 | +#ifdef WITH_LSPP | |
1487 | + if (is_lspp_config()) | |
1488 | + { | |
1489 | + if (!job->scon || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0) | |
1490 | + { | |
1491 | + if (AuditLog != -1) | |
1492 | + { | |
1493 | + audit_message = NULL; | |
1494 | + cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s", | |
1495 | + job->id, job->auid, job->username, job->printer->name, title); | |
1496 | + audit_log_user_message(AuditLog, AUDIT_USER_UNLABELED_EXPORT, audit_message, | |
1497 | + ServerName, NULL, NULL, 1); | |
1498 | + cupsdClearString(&audit_message); | |
1499 | + } | |
1500 | + } | |
1501 | + else | |
1502 | + { | |
1503 | + jobcon = context_new(job->scon); | |
1504 | + | |
1505 | + if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME)) == NULL) | |
1506 | + label_template = strdup(Classification); | |
1507 | + else if (attr->num_values > 1 && | |
1508 | + strcmp(attr->values[1].string.text, "none") != 0) | |
1509 | + label_template = strdup(attr->values[1].string.text); | |
1510 | + else | |
1511 | + label_template = strdup(attr->values[0].string.text); | |
1512 | + | |
1f9b7ef8 | 1513 | + if (_cups_strcasecmp(label_template, MLS_CONFIG) == 0) |
f92713d3 | 1514 | + mls_label = context_range_get(jobcon); |
1f9b7ef8 | 1515 | + else if (_cups_strcasecmp(label_template, TE_CONFIG) == 0) |
f92713d3 | 1516 | + mls_label = context_type_get(jobcon); |
1f9b7ef8 | 1517 | + else if (_cups_strcasecmp(label_template, SELINUX_CONFIG) == 0) |
f92713d3 SS |
1518 | + mls_label = context_str(jobcon); |
1519 | + else | |
1520 | + mls_label = label_template; | |
1521 | + | |
1522 | + if (mls_label && (PerPageLabels || banner_page)) | |
1523 | + { | |
1524 | + snprintf(classification, sizeof(classification), "CLASSIFICATION=LSPP:%s", mls_label); | |
1525 | + envp[envc ++] = classification; | |
1526 | + } | |
1527 | + | |
1528 | + if ((AuditLog != -1) && !banner_page) | |
1529 | + { | |
1530 | + audit_message = NULL; | |
1531 | + cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s" | |
1532 | + " obj=%s label=%s", job->id, job->auid, job->username, | |
1533 | + job->printer->name, title, job->scon, mls_label?mls_label:"none"); | |
1534 | + audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message, | |
1535 | + ServerName, NULL, NULL, 1); | |
1536 | + cupsdClearString(&audit_message); | |
1537 | + } | |
1538 | + context_free(jobcon); | |
1539 | + free(label_template); | |
1540 | + } | |
1541 | + } | |
1542 | + else | |
1543 | + /* | |
1544 | + * Fall through to the non-LSPP behavior | |
1545 | + */ | |
1546 | +#endif /* WITH_LSPP */ | |
1547 | if (Classification && !banner_page) | |
1548 | { | |
1549 | if ((attr = ippFindAttribute(job->attrs, "job-sheets", | |
1f9b7ef8 KB |
1550 | @@ -1845,6 +1925,20 @@ cupsdLoadJob(cupsd_job_t *job) /* I - J |
1551 | ippSetString(job->attrs, &job->reasons, 0, "none"); | |
f92713d3 SS |
1552 | } |
1553 | ||
1554 | +#ifdef WITH_LSPP | |
1555 | + if ((attr = ippFindAttribute(job->attrs, "security-context", IPP_TAG_NAME)) != NULL) | |
1556 | + cupsdSetString(&job->scon, attr->values[0].string.text); | |
1557 | + else if (is_lspp_config()) | |
1558 | + { | |
1559 | + /* | |
1560 | + * There was no security context so delete the job | |
1561 | + */ | |
1562 | + cupsdLogMessage(CUPSD_LOG_ERROR, "LoadAllJobs: Missing or bad security-context attribute in control file \"%s\"!", | |
1563 | + jobfile); | |
1564 | + goto error; | |
1565 | + } | |
1566 | +#endif /* WITH_LSPP */ | |
1567 | + | |
1568 | job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed", | |
1569 | IPP_TAG_INTEGER); | |
1570 | job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME); | |
1f9b7ef8 | 1571 | @@ -2235,6 +2329,14 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J |
f92713d3 SS |
1572 | { |
1573 | char filename[1024]; /* Job control filename */ | |
1574 | cups_file_t *fp; /* Job file */ | |
1575 | +#ifdef WITH_LSPP | |
1576 | + security_context_t spoolcon; /* context of the job control file */ | |
1577 | + context_t jobcon; /* contex_t container for job->scon */ | |
1578 | + context_t tmpcon; /* Temp context to swap the level */ | |
1579 | + char *jobclearance; /* SELinux low end clearance */ | |
1580 | + const char *jobrange; /* SELinux sensitivity range */ | |
1581 | + char *jobrange_copy; /* SELinux sensitivity range */ | |
1582 | +#endif /* WITH_LSPP */ | |
1583 | ||
1584 | ||
1585 | cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p", | |
1f9b7ef8 KB |
1586 | @@ -2247,6 +2349,76 @@ cupsdSaveJob(cupsd_job_t *job) /* I - J |
1587 | ||
f92713d3 SS |
1588 | fchown(cupsFileNumber(fp), RunUser, Group); |
1589 | ||
1590 | +#ifdef WITH_LSPP | |
1591 | + if (job->scon && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0) | |
1592 | + { | |
1593 | + if (getfilecon(filename, &spoolcon) == -1) | |
1594 | + { | |
1595 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1596 | + "Unable to get context of job control file \"%s\" - %s.", | |
1597 | + filename, strerror(errno)); | |
1598 | + return; | |
1599 | + } | |
1600 | + jobcon = context_new(job->scon); | |
1601 | + tmpcon = context_new(spoolcon); | |
1602 | + freecon(spoolcon); | |
1603 | + if (!jobcon || !tmpcon) | |
1604 | + { | |
1605 | + if (jobcon) | |
1606 | + context_free(jobcon); | |
1607 | + if (tmpcon) | |
1608 | + context_free(tmpcon); | |
1609 | + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get SELinux contexts"); | |
1610 | + return; | |
1611 | + } | |
1612 | + jobrange = context_range_get(jobcon); | |
1613 | + if (jobrange) | |
1614 | + { | |
1615 | + jobrange_copy = strdup(jobrange); | |
1616 | + if ((jobclearance = strtok(jobrange_copy, "-")) != NULL) | |
1617 | + { | |
1618 | + if (context_range_set(tmpcon, jobclearance) == -1) | |
1619 | + { | |
1620 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1621 | + "Unable to set the range for job control file \"%s\" - %s.", | |
1622 | + filename, strerror(errno)); | |
1623 | + free(jobrange_copy); | |
1624 | + context_free(tmpcon); | |
1625 | + context_free(jobcon); | |
1626 | + return; | |
1627 | + } | |
1628 | + } | |
1629 | + else | |
1630 | + { | |
1631 | + if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1) | |
1632 | + { | |
1633 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1634 | + "Unable to set the range for job control file \"%s\" - %s.", | |
1635 | + filename, strerror(errno)); | |
1636 | + free(jobrange_copy); | |
1637 | + context_free(tmpcon); | |
1638 | + context_free(jobcon); | |
1639 | + return; | |
1640 | + } | |
1641 | + } | |
1642 | + free(jobrange_copy); | |
1643 | + } | |
1644 | + if (setfilecon(filename, context_str(tmpcon)) == -1) | |
1645 | + { | |
1646 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1647 | + "Unable to set context of job control file \"%s\" - %s.", | |
1648 | + filename, strerror(errno)); | |
1649 | + context_free(tmpcon); | |
1650 | + context_free(jobcon); | |
1651 | + return; | |
1652 | + } | |
1653 | + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p): new spool file context=%s", | |
1654 | + job, context_str(tmpcon)); | |
1655 | + context_free(tmpcon); | |
1656 | + context_free(jobcon); | |
1657 | + } | |
1658 | +#endif /* WITH_LSPP */ | |
1659 | + | |
1660 | job->attrs->state = IPP_IDLE; | |
1661 | ||
1662 | if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL, | |
1f9b7ef8 | 1663 | @@ -3735,6 +3907,18 @@ get_options(cupsd_job_t *job, /* I - Jo |
f92713d3 SS |
1664 | banner_page) |
1665 | continue; | |
1666 | ||
1667 | +#ifdef WITH_LSPP | |
1668 | + /* | |
1669 | + * In LSPP mode refuse to honor the page-label | |
1670 | + */ | |
1671 | + if (is_lspp_config() && | |
1672 | + !strcmp(attr->name, "page-label")) | |
1673 | + { | |
1674 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "Ignoring page-label option due to LSPP mode"); | |
1675 | + continue; | |
1676 | + } | |
1677 | +#endif /* WITH_LSPP */ | |
1678 | + | |
1679 | /* | |
1680 | * Otherwise add them to the list... | |
1681 | */ | |
1f9b7ef8 | 1682 | @@ -4457,6 +4641,19 @@ static void |
f92713d3 SS |
1683 | start_job(cupsd_job_t *job, /* I - Job ID */ |
1684 | cupsd_printer_t *printer) /* I - Printer to print job */ | |
1685 | { | |
1686 | +#ifdef WITH_LSPP | |
1687 | + char *audit_message = NULL; /* Audit message string */ | |
1688 | + char *printerfile = NULL; /* Device file pointed to by the printer */ | |
1689 | + security_id_t clisid; /* SELinux SID for the client */ | |
1690 | + security_id_t psid; /* SELinux SID for the printer */ | |
1691 | + context_t printercon; /* Printer's context string */ | |
1692 | + struct stat printerstat; /* Printer's stat buffer */ | |
1693 | + security_context_t devcon; /* Printer's SELinux context */ | |
1694 | + struct avc_entry_ref avcref; /* Pointer to the access vector cache */ | |
1695 | + security_class_t tclass; /* Object class for the SELinux check */ | |
1696 | + access_vector_t avr; /* Access method being requested */ | |
1697 | +#endif /* WITH_LSPP */ | |
1698 | + | |
1699 | cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))", | |
1700 | job, job->id, printer, printer->name); | |
1701 | ||
1f9b7ef8 | 1702 | @@ -4599,6 +4796,108 @@ start_job(cupsd_job_t *job, /* I - |
f92713d3 SS |
1703 | fcntl(job->side_pipes[1], F_SETFD, |
1704 | fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC); | |
1705 | ||
1706 | +#ifdef WITH_LSPP | |
1707 | + if (is_lspp_config()) | |
1708 | + { | |
1709 | + /* | |
1710 | + * Perform an access check before printing, but only if the printer starts with /dev/ | |
1711 | + */ | |
1712 | + printerfile = strstr(printer->device_uri, "/dev/"); | |
1713 | + if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0)) | |
1714 | + printerfile = printer->device_uri + strlen("file:"); | |
1715 | + | |
1716 | + if (printerfile != NULL) | |
1717 | + { | |
1718 | + cupsdLogMessage(CUPSD_LOG_DEBUG, | |
1719 | + "StartJob: Attempting to check access on printer device %s", printerfile); | |
1720 | + if (lstat(printerfile, &printerstat) < 0) | |
1721 | + { | |
1722 | + if (errno != ENOENT) | |
1723 | + { | |
1724 | + cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to stat the printer"); | |
1725 | + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL); | |
1726 | + return ; | |
1727 | + } | |
1728 | + /* | |
1729 | + * The printer does not exist, so for now assume it's a FileDevice | |
1730 | + */ | |
1731 | + tclass = SECCLASS_FILE; | |
1732 | + avr = FILE__WRITE; | |
1733 | + } | |
1734 | + else if (S_ISCHR(printerstat.st_mode)) | |
1735 | + { | |
1736 | + tclass = SECCLASS_CHR_FILE; | |
1737 | + avr = CHR_FILE__WRITE; | |
1738 | + } | |
1739 | + else if (S_ISREG(printerstat.st_mode)) | |
1740 | + { | |
1741 | + tclass = SECCLASS_FILE; | |
1742 | + avr = FILE__WRITE; | |
1743 | + } | |
1744 | + else | |
1745 | + { | |
1746 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1747 | + "StartJob: Printer is not a character device or regular file"); | |
1748 | + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL); | |
1749 | + return ; | |
1750 | + } | |
1751 | + static avc_initialized = 0; | |
1752 | + if (!avc_initialized++) | |
1753 | + avc_init("cupsd_dequeue_", NULL, NULL, NULL, NULL); | |
1754 | + avc_entry_ref_init(&avcref); | |
1755 | + if (avc_context_to_sid(job->scon, &clisid) != 0) | |
1756 | + { | |
1757 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1758 | + "StartJob: Unable to determine the SELinux sid for the job"); | |
1759 | + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL); | |
1760 | + return ; | |
1761 | + } | |
1762 | + if (getfilecon(printerfile, &devcon) == -1) | |
1763 | + { | |
1764 | + cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to get the SELinux context of %s", | |
1765 | + printerfile); | |
1766 | + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL); | |
1767 | + return ; | |
1768 | + } | |
1769 | + printercon = context_new(devcon); | |
1770 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "StartJob: printer context %s client context %s", | |
1771 | + context_str(printercon), job->scon); | |
1772 | + context_free(printercon); | |
1773 | + | |
1774 | + if (avc_context_to_sid(devcon, &psid) != 0) | |
1775 | + { | |
1776 | + cupsdLogMessage(CUPSD_LOG_ERROR, | |
1777 | + "StartJob: Unable to determine the SELinux sid for the printer"); | |
1778 | + freecon(devcon); | |
1779 | + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL); | |
1780 | + return ; | |
1781 | + } | |
1782 | + freecon(devcon); | |
1783 | + | |
1784 | + if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0) | |
1785 | + { | |
1786 | + /* | |
1787 | + * The access check failed, so cancel the job and send an audit message | |
1788 | + */ | |
1789 | + if (AuditLog != -1) | |
1790 | + { | |
1791 | + audit_message = NULL; | |
1792 | + cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s obj=%s canceled" | |
1793 | + " unable to access printer=%s", job->id, | |
1794 | + job->auid, (job->username)?job->username:"?", job->scon, printer->name); | |
1795 | + audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message, | |
1796 | + ServerName, NULL, NULL, 0); | |
1797 | + cupsdClearString(&audit_message); | |
1798 | + } | |
1799 | + | |
1800 | + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL); | |
1801 | + | |
1802 | + return ; | |
1803 | + } | |
1804 | + } | |
1805 | + } | |
1806 | +#endif /* WITH_LSPP */ | |
1807 | + | |
1808 | /* | |
1809 | * Now start the first file in the job... | |
1810 | */ | |
1f9b7ef8 KB |
1811 | diff -up cups-1.6b1/scheduler/job.h.lspp cups-1.6b1/scheduler/job.h |
1812 | --- cups-1.6b1/scheduler/job.h.lspp 2012-05-23 03:36:50.000000000 +0200 | |
1813 | +++ cups-1.6b1/scheduler/job.h 2012-05-25 17:23:41.802504888 +0200 | |
f92713d3 SS |
1814 | @@ -13,6 +13,13 @@ |
1815 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
1816 | */ | |
1817 | ||
1818 | +/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */ | |
1819 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
1820 | + | |
1821 | +#ifdef WITH_LSPP | |
1822 | +#include <selinux/selinux.h> | |
1823 | +#endif /* WITH_LSPP */ | |
1824 | + | |
1825 | /* | |
1826 | * Constants... | |
1827 | */ | |
1f9b7ef8 KB |
1828 | @@ -82,6 +89,10 @@ struct cupsd_job_s /**** Job request * |
1829 | int progress; /* Printing progress */ | |
1830 | int num_keywords; /* Number of PPD keywords */ | |
1831 | cups_option_t *keywords; /* PPD keywords */ | |
f92713d3 SS |
1832 | +#ifdef WITH_LSPP |
1833 | + security_context_t scon; /* Security context of job */ | |
1834 | + uid_t auid; /* Audit loginuid for this job */ | |
1835 | +#endif /* WITH_LSPP */ | |
1836 | }; | |
1837 | ||
1838 | typedef struct cupsd_joblog_s /**** Job log message ****/ | |
1f9b7ef8 KB |
1839 | diff -up cups-1.6b1/scheduler/main.c.lspp cups-1.6b1/scheduler/main.c |
1840 | --- cups-1.6b1/scheduler/main.c.lspp 2012-05-25 17:01:32.849768516 +0200 | |
1841 | +++ cups-1.6b1/scheduler/main.c 2012-05-25 17:01:32.868768383 +0200 | |
1842 | @@ -38,6 +38,8 @@ | |
f92713d3 SS |
1843 | * usage() - Show scheduler usage. |
1844 | */ | |
1845 | ||
1846 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
1847 | + | |
1848 | /* | |
1849 | * Include necessary headers... | |
1850 | */ | |
1f9b7ef8 KB |
1851 | @@ -75,6 +77,9 @@ |
1852 | # include <notify.h> | |
1853 | #endif /* HAVE_NOTIFY_H */ | |
f92713d3 SS |
1854 | |
1855 | +#ifdef WITH_LSPP | |
1856 | +# include <libaudit.h> | |
1857 | +#endif /* WITH_LSPP */ | |
1858 | ||
1859 | /* | |
1860 | * Local functions... | |
1f9b7ef8 | 1861 | @@ -138,6 +143,9 @@ main(int argc, /* I - Number of comm |
f92713d3 SS |
1862 | #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) |
1863 | struct sigaction action; /* Actions for POSIX signals */ | |
1864 | #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ | |
1865 | +#if WITH_LSPP | |
1866 | + auditfail_t failmode; /* Action for audit_open failure */ | |
1867 | +#endif /* WITH_LSPP */ | |
1868 | #ifdef __sgi | |
1869 | cups_file_t *fp; /* Fake lpsched lock file */ | |
1870 | struct stat statbuf; /* Needed for checking lpsched FIFO */ | |
1f9b7ef8 | 1871 | @@ -463,6 +471,25 @@ main(int argc, /* I - Number of comm |
f92713d3 SS |
1872 | #endif /* DEBUG */ |
1873 | } | |
1874 | ||
1875 | +#ifdef WITH_LSPP | |
1876 | + if ((AuditLog = audit_open()) < 0 ) | |
1877 | + { | |
1878 | + if (get_auditfail_action(&failmode) == 0) | |
1879 | + { | |
1880 | + if (failmode == FAIL_LOG) | |
1881 | + { | |
1882 | + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to connect to audit subsystem."); | |
1883 | + AuditLog = -1; | |
1884 | + } | |
1885 | + else if (failmode == FAIL_TERMINATE) | |
1886 | + { | |
1887 | + fprintf(stderr, "cupsd: unable to start auditing, terminating"); | |
1888 | + return -1; | |
1889 | + } | |
1890 | + } | |
1891 | + } | |
1892 | +#endif /* WITH_LSPP */ | |
1893 | + | |
1894 | /* | |
1895 | * Set the timezone info... | |
1896 | */ | |
1f9b7ef8 | 1897 | @@ -1180,6 +1207,11 @@ main(int argc, /* I - Number of comm |
f92713d3 SS |
1898 | |
1899 | cupsdStopSelect(); | |
1900 | ||
1901 | +#ifdef WITH_LSPP | |
1902 | + if (AuditLog != -1) | |
1903 | + audit_close(AuditLog); | |
1904 | +#endif /* WITH_LSPP */ | |
1905 | + | |
1906 | return (!stop_scheduler); | |
1907 | } | |
1908 | ||
1f9b7ef8 KB |
1909 | diff -up cups-1.6b1/scheduler/printers.c.lspp cups-1.6b1/scheduler/printers.c |
1910 | --- cups-1.6b1/scheduler/printers.c.lspp 2012-05-25 17:01:32.786768955 +0200 | |
1911 | +++ cups-1.6b1/scheduler/printers.c 2012-05-25 17:24:11.144300359 +0200 | |
1912 | @@ -56,6 +56,8 @@ | |
f92713d3 SS |
1913 | * write_xml_string() - Write a string with XML escaping. |
1914 | */ | |
1915 | ||
1916 | +/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */ | |
1917 | + | |
1918 | /* | |
1919 | * Include necessary headers... | |
1920 | */ | |
1f9b7ef8 KB |
1921 | @@ -80,6 +82,10 @@ |
1922 | # include <asl.h> | |
1923 | #endif /* __APPLE__ */ | |
f92713d3 SS |
1924 | |
1925 | +#ifdef WITH_LSPP | |
1926 | +# include <libaudit.h> | |
1927 | +# include <selinux/context.h> | |
1928 | +#endif /* WITH_LSPP */ | |
1929 | ||
1930 | /* | |
1f9b7ef8 KB |
1931 | * Local functions... |
1932 | @@ -2101,6 +2107,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) | |
f92713d3 SS |
1933 | "username", |
1934 | "password" | |
1935 | }; | |
1936 | +#ifdef WITH_LSPP | |
1937 | + char *audit_message; /* Audit message string */ | |
1938 | + char *printerfile; /* Path to a local printer dev */ | |
1939 | + char *rangestr; /* Printer's range if its available */ | |
1940 | + security_context_t devcon; /* Printer SELinux context */ | |
1941 | + context_t printercon; /* context_t for the printer */ | |
1942 | +#endif /* WITH_LSPP */ | |
1943 | ||
1944 | ||
1945 | DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name, | |
1f9b7ef8 | 1946 | @@ -2234,6 +2247,45 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) |
f92713d3 SS |
1947 | attr->values[1].string.text = _cupsStrAlloc(Classification ? |
1948 | Classification : p->job_sheets[1]); | |
1949 | } | |
1950 | +#ifdef WITH_LSPP | |
1951 | + if (AuditLog != -1) | |
1952 | + { | |
1953 | + audit_message = NULL; | |
1954 | + rangestr = NULL; | |
1955 | + printercon = 0; | |
1956 | + printerfile = strstr(p->device_uri, "/dev/"); | |
1957 | + if (printerfile == NULL && (strncmp(p->device_uri, "file:/", 6) == 0)) | |
1958 | + printerfile = p->device_uri + strlen("file:"); | |
1959 | + | |
1960 | + if (printerfile != NULL) | |
1961 | + { | |
1962 | + if (getfilecon(printerfile, &devcon) == -1) | |
1963 | + { | |
1964 | + if(is_selinux_enabled()) | |
1f9b7ef8 | 1965 | + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetPrinterAttrs: Unable to get printer context"); |
f92713d3 SS |
1966 | + } |
1967 | + else | |
1968 | + { | |
1969 | + printercon = context_new(devcon); | |
1970 | + freecon(devcon); | |
1971 | + } | |
1972 | + } | |
1973 | + | |
1974 | + if (printercon && context_range_get(printercon)) | |
1975 | + rangestr = strdup(context_range_get(printercon)); | |
1976 | + else | |
1977 | + rangestr = strdup("unknown"); | |
1978 | + | |
1979 | + cupsdSetStringf(&audit_message, "printer=%s uri=%s banners=%s,%s range=%s", | |
1980 | + p->name, p->sanitized_device_uri, p->job_sheets[0], p->job_sheets[1], rangestr); | |
1981 | + audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message, | |
1982 | + ServerName, NULL, NULL, 1); | |
1983 | + if (printercon) | |
1984 | + context_free(printercon); | |
1985 | + free(rangestr); | |
1986 | + cupsdClearString(&audit_message); | |
1987 | + } | |
1988 | +#endif /* WITH_LSPP */ | |
1989 | } | |
1990 | ||
1991 | p->raw = 0; | |
1f9b7ef8 | 1992 | @@ -5320,7 +5372,6 @@ write_irix_state(cupsd_printer_t *p) /* |
f92713d3 SS |
1993 | } |
1994 | #endif /* __sgi */ | |
1995 | ||
1996 | - | |
1997 | /* | |
1998 | * 'write_xml_string()' - Write a string with XML escaping. | |
1999 | */ |