View | Details | Raw Unified | Return to bug 29477
Collapse All | Expand All

(-)cups-1.6.2/config.h.in.lspp (+7 lines)
Lines 746-751 static __inline int _cups_abs(int i) { r Link Here
746
#  endif /* __GNUC__ || __STDC_VERSION__ */
746
#  endif /* __GNUC__ || __STDC_VERSION__ */
747
#endif /* !HAVE_ABS && !abs */
747
#endif /* !HAVE_ABS && !abs */
748
748
749
/*
750
 * Are we trying to meet LSPP requirements?
751
 */
752
753
#undef WITH_LSPP
754
755
749
#endif /* !_CUPS_CONFIG_H_ */
756
#endif /* !_CUPS_CONFIG_H_ */
750
757
751
/*
758
/*
(-)cups-1.6.2/config-scripts/cups-lspp.m4.lspp (+36 lines)
Line 0 Link Here
1
dnl
2
dnl   LSPP code for the Common UNIX Printing System (CUPS).
3
dnl
4
dnl   Copyright 2005-2006 by Hewlett-Packard Development Company, L.P.
5
dnl
6
dnl   This program is free software; you can redistribute it and/or modify
7
dnl   it under the terms of the GNU General Public License as published by
8
dnl   the Free Software Foundation; version 2.
9
dnl
10
dnl   This program is distributed in the hope that it will be useful, but
11
dnl   WITHOUT ANY WARRANTY; without even the implied warranty of
12
dnl   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
dnl   General Public License for more details.
14
dnl
15
dnl   You should have received a copy of the GNU General Public License
16
dnl   along with this program; if not, write to the Free Software Foundation,
17
dnl   Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA
18
dnl
19
20
dnl Are we trying to meet LSPP requirements
21
AC_ARG_ENABLE(lspp, [  --enable-lspp           turn on auditing and label support, default=no])
22
23
if test x"$enable_lspp" != xno; then
24
    case "$uname" in
25
        Linux)
26
            AC_CHECK_LIB(audit,audit_log_user_message, [LIBAUDIT="-laudit" AC_SUBST(LIBAUDIT)])
27
            AC_CHECK_HEADER(libaudit.h)
28
            AC_CHECK_LIB(selinux,getpeercon, [LIBSELINUX="-lselinux" AC_SUBST(LIBSELINUX)])
29
            AC_CHECK_HEADER(selinux/selinux.h)
30
            AC_DEFINE(WITH_LSPP)
31
            ;;
32
        *)
33
            # All others
34
            ;;
35
    esac
36
fi
(-)cups-1.6.2/configure.in.lspp (+2 lines)
Lines 37-42 sinclude(config-scripts/cups-systemd.m4) Link Here
37
sinclude(config-scripts/cups-defaults.m4)
37
sinclude(config-scripts/cups-defaults.m4)
38
sinclude(config-scripts/cups-scripting.m4)
38
sinclude(config-scripts/cups-scripting.m4)
39
39
40
sinclude(config-scripts/cups-lspp.m4)
41
40
INSTALL_LANGUAGES=""
42
INSTALL_LANGUAGES=""
41
UNINSTALL_LANGUAGES=""
43
UNINSTALL_LANGUAGES=""
42
LANGFILES=""
44
LANGFILES=""
(-)cups-1.6.2/filter/common.c.lspp (+139 lines)
Lines 30-35 Link Here
30
 * Include necessary headers...
30
 * Include necessary headers...
31
 */
31
 */
32
32
33
#include "config.h"
34
#ifdef WITH_LSPP
35
#define _GNU_SOURCE
36
#include <string.h>
37
#endif /* WITH_LSPP */
38
33
#include "common.h"
39
#include "common.h"
34
#include <locale.h>
40
#include <locale.h>
35
41
Lines 312-317 WriteLabelProlog(const char *label, /* I Link Here
312
{
318
{
313
  const char	*classification;	/* CLASSIFICATION environment variable */
319
  const char	*classification;	/* CLASSIFICATION environment variable */
314
  const char	*ptr;			/* Temporary string pointer */
320
  const char	*ptr;			/* Temporary string pointer */
321
#ifdef WITH_LSPP
322
  int           i,                      /* counter */
323
                n,                      /* counter */
324
                lines,                  /* number of lines needed */
325
                line_len,               /* index into tmp_label */
326
                label_len,              /* length of the label in characters */
327
                label_index,            /* index into the label */
328
                longest,                /* length of the longest line */
329
                longest_line,           /* index to the longest line */
330
                max_width;              /* maximum width in characters */
331
  char          **wrapped_label;        /* label with line breaks */
332
#endif /* WITH_LSPP */
315
333
316
334
317
 /*
335
 /*
Lines 334-339 WriteLabelProlog(const char *label, /* I Link Here
334
    return;
352
    return;
335
  }
353
  }
336
354
355
#ifdef WITH_LSPP
356
  if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
357
  {
358
   /*
359
    * Based on the 12pt fixed width font below determine the max_width
360
    */
361
    max_width = width / 8;
362
    longest_line = 0;
363
    longest = 0;
364
    classification += 5; // Skip the "LSPP:"
365
    label_len = strlen(classification);
366
367
    if (label_len > max_width)
368
    {
369
      lines = 1 + (int)(label_len / max_width);
370
      line_len = (int)(label_len / lines);
371
      wrapped_label = malloc(sizeof(*wrapped_label) * lines);
372
      label_index = i = n = 0;
373
      while (classification[label_index])
374
      {
375
        if ((label_index + line_len) > label_len)
376
          break;
377
        switch (classification[label_index + line_len + i])
378
        {
379
          case ':':
380
          case ',':
381
          case '-':
382
            i++;
383
            wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
384
            label_index += line_len + i;
385
            i = 0;
386
            break;
387
          default:
388
            i++;
389
            break;
390
        }
391
        if ((i + line_len) == max_width)
392
        {
393
          wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
394
          label_index = label_index + line_len + i;
395
          i = 0;
396
        }
397
      }
398
      wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
399
    }
400
    else
401
    {
402
      lines = 1;
403
      wrapped_label = malloc(sizeof(*wrapped_label));
404
      wrapped_label[0] = (char*)classification;
405
    }
406
407
    for (n = 0; n < lines; n++ )
408
    {
409
      printf("userdict/ESPp%c(", ('a' + n));
410
      for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
411
        if (*ptr < 32 || *ptr > 126)
412
          printf("\\%03o", *ptr);
413
        else
414
        {
415
          if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
416
            putchar('\\');
417
418
          printf("%c", *ptr);
419
        }
420
      if (i > longest)
421
      {
422
        longest = i;
423
        longest_line = n;
424
      }
425
      printf(")put\n");
426
    }
427
428
   /*
429
    * For LSPP use a fixed width font so that line wrapping can be calculated
430
    */
431
432
    puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
433
434
   /*
435
    * Finally, the procedure to write the labels on the page...
436
    */
437
438
    printf("userdict/ESPwl{\n"
439
           "  ESPlf setfont\n");
440
    printf("  ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
441
           'a' + longest_line, width * 0.5f);
442
    for (n = 1; n < lines; n++)
443
      printf(" dup");
444
    printf("\n  1 setgray\n");
445
    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
446
           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
447
    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
448
           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
449
    printf("  0 setgray\n");
450
    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
451
           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
452
    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
453
           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
454
    for (n = 0; n < lines; n ++)
455
    {
456
      printf("  dup %.0f moveto ESPp%c show\n",
457
             bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
458
      printf("  %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
459
    }
460
    printf("  pop\n"
461
           "}bind put\n");
462
463
   /*
464
    * Do some clean up at the end of the LSPP special case
465
    */
466
    free(wrapped_label);
467
468
  }
469
  else
470
  {
471
#endif /* !WITH_LSPP */
472
  
337
 /*
473
 /*
338
  * Set the classification + page label string...
474
  * Set the classification + page label string...
339
  */
475
  */
Lines 414-420 WriteLabelProlog(const char *label, /* I Link Here
414
  printf("  %.0f moveto ESPpl show\n", top - 14.0);
550
  printf("  %.0f moveto ESPpl show\n", top - 14.0);
415
  puts("pop");
551
  puts("pop");
416
  puts("}bind put");
552
  puts("}bind put");
553
  }
554
#ifdef WITH_LSPP
417
}
555
}
556
#endif /* WITH_LSPP */
418
557
419
558
420
/*
559
/*
(-)cups-1.6.2/filter/pstops.c.lspp (+133 lines)
Lines 3202-3207 write_label_prolog(pstops_doc_t *doc, /* Link Here
3202
{
3202
{
3203
  const char	*classification;	/* CLASSIFICATION environment variable */
3203
  const char	*classification;	/* CLASSIFICATION environment variable */
3204
  const char	*ptr;			/* Temporary string pointer */
3204
  const char	*ptr;			/* Temporary string pointer */
3205
#ifdef WITH_LSPP
3206
  int           i,                      /* counter */
3207
                n,                      /* counter */
3208
                lines,                  /* number of lines needed */
3209
                line_len,               /* index into tmp_label */
3210
                label_len,              /* length of the label in characters */
3211
                label_index,            /* index into the label */
3212
                longest,                /* length of the longest line */
3213
                longest_line,           /* index to the longest line */
3214
                max_width;              /* maximum width in characters */
3215
  char          **wrapped_label;        /* label with line breaks */
3216
#endif /* WITH_LSPP */
3205
3217
3206
3218
3207
 /*
3219
 /*
Lines 3224-3229 write_label_prolog(pstops_doc_t *doc, /* Link Here
3224
    return;
3236
    return;
3225
  }
3237
  }
3226
3238
3239
#ifdef WITH_LSPP
3240
  if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
3241
  {
3242
   /*
3243
    * Based on the 12pt fixed width font below determine the max_width
3244
    */
3245
    max_width = width / 8;
3246
    longest_line = 0;
3247
    longest = 0;
3248
    classification += 5; // Skip the "LSPP:"
3249
    label_len = strlen(classification);
3250
3251
    if (label_len > max_width)
3252
    {
3253
      lines = 1 + (int)(label_len / max_width);
3254
      line_len = (int)(label_len / lines);
3255
      wrapped_label = malloc(sizeof(*wrapped_label) * lines);
3256
      label_index = i = n = 0;
3257
      while (classification[label_index])
3258
      {
3259
        if ((label_index + line_len) > label_len)
3260
          break;
3261
        switch (classification[label_index + line_len + i])
3262
        {
3263
          case ':':
3264
          case ',':
3265
          case '-':
3266
            i++;
3267
            wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
3268
            label_index += line_len + i;
3269
            i = 0;
3270
            break;
3271
          default:
3272
            i++;
3273
            break;
3274
        }
3275
        if ((i + line_len) == max_width)
3276
        {
3277
          wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
3278
          label_index = label_index + line_len + i;
3279
          i = 0;
3280
        }
3281
      }
3282
      wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
3283
    }
3284
    else
3285
    {
3286
      lines = 1;
3287
      wrapped_label = malloc(sizeof(*wrapped_label));
3288
      wrapped_label[0] = (char*)classification;
3289
    }
3290
3291
    for (n = 0; n < lines; n++ )
3292
    {
3293
      printf("userdict/ESPp%c(", ('a' + n));
3294
      for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
3295
        if (*ptr < 32 || *ptr > 126)
3296
          printf("\\%03o", *ptr);
3297
        else
3298
        {
3299
          if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
3300
            putchar('\\');
3301
3302
          printf("%c", *ptr);
3303
        }
3304
      if (i > longest)
3305
      {
3306
        longest = i;
3307
        longest_line = n;
3308
      }
3309
      printf(")put\n");
3310
    }
3311
3312
   /*
3313
    * For LSPP use a fixed width font so that line wrapping can be calculated
3314
    */
3315
3316
    puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
3317
3318
   /*
3319
    * Finally, the procedure to write the labels on the page...
3320
    */
3321
3322
    printf("userdict/ESPwl{\n"
3323
           "  ESPlf setfont\n");
3324
    printf("  ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
3325
           'a' + longest_line, width * 0.5f);
3326
    for (n = 1; n < lines; n++)
3327
      printf(" dup");
3328
    printf("\n  1 setgray\n");
3329
    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
3330
           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
3331
    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
3332
           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
3333
    printf("  0 setgray\n");
3334
    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
3335
           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
3336
    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
3337
           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
3338
    for (n = 0; n < lines; n ++)
3339
    {
3340
      printf("  dup %.0f moveto ESPp%c show\n",
3341
             bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
3342
      printf("  %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
3343
    }
3344
    printf("  pop\n"
3345
           "}bind put\n");
3346
3347
   /*
3348
    * Do some clean up at the end of the LSPP special case
3349
    */
3350
    free(wrapped_label);
3351
3352
  }
3353
  else
3354
  {
3355
#endif /* !WITH_LSPP */
3356
3227
 /*
3357
 /*
3228
  * Set the classification + page label string...
3358
  * Set the classification + page label string...
3229
  */
3359
  */
Lines 3302-3308 write_label_prolog(pstops_doc_t *doc, /* Link Here
3302
  doc_printf(doc, "  %.0f moveto ESPpl show\n", top - 14.0);
3432
  doc_printf(doc, "  %.0f moveto ESPpl show\n", top - 14.0);
3303
  doc_puts(doc, "pop\n");
3433
  doc_puts(doc, "pop\n");
3304
  doc_puts(doc, "}bind put\n");
3434
  doc_puts(doc, "}bind put\n");
3435
  }
3436
#ifdef WITH_LSPP
3305
}
3437
}
3438
#endif /* WITH_LSPP */
3306
3439
3307
3440
3308
/*
3441
/*
(-)cups-1.6.2/Makedefs.in.lspp (-1 / +1 lines)
Lines 146-152 LDFLAGS = -L../cgi-bin -L../cups -L../f Link Here
146
			@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
146
			@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
147
LINKCUPS	=	@LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ)
147
LINKCUPS	=	@LINKCUPS@ $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ)
148
LINKCUPSIMAGE	=	@LINKCUPSIMAGE@
148
LINKCUPSIMAGE	=	@LINKCUPSIMAGE@
149
LIBS		=	$(LINKCUPS) $(COMMONLIBS)
149
LIBS		=	$(LINKCUPS) $(COMMONLIBS) @LIBAUDIT@ @LIBSELINUX@
150
OPTIM		=	@OPTIM@
150
OPTIM		=	@OPTIM@
151
OPTIONS		=
151
OPTIONS		=
152
PAMLIBS		=	@PAMLIBS@
152
PAMLIBS		=	@PAMLIBS@
(-)cups-1.6.2/scheduler/client.c.lspp (+169 lines)
Lines 41-46 Link Here
41
 *   valid_host()	    - Is the Host: field valid?
41
 *   valid_host()	    - Is the Host: field valid?
42
 *   write_file()	    - Send a file via HTTP.
42
 *   write_file()	    - Send a file via HTTP.
43
 *   write_pipe()	    - Flag that data is available on the CGI pipe.
43
 *   write_pipe()	    - Flag that data is available on the CGI pipe.
44
 *   client_pid_to_auid()   - Get the audit login uid of the client.
44
 */
45
 */
45
46
46
/*
47
/*
Lines 49-58 Link Here
49
50
50
#include "cupsd.h"
51
#include "cupsd.h"
51
52
53
#define _GNU_SOURCE
52
#ifdef HAVE_TCPD_H
54
#ifdef HAVE_TCPD_H
53
#  include <tcpd.h>
55
#  include <tcpd.h>
54
#endif /* HAVE_TCPD_H */
56
#endif /* HAVE_TCPD_H */
55
57
58
#ifdef WITH_LSPP
59
#include <selinux/selinux.h>
60
#include <selinux/context.h>
61
#include <fcntl.h>
62
#endif /* WITH_LSPP */
56
63
57
/*
64
/*
58
 * Local globals...
65
 * Local globals...
Lines 371-376 cupsdAcceptClient(cupsd_listener_t *lis) Link Here
371
  }
378
  }
372
#endif /* HAVE_TCPD_H */
379
#endif /* HAVE_TCPD_H */
373
380
381
#ifdef WITH_LSPP
382
  if (is_lspp_config())
383
  {
384
    struct ucred cr;
385
    unsigned int cl=sizeof(cr);
386
387
    if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0)
388
    {
389
     /*
390
      * client_pid_to_auid() can be racey
391
      * In this case the pid is based on a socket connected to the client
392
      */
393
      if ((con->auid = client_pid_to_auid(cr.pid)) == -1)
394
      {
395
        close(con->http.fd);
396
        cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: "
397
                        "unable to determine client auid for client pid=%d", cr.pid);
398
        free(con);
399
        return;
400
      }
401
      cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: peer's pid=%d, uid=%d, gid=%d, auid=%d",
402
                      cr.pid, cr.uid, cr.gid, con->auid);
403
    }
404
    else
405
    {
406
      close(con->http.fd);
407
      cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getsockopt() failed");
408
      free(con);
409
      return; 
410
    }
411
412
   /*
413
    * get the context of the peer connection
414
    */
415
    if (getpeercon(con->http.fd, &con->scon))
416
    {
417
      close(con->http.fd);
418
      cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdAcceptClient: getpeercon() failed");
419
      free(con);
420
      return; 
421
    }
422
423
    cupsdLogMessage(CUPSD_LOG_INFO, "cupsdAcceptClient: client context=%s", con->scon);
424
  }
425
  else
426
  {
427
    cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: skipping getpeercon()");
428
    cupsdSetString(&con->scon, UNKNOWN_SL);
429
  }
430
#endif /* WITH_LSPP */
431
374
#ifdef AF_LOCAL
432
#ifdef AF_LOCAL
375
  if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
433
  if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
376
    cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)",
434
    cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)",
Lines 678-683 cupsdReadClient(cupsd_client_t *con) /* Link Here
678
  mime_type_t		*type;		/* MIME type of file */
736
  mime_type_t		*type;		/* MIME type of file */
679
  cupsd_printer_t	*p;		/* Printer */
737
  cupsd_printer_t	*p;		/* Printer */
680
  static unsigned	request_id = 0;	/* Request ID for temp files */
738
  static unsigned	request_id = 0;	/* Request ID for temp files */
739
#ifdef WITH_LSPP
740
  security_context_t	spoolcon;	/* context of the job file */
741
  context_t		clicon;		/* contex_t container for con->scon */
742
  context_t		tmpcon;		/* temp context to swap the level */
743
  char			*clirange;	/* SELinux sensitivity range */
744
  char			*cliclearance;	/* SELinux low end clearance */
745
#endif /* WITH_LSPP */
681
746
682
747
683
  status = HTTP_CONTINUE;
748
  status = HTTP_CONTINUE;
Lines 2134-2139 cupsdReadClient(cupsd_client_t *con) /* Link Here
2134
	    fchmod(con->file, 0640);
2199
	    fchmod(con->file, 0640);
2135
	    fchown(con->file, RunUser, Group);
2200
	    fchown(con->file, RunUser, Group);
2136
            fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
2201
            fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
2202
#ifdef WITH_LSPP
2203
	    if (strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
2204
	    {
2205
	      if (getfilecon(con->filename, &spoolcon) == -1)
2206
	      {
2207
		cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
2208
		return (cupsdCloseClient(con));
2209
	      }
2210
	      clicon = context_new(con->scon);
2211
	      tmpcon = context_new(spoolcon);
2212
	      freecon(spoolcon);
2213
	      if (!clicon || !tmpcon)
2214
	      {
2215
		cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
2216
		if (clicon)
2217
		  context_free(clicon);
2218
		if (tmpcon)
2219
		  context_free(tmpcon);
2220
		return (cupsdCloseClient(con));
2221
	      }
2222
	      clirange = context_range_get(clicon);
2223
	      if (clirange)
2224
	      {
2225
		clirange = strdup(clirange);
2226
		if ((cliclearance = strtok(clirange, "-")) != NULL)
2227
		{
2228
		  if (context_range_set(tmpcon, cliclearance) == -1)
2229
		  {
2230
		    cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
2231
		    free(clirange);
2232
		    context_free(tmpcon);
2233
		    context_free(clicon);
2234
		    return (cupsdCloseClient(con));
2235
		  }
2236
		}
2237
		else
2238
		{
2239
		  if (context_range_set(tmpcon, (context_range_get(clicon))) == -1)
2240
		  {
2241
		    cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
2242
		    free(clirange);
2243
		    context_free(tmpcon);
2244
		    context_free(clicon);
2245
		    return (cupsdCloseClient(con));
2246
		  }
2247
		}
2248
		free(clirange);
2249
	      }
2250
	      if (setfilecon(con->filename, context_str(tmpcon)) == -1)
2251
	      {
2252
		cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
2253
		context_free(tmpcon);
2254
		context_free(clicon);
2255
		return (cupsdCloseClient(con));
2256
	      }
2257
	      cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: %s set to %s", 
2258
			      con->filename, context_str(tmpcon));
2259
	      context_free(tmpcon);
2260
	      context_free(clicon);
2261
	    }
2262
#endif /* WITH_LSPP */
2137
	  }
2263
	  }
2138
2264
2139
	  if (con->http.state != HTTP_POST_SEND)
2265
	  if (con->http.state != HTTP_POST_SEND)
Lines 3572-3577 is_path_absolute(const char *path) /* I Link Here
3572
  return (1);
3698
  return (1);
3573
}
3699
}
3574
3700
3701
#ifdef WITH_LSPP
3702
/*
3703
 * 'client_pid_to_auid()' - Using the client's pid, read /proc and determine the loginuid.
3704
 */
3705
3706
uid_t client_pid_to_auid(pid_t clipid)
3707
{
3708
  uid_t uid;
3709
  int len, in;
3710
  char buf[16] = {0};
3711
  char fname[32] = {0};
3712
3713
3714
 /*
3715
  * Hopefully this pid is still the one we are interested in.
3716
  */
3717
  snprintf(fname, 32, "/proc/%d/loginuid", clipid);
3718
  in = open(fname, O_NOFOLLOW|O_RDONLY);
3719
3720
  if (in < 0)
3721
    return -1;
3722
3723
  errno = 0;
3724
3725
  do {
3726
    len = read(in, buf, sizeof(buf));
3727
  } while (len < 0 && errno == EINTR);
3728
3729
  close(in);
3730
3731
  if (len < 0 || len >= sizeof(buf))
3732
    return -1;
3733
3734
  errno = 0;
3735
  buf[len] = 0;
3736
  uid = strtol(buf, 0, 10);
3737
3738
  if (errno != 0)
3739
    return -1;
3740
  else
3741
    return uid;
3742
}
3743
#endif /* WITH_LSPP */
3575
3744
3576
/*
3745
/*
3577
 * 'pipe_command()' - Pipe the output of a command to the remote client.
3746
 * 'pipe_command()' - Pipe the output of a command to the remote client.
(-)cups-1.6.2/scheduler/client.h.lspp (+14 lines)
Lines 18-23 Link Here
18
#endif /* HAVE_AUTHORIZATION_H */
18
#endif /* HAVE_AUTHORIZATION_H */
19
19
20
20
21
/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
22
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
23
24
#ifdef WITH_LSPP
25
#include <selinux/selinux.h>
26
#endif /* WITH_LSPP */
27
21
/*
28
/*
22
 * HTTP client structure...
29
 * HTTP client structure...
23
 */
30
 */
Lines 63-68 struct cupsd_client_s Link Here
63
#ifdef HAVE_AUTHORIZATION_H
70
#ifdef HAVE_AUTHORIZATION_H
64
  AuthorizationRef	authref;	/* Authorization ref */
71
  AuthorizationRef	authref;	/* Authorization ref */
65
#endif /* HAVE_AUTHORIZATION_H */
72
#endif /* HAVE_AUTHORIZATION_H */
73
#ifdef WITH_LSPP
74
  security_context_t	scon;		/* Security context of connection */
75
  uid_t			auid;		/* Audit loginuid of the client */
76
#endif /* WITH_LSPP */
66
};
77
};
67
78
68
#define HTTP(con) &((con)->http)
79
#define HTTP(con) &((con)->http)
Lines 135-140 extern void cupsdStartListening(void); Link Here
135
extern void	cupsdStopListening(void);
146
extern void	cupsdStopListening(void);
136
extern void	cupsdUpdateCGI(void);
147
extern void	cupsdUpdateCGI(void);
137
extern void	cupsdWriteClient(cupsd_client_t *con);
148
extern void	cupsdWriteClient(cupsd_client_t *con);
149
#ifdef WITH_LSPP
150
extern uid_t	client_pid_to_auid(pid_t clipid);
151
#endif /* WITH_LSPP */
138
152
139
#ifdef HAVE_SSL
153
#ifdef HAVE_SSL
140
extern int	cupsdEndTLS(cupsd_client_t *con);
154
extern int	cupsdEndTLS(cupsd_client_t *con);
(-)cups-1.6.2/scheduler/conf.c.lspp (+54 lines)
Lines 34-39 Link Here
34
 *   read_location()	      - Read a <Location path> definition.
34
 *   read_location()	      - Read a <Location path> definition.
35
 *   read_policy()	      - Read a <Policy name> definition.
35
 *   read_policy()	      - Read a <Policy name> definition.
36
 *   set_policy_defaults()    - Set default policy values as needed.
36
 *   set_policy_defaults()    - Set default policy values as needed.
37
 *   is_lspp_config()         - Is the system configured for LSPP
37
 */
38
 */
38
39
39
/*
40
/*
Lines 59-64 Link Here
59
#  define INADDR_NONE	0xffffffff
60
#  define INADDR_NONE	0xffffffff
60
#endif /* !INADDR_NONE */
61
#endif /* !INADDR_NONE */
61
62
63
#ifdef WITH_LSPP
64
#  include <libaudit.h>
65
#endif /* WITH_LSPP */
62
66
63
/*
67
/*
64
 * Configuration variable structure...
68
 * Configuration variable structure...
Lines 164-169 static const cupsd_var_t variables[] = Link Here
164
#  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
168
#  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
165
  { "ServerKey",		&ServerKey,		CUPSD_VARTYPE_PATHNAME },
169
  { "ServerKey",		&ServerKey,		CUPSD_VARTYPE_PATHNAME },
166
#  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
170
#  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
171
#ifdef WITH_LSPP
172
  { "AuditLog",			&AuditLog,		CUPSD_VARTYPE_INTEGER },
173
  { "PerPageLabels",		&PerPageLabels,		CUPSD_VARTYPE_BOOLEAN },
174
#endif /* WITH_LSPP */
167
#endif /* HAVE_SSL */
175
#endif /* HAVE_SSL */
168
  { "ServerName",		&ServerName,		CUPSD_VARTYPE_STRING },
176
  { "ServerName",		&ServerName,		CUPSD_VARTYPE_STRING },
169
  { "ServerRoot",		&ServerRoot,		CUPSD_VARTYPE_PATHNAME },
177
  { "ServerRoot",		&ServerRoot,		CUPSD_VARTYPE_PATHNAME },
Lines 537-542 cupsdReadConfiguration(void) Link Here
537
  const char	*tmpdir;		/* TMPDIR environment variable */
545
  const char	*tmpdir;		/* TMPDIR environment variable */
538
  struct stat	tmpinfo;		/* Temporary directory info */
546
  struct stat	tmpinfo;		/* Temporary directory info */
539
  cupsd_policy_t *p;			/* Policy */
547
  cupsd_policy_t *p;			/* Policy */
548
#ifdef WITH_LSPP
549
  char		*audit_message;		/* Audit message string */
550
#endif /* WITH_LSPP */
540
551
541
552
542
 /*
553
 /*
Lines 851-856 cupsdReadConfiguration(void) Link Here
851
862
852
  RunUser = getuid();
863
  RunUser = getuid();
853
864
865
#ifdef WITH_LSPP
866
  if (AuditLog != -1)
867
  {
868
   /*
869
    * ClassifyOverride is set during read_configuration, if its ON, report it now
870
    */
871
    if (ClassifyOverride)
872
      audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
873
                "[Config] ClassifyOverride=enabled Users can override print banners",
874
                ServerName, NULL, NULL, 1);
875
   /*
876
    * PerPageLabel is set during read_configuration, if its OFF, report it now
877
    */
878
    if (!PerPageLabels)
879
      audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
880
                "[Config] PerPageLabels=disabled", ServerName, NULL, NULL, 1);
881
  }
882
#endif /* WITH_LSPP */
883
854
  cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
884
  cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
855
                  RemotePort ? "enabled" : "disabled");
885
                  RemotePort ? "enabled" : "disabled");
856
886
Lines 1253-1259 cupsdReadConfiguration(void) Link Here
1253
    cupsdClearString(&Classification);
1283
    cupsdClearString(&Classification);
1254
1284
1255
  if (Classification)
1285
  if (Classification)
1286
  {
1256
    cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
1287
    cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
1288
#ifdef WITH_LSPP
1289
    if (AuditLog != -1)
1290
    {
1291
      audit_message = NULL;
1292
      cupsdSetStringf(&audit_message, "[Config] Classification=%s", Classification);
1293
      audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
1294
                             ServerName, NULL, NULL, 1);
1295
      cupsdClearString(&audit_message);
1296
    }
1297
#endif /* WITH_LSPP */
1298
  }
1257
1299
1258
 /*
1300
 /*
1259
  * Check the MaxClients setting, and then allocate memory for it...
1301
  * Check the MaxClients setting, and then allocate memory for it...
Lines 3639-3644 read_location(cups_file_t *fp, /* I - C Link Here
3639
  return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
3681
  return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
3640
}
3682
}
3641
3683
3684
#ifdef WITH_LSPP
3685
int is_lspp_config()
3686
{
3687
  if (Classification != NULL)
3688
    return ((_cups_strcasecmp(Classification, MLS_CONFIG) == 0) 
3689
            || (_cups_strcasecmp(Classification, TE_CONFIG) == 0)
3690
            || (_cups_strcasecmp(Classification, SELINUX_CONFIG) == 0));
3691
  else
3692
    return 0;
3693
}
3694
#endif /* WITH_LSPP */
3695
3642
3696
3643
/*
3697
/*
3644
 * 'read_policy()' - Read a <Policy name> definition.
3698
 * 'read_policy()' - Read a <Policy name> definition.
(-)cups-1.6.2/scheduler/conf.h.lspp (+10 lines)
Lines 249-254 VAR int SSLOptions VALUE(CUPSD_SSL_NO Link Here
249
					/* SSL/TLS options */
249
					/* SSL/TLS options */
250
#endif /* HAVE_SSL */
250
#endif /* HAVE_SSL */
251
251
252
#ifdef WITH_LSPP
253
VAR int			AuditLog		VALUE(-1),
254
					/* File descriptor for audit */
255
			PerPageLabels		VALUE(TRUE);
256
					/* Put the label on each page */
257
#endif /* WITH_LSPP */
258
252
#ifdef HAVE_LAUNCHD
259
#ifdef HAVE_LAUNCHD
253
VAR int			LaunchdTimeout		VALUE(10);
260
VAR int			LaunchdTimeout		VALUE(10);
254
					/* Time after which an idle cupsd will exit */
261
					/* Time after which an idle cupsd will exit */
Lines 267-272 int HaveServerCreds VALUE(0); Link Here
267
gss_cred_id_t		ServerCreds;	/* Server's GSS credentials */
274
gss_cred_id_t		ServerCreds;	/* Server's GSS credentials */
268
#endif /* HAVE_GSSAPI */
275
#endif /* HAVE_GSSAPI */
269
276
277
#ifdef WITH_LSPP
278
extern int		is_lspp_config(void);
279
#endif /* WITH_LSPP */
270
280
271
/*
281
/*
272
 * Prototypes...
282
 * Prototypes...
(-)cups-1.6.2/scheduler/cupsd.h.lspp (-1 / +10 lines)
Lines 13-18 Link Here
13
 *   file is missing or damaged, see the license at "http://www.cups.org/".
13
 *   file is missing or damaged, see the license at "http://www.cups.org/".
14
 */
14
 */
15
15
16
/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
17
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
16
18
17
/*
19
/*
18
 * Include necessary headers.
20
 * Include necessary headers.
Lines 37-49 Link Here
37
#  include <unistd.h>
39
#  include <unistd.h>
38
#endif /* WIN32 */
40
#endif /* WIN32 */
39
41
42
#include "config.h"
43
#ifdef WITH_LSPP
44
#  define MLS_CONFIG "mls"
45
#  define TE_CONFIG "te"
46
#  define SELINUX_CONFIG "SELinux"
47
#  define UNKNOWN_SL "UNKNOWN SL"
48
#endif /* WITH_LSPP */
49
40
#include "mime.h"
50
#include "mime.h"
41
51
42
#if defined(HAVE_CDSASSL)
52
#if defined(HAVE_CDSASSL)
43
#  include <CoreFoundation/CoreFoundation.h>
53
#  include <CoreFoundation/CoreFoundation.h>
44
#endif /* HAVE_CDSASSL */
54
#endif /* HAVE_CDSASSL */
45
55
46
47
/*
56
/*
48
 * Some OS's don't have hstrerror(), most notably Solaris...
57
 * Some OS's don't have hstrerror(), most notably Solaris...
49
 */
58
 */
(-)cups-1.6.2/scheduler/ipp.c.lspp (+466 lines)
Lines 35-40 Link Here
35
 *   cancel_all_jobs()           - Cancel all or selected print jobs.
35
 *   cancel_all_jobs()           - Cancel all or selected print jobs.
36
 *   cancel_job()                - Cancel a print job.
36
 *   cancel_job()                - Cancel a print job.
37
 *   cancel_subscription()       - Cancel a subscription.
37
 *   cancel_subscription()       - Cancel a subscription.
38
 *   check_context()             - Check the SELinux context for a user and job
38
 *   check_rss_recipient()       - Check that we do not have a duplicate RSS
39
 *   check_rss_recipient()       - Check that we do not have a duplicate RSS
39
 *                                 feed URI.
40
 *                                 feed URI.
40
 *   check_quotas()              - Check quotas for a printer and user.
41
 *   check_quotas()              - Check quotas for a printer and user.
Lines 99-104 Link Here
99
 *   validate_user()             - Validate the user for the request.
100
 *   validate_user()             - Validate the user for the request.
100
 */
101
 */
101
102
103
/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
104
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
105
102
/*
106
/*
103
 * Include necessary headers...
107
 * Include necessary headers...
104
 */
108
 */
Lines 122-127 extern int mbr_check_membership_by_id(uu Link Here
122
#  endif /* HAVE_MEMBERSHIPPRIV_H */
126
#  endif /* HAVE_MEMBERSHIPPRIV_H */
123
#endif /* __APPLE__ */
127
#endif /* __APPLE__ */
124
128
129
#ifdef WITH_LSPP
130
#include <libaudit.h>
131
#include <selinux/selinux.h>
132
#include <selinux/context.h>
133
#include <selinux/avc.h>
134
#include <selinux/flask.h>
135
#include <selinux/av_permissions.h>
136
#endif /* WITH_LSPP */
125
137
126
/*
138
/*
127
 * Local functions...
139
 * Local functions...
Lines 146-151 static void cancel_all_jobs(cupsd_client Link Here
146
static void	cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
158
static void	cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
147
static void	cancel_subscription(cupsd_client_t *con, int id);
159
static void	cancel_subscription(cupsd_client_t *con, int id);
148
static int	check_rss_recipient(const char *recipient);
160
static int	check_rss_recipient(const char *recipient);
161
#ifdef WITH_LSPP
162
static int	check_context(cupsd_client_t *con, cupsd_job_t *job);
163
#endif /* WITH_LSPP */
149
static int	check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
164
static int	check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
150
static void	close_job(cupsd_client_t *con, ipp_attribute_t *uri);
165
static void	close_job(cupsd_client_t *con, ipp_attribute_t *uri);
151
static void	copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
166
static void	copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
Lines 1300-1305 add_job(cupsd_client_t *con, /* I - Cl Link Here
1300
    "time-at-creation",
1315
    "time-at-creation",
1301
    "time-at-processing"
1316
    "time-at-processing"
1302
  };
1317
  };
1318
#ifdef WITH_LSPP
1319
  char		*audit_message;		/* Audit message string */
1320
  char		*printerfile;		/* device file pointed to by the printer */
1321
  char		*userheader = NULL;	/* User supplied job-sheets[0] */
1322
  char		*userfooter = NULL;	/* User supplied job-sheets[1] */
1323
  int		override = 0;		/* Was a banner overrode on a job */
1324
  security_id_t	clisid;			/* SELinux SID for the client */
1325
  security_id_t	psid;			/* SELinux SID for the printer */
1326
  context_t	printercon;		/* Printer's context string */
1327
  struct stat	printerstat;		/* Printer's stat buffer */
1328
  security_context_t	devcon;		/* Printer's SELinux context */
1329
  struct avc_entry_ref	avcref;		/* Pointer to the access vector cache */
1330
  security_class_t	tclass;		/* Object class for the SELinux check */
1331
  access_vector_t	avr;		/* Access method being requested */
1332
#endif /* WITH_LSPP */
1303
1333
1304
1334
1305
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
1335
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
Lines 1640-1645 add_job(cupsd_client_t *con, /* I - Cl Link Here
1640
    }
1670
    }
1641
  }
1671
  }
1642
1672
1673
#ifdef WITH_LSPP
1674
  if (is_lspp_config())
1675
  {
1676
    if (!con->scon || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
1677
    {
1678
      cupsdLogMessage(CUPSD_LOG_ERROR, "add_job: missing classification for connection \'%s\'!", printer->name);
1679
      send_ipp_status(con, IPP_INTERNAL_ERROR, _("Missing required security attributes."));
1680
      return (NULL);
1681
    }
1682
1683
   /*
1684
    * Perform an access check so that if the user gets feedback at enqueue time
1685
    */
1686
1687
    printerfile = strstr(printer->device_uri, "/dev/");
1688
    if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
1689
      printerfile = printer->device_uri + strlen("file:");
1690
1691
    if (printerfile != NULL)
1692
    {
1693
      cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: Attempting an access check on printer device %s",
1694
                      printerfile);
1695
1696
      if (lstat(printerfile, &printerstat) < 0)
1697
      {
1698
	if (errno != ENOENT)
1699
	{
1700
	  send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to stat the printer"));
1701
	  return (NULL);
1702
	}
1703
	/*
1704
	 * The printer does not exist, so for now assume it's a FileDevice
1705
	 */
1706
	tclass = SECCLASS_FILE;
1707
	avr = FILE__WRITE;
1708
      }
1709
      else if (S_ISCHR(printerstat.st_mode))
1710
      {
1711
	tclass = SECCLASS_CHR_FILE;
1712
	avr = CHR_FILE__WRITE;
1713
      }
1714
      else if (S_ISREG(printerstat.st_mode))
1715
      {
1716
	tclass = SECCLASS_FILE;
1717
	avr = FILE__WRITE;
1718
      }
1719
      else
1720
      {
1721
	send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer is not a character device or regular file"));
1722
	return (NULL);
1723
      }
1724
      static avc_initialized = 0;
1725
      if (!avc_initialized++)
1726
          avc_init("cupsd_enqueue_", NULL, NULL, NULL, NULL);
1727
      avc_entry_ref_init(&avcref);
1728
      if (avc_context_to_sid(con->scon, &clisid) != 0)
1729
      {
1730
        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the client"));
1731
        return (NULL);
1732
      }
1733
      if (getfilecon(printerfile, &devcon) == -1)
1734
      {
1735
        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux context of the printer"));
1736
        return (NULL);
1737
      }
1738
      printercon = context_new(devcon);
1739
      cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: printer context %s client context %s",
1740
                      context_str(printercon), con->scon);
1741
      context_free(printercon);
1742
1743
      if (avc_context_to_sid(devcon, &psid) != 0)
1744
      {
1745
        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the printer"));
1746
        freecon(devcon);
1747
        return (NULL);
1748
      }
1749
      freecon(devcon);
1750
      if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
1751
      {
1752
       /*
1753
        * The access check failed, so cancel the job and send an audit message
1754
        */
1755
        if (AuditLog != -1)
1756
        {
1757
          audit_message = NULL;
1758
          cupsdSetStringf(&audit_message, "job=? auid=%u acct=%s obj=%s refused"
1759
                          " unable to access printer=%s", con->auid,
1760
                          con->username, con->scon, printer->name);
1761
          audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
1762
                                 ServerName, NULL, NULL, 0);
1763
          cupsdClearString(&audit_message);
1764
        }
1765
1766
        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("SELinux prohibits access to the printer"));
1767
        return (NULL);
1768
      }
1769
    }
1770
  }
1771
#endif /* WITH_LSPP */
1772
1643
  if ((job = cupsdAddJob(priority, printer->name)) == NULL)
1773
  if ((job = cupsdAddJob(priority, printer->name)) == NULL)
1644
  {
1774
  {
1645
    send_ipp_status(con, IPP_INTERNAL_ERROR,
1775
    send_ipp_status(con, IPP_INTERNAL_ERROR,
Lines 1648-1653 add_job(cupsd_client_t *con, /* I - Cl Link Here
1648
    return (NULL);
1778
    return (NULL);
1649
  }
1779
  }
1650
1780
1781
#ifdef WITH_LSPP
1782
  if (is_lspp_config())
1783
  {
1784
   /*
1785
    * duplicate the security context and auid of the connection into the job structure
1786
    */
1787
    job->scon = strdup(con->scon);
1788
    job->auid = con->auid;
1789
1790
   /* 
1791
    * add the security context to the request so that on a restart the security
1792
    * attributes will be able to be restored
1793
    */
1794
    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "security-context", 
1795
		 NULL, job->scon);
1796
  }
1797
  else
1798
  {
1799
   /*
1800
    * Fill in the security context of the job as unlabeled
1801
    */
1802
    cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: setting context of job to %s", UNKNOWN_SL);
1803
    cupsdSetString(&job->scon, UNKNOWN_SL);
1804
  }
1805
#endif /* WITH_LSPP */
1806
1651
  job->dtype   = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
1807
  job->dtype   = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
1652
  job->attrs   = con->request;
1808
  job->attrs   = con->request;
1653
  job->dirty   = 1;
1809
  job->dirty   = 1;
Lines 1857-1862 add_job(cupsd_client_t *con, /* I - Cl Link Here
1857
      attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
2013
      attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
1858
      attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]);
2014
      attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]);
1859
    }
2015
    }
2016
#ifdef WITH_LSPP
2017
    else
2018
    {
2019
     /*
2020
      * The option was present, so capture the user supplied strings
2021
      */
2022
      userheader = strdup(attr->values[0].string.text);
2023
2024
      if (attr->num_values > 1)
2025
        userfooter = strdup(attr->values[1].string.text);
2026
  
2027
      if (Classification != NULL && (strcmp(userheader, Classification) == 0)
2028
          && userfooter &&(strcmp(userfooter, Classification) == 0))
2029
      {
2030
       /*
2031
        * Since both values are Classification, the user is not trying to Override
2032
        */
2033
        free(userheader);
2034
        if (userfooter) free(userfooter);
2035
        userheader = userfooter = NULL;
2036
      }
2037
    }
2038
#endif /* WITH_LSPP */
1860
2039
1861
    job->job_sheets = attr;
2040
    job->job_sheets = attr;
1862
2041
Lines 1887-1892 add_job(cupsd_client_t *con, /* I - Cl Link Here
1887
	                		     "job-sheets=\"%s,none\", "
2066
	                		     "job-sheets=\"%s,none\", "
1888
					     "job-originating-user-name=\"%s\"",
2067
					     "job-originating-user-name=\"%s\"",
1889
	              Classification, job->username);
2068
	              Classification, job->username);
2069
#ifdef WITH_LSPP
2070
	  override = 1;
2071
#endif /* WITH_LSPP */
1890
	}
2072
	}
1891
	else if (attr->num_values == 2 &&
2073
	else if (attr->num_values == 2 &&
1892
	         strcmp(attr->values[0].string.text,
2074
	         strcmp(attr->values[0].string.text,
Lines 1905-1910 add_job(cupsd_client_t *con, /* I - Cl Link Here
1905
					     "job-originating-user-name=\"%s\"",
2087
					     "job-originating-user-name=\"%s\"",
1906
		      attr->values[0].string.text,
2088
		      attr->values[0].string.text,
1907
		      attr->values[1].string.text, job->username);
2089
		      attr->values[1].string.text, job->username);
2090
#ifdef WITH_LSPP
2091
	  override = 1;
2092
#endif /* WITH_LSPP */
1908
	}
2093
	}
1909
	else if (strcmp(attr->values[0].string.text, Classification) &&
2094
	else if (strcmp(attr->values[0].string.text, Classification) &&
1910
	         strcmp(attr->values[0].string.text, "none") &&
2095
	         strcmp(attr->values[0].string.text, "none") &&
Lines 1925-1930 add_job(cupsd_client_t *con, /* I - Cl Link Here
1925
			"job-originating-user-name=\"%s\"",
2110
			"job-originating-user-name=\"%s\"",
1926
			attr->values[0].string.text,
2111
			attr->values[0].string.text,
1927
			attr->values[1].string.text, job->username);
2112
			attr->values[1].string.text, job->username);
2113
#ifdef WITH_LSPP
2114
	  override = 1;
2115
#endif /* WITH_LSPP */
1928
        }
2116
        }
1929
      }
2117
      }
1930
      else if (strcmp(attr->values[0].string.text, Classification) &&
2118
      else if (strcmp(attr->values[0].string.text, Classification) &&
Lines 1965-1972 add_job(cupsd_client_t *con, /* I - Cl Link Here
1965
		      "job-sheets=\"%s\", "
2153
		      "job-sheets=\"%s\", "
1966
		      "job-originating-user-name=\"%s\"",
2154
		      "job-originating-user-name=\"%s\"",
1967
		      Classification, job->username);
2155
		      Classification, job->username);
2156
#ifdef WITH_LSPP
2157
	override = 1;
2158
#endif /* WITH_LSPP */
2159
      }
2160
#ifdef WITH_LSPP
2161
      if (is_lspp_config() && AuditLog != -1)
2162
      {
2163
        audit_message = NULL;
2164
2165
        if (userheader || userfooter)
2166
        {
2167
          if (!override)
2168
          {
2169
           /*
2170
            * The user overrode the banner, so audit it
2171
            */
2172
            cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
2173
                            " using banners=%s,%s", job->id, userheader,
2174
                            userfooter, attr->values[0].string.text,
2175
                            (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
2176
            audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
2177
                                   ServerName, NULL, NULL, 1);
2178
	  }
2179
          else
2180
          {
2181
           /*
2182
            * The user tried to override the banner, audit the failure
2183
            */
2184
            cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
2185
                            " ignored banners=%s,%s", job->id, userheader,
2186
                            userfooter, attr->values[0].string.text,
2187
                            (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
2188
            audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
2189
                                   ServerName, NULL, NULL, 0);
2190
	  }
2191
          cupsdClearString(&audit_message);
2192
	}
1968
      }
2193
      }
2194
2195
      if (userheader)
2196
        free(userheader);
2197
      if (userfooter)
2198
        free(userfooter);
2199
#endif /* WITH_LSPP */
1969
    }
2200
    }
2201
    
1970
2202
1971
   /*
2203
   /*
1972
    * See if we need to add the starting sheet...
2204
    * See if we need to add the starting sheet...
Lines 3730-3735 check_rss_recipient( Link Here
3730
}
3962
}
3731
3963
3732
3964
3965
#ifdef WITH_LSPP
3966
/*
3967
 * 'check_context()' - Check SELinux security context of a user and job
3968
 */
3969
3970
static int				/* O - 1 if OK, 0 if not, -1 on error */
3971
check_context(cupsd_client_t *con,	/* I - Client connection */
3972
             cupsd_job_t    *job)	/* I - Job */
3973
{
3974
  int			enforcing;	/* is SELinux in enforcing mode */
3975
  char			filename[1024]; /* Filename of the spool file */
3976
  security_id_t		clisid;		/* SELinux SID of the client */
3977
  security_id_t		jobsid;		/* SELinux SID of the job */
3978
  security_id_t		filesid;	/* SELinux SID of the spool file */
3979
  struct avc_entry_ref	avcref;		/* AVC entry cache pointer */
3980
  security_class_t	tclass;		/* SELinux security class */
3981
  access_vector_t	avr;		/* SELinux access being queried */
3982
  security_context_t	spoolfilecon;	/* SELinux context of the spool file */
3983
3984
3985
 /*
3986
  * Validate the input to be sure there are contexts to work with...
3987
  */
3988
3989
  if (con->scon == NULL || job->scon == NULL
3990
      || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0
3991
      || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
3992
    return -1;
3993
3994
  if ((enforcing = security_getenforce()) == -1)
3995
  {
3996
    cupsdLogMessage(CUPSD_LOG_ERROR, "Error while determining SELinux enforcement");
3997
    return -1;
3998
  }
3999
  cupsdLogMessage(CUPSD_LOG_DEBUG, "check_context: client context %s job context %s", con->scon, job->scon);
4000
4001
4002
 /*
4003
  * Initialize the avc engine...
4004
  */
4005
4006
  static avc_initialized = 0;
4007
  if (! avc_initialized++)
4008
  {
4009
    if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0)
4010
    {
4011
      cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable avc_init");
4012
      return -1;
4013
    } 
4014
  } 
4015
  if (avc_context_to_sid(con->scon, &clisid) != 0)
4016
  {
4017
    cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", con->scon);
4018
    return -1;
4019
  }
4020
  if (avc_context_to_sid(job->scon, &jobsid) != 0)
4021
  {
4022
    cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: unable to convert %s to SELinux sid", job->scon);
4023
    return -1;
4024
  }
4025
  avc_entry_ref_init(&avcref);
4026
  tclass = SECCLASS_FILE;
4027
  avr = FILE__READ;
4028
4029
 /*
4030
  * Perform the check with the client as the subject, first with the job as the object
4031
  *   if that fails then with the spool file as the object...
4032
  */
4033
4034
  if (avc_has_perm_noaudit(clisid, jobsid, tclass, avr, &avcref, NULL) != 0)
4035
  {
4036
    cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access based on the client context");
4037
4038
    snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
4039
    if (getfilecon(filename, &spoolfilecon) == -1)
4040
    {
4041
      cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to get spoolfile context");
4042
      return -1;
4043
    }
4044
    if (avc_context_to_sid(spoolfilecon, &filesid) != 0)
4045
    {
4046
      cupsdLogMessage(CUPSD_LOG_ERROR, "check_context: Unable to determine the SELinux sid for the spool file");
4047
      freecon(spoolfilecon);
4048
      return -1;
4049
    }
4050
    freecon(spoolfilecon);
4051
    if (avc_has_perm_noaudit(clisid, filesid, tclass, avr, &avcref, NULL) != 0)
4052
    {
4053
      cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux denied access to the spool file");
4054
      return 0;
4055
    }
4056
    cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access to the spool file");
4057
    return 1;
4058
  }
4059
  else
4060
    if (enforcing == 0)
4061
        cupsdLogMessage(CUPSD_LOG_INFO, "check_context: allowing operation due to permissive mode");
4062
    else
4063
        cupsdLogMessage(CUPSD_LOG_INFO, "check_context: SELinux allowed access based on the client context");
4064
4065
  return 1;
4066
}
4067
#endif /* WITH_LSPP */
4068
4069
3733
/*
4070
/*
3734
 * 'check_quotas()' - Check quotas for a printer and user.
4071
 * 'check_quotas()' - Check quotas for a printer and user.
3735
 */
4072
 */
Lines 4182-4187 copy_banner(cupsd_client_t *con, /* I - Link Here
4182
  char		attrname[255],		/* Name of attribute */
4519
  char		attrname[255],		/* Name of attribute */
4183
		*s;			/* Pointer into name */
4520
		*s;			/* Pointer into name */
4184
  ipp_attribute_t *attr;		/* Attribute */
4521
  ipp_attribute_t *attr;		/* Attribute */
4522
#ifdef WITH_LSPP
4523
  const char	*mls_label;		/* SL of print job */
4524
  char		*jobrange;		/* SELinux sensitivity range */
4525
  char		*jobclearance;		/* SELinux low end clearance */
4526
  context_t	jobcon;			/* SELinux context of the job */
4527
  context_t	tmpcon;			/* Temp context to set the level */
4528
  security_context_t	spoolcon;	/* Context of the file in the spool */
4529
#endif /* WITH_LSPP */
4530
4185
4531
4186
4532
4187
  cupsdLogMessage(CUPSD_LOG_DEBUG2,
4533
  cupsdLogMessage(CUPSD_LOG_DEBUG2,
Lines 4217-4222 copy_banner(cupsd_client_t *con, /* I - Link Here
4217
4563
4218
  fchmod(cupsFileNumber(out), 0640);
4564
  fchmod(cupsFileNumber(out), 0640);
4219
  fchown(cupsFileNumber(out), RunUser, Group);
4565
  fchown(cupsFileNumber(out), RunUser, Group);
4566
#ifdef WITH_LSPP
4567
  if (job->scon != NULL &&
4568
      strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
4569
  {
4570
    if (getfilecon(filename, &spoolcon) == -1)
4571
    {
4572
      cupsdLogMessage(CUPSD_LOG_ERROR,
4573
                      "copy_banner: Unable to get the context of the banner file %s - %s",
4574
                      filename, strerror(errno));
4575
      job->num_files --;
4576
      return (0);
4577
    }
4578
    tmpcon = context_new(spoolcon);
4579
    jobcon = context_new(job->scon);
4580
    freecon(spoolcon);
4581
    if (!tmpcon || !jobcon)
4582
    {
4583
      if (tmpcon)
4584
        context_free(tmpcon);
4585
      if (jobcon)
4586
        context_free(jobcon);
4587
      cupsdLogMessage(CUPSD_LOG_ERROR,
4588
                      "copy_banner: Unable to get the SELinux contexts");
4589
      job->num_files --;
4590
      return (0);
4591
    }
4592
    jobrange = context_range_get(jobcon);
4593
    if (jobrange)
4594
    {
4595
      jobrange = strdup(jobrange);
4596
      if ((jobclearance = strtok(jobrange, "-")) != NULL)
4597
      {
4598
	if (context_range_set(tmpcon, jobclearance) == -1)
4599
	{
4600
	  cupsdLogMessage(CUPSD_LOG_ERROR,
4601
			  "copy_banner: Unable to set the level of the context for file %s - %s",
4602
			  filename, strerror(errno));
4603
	  free(jobrange);
4604
	  context_free(jobcon);
4605
	  context_free(tmpcon);
4606
	  job->num_files --;
4607
	  return (0);
4608
	}
4609
      }
4610
      else
4611
      {
4612
	if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
4613
	{
4614
	  cupsdLogMessage(CUPSD_LOG_ERROR,
4615
			  "copy_banner: Unable to set the level of the context for file %s - %s",
4616
			  filename, strerror(errno));
4617
	  free(jobrange);
4618
	  context_free(jobcon);
4619
	  context_free(tmpcon);
4620
	  job->num_files --;
4621
	  return (0);
4622
	}
4623
      }
4624
      free(jobrange);
4625
    }
4626
    if (setfilecon(filename, context_str(tmpcon)) == -1)
4627
    {
4628
      cupsdLogMessage(CUPSD_LOG_ERROR,
4629
                      "copy_banner: Unable to set the context of the banner file %s - %s",
4630
                      filename, strerror(errno));
4631
      context_free(jobcon);
4632
      context_free(tmpcon);
4633
      job->num_files --;
4634
      return (0);
4635
    }
4636
    cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_banner: %s set to %s",
4637
                    filename, context_str(tmpcon));
4638
    context_free(jobcon);
4639
    context_free(tmpcon);
4640
  }
4641
#endif /* WITH_LSPP */
4220
4642
4221
 /*
4643
 /*
4222
  * Try the localized banner file under the subdirectory...
4644
  * Try the localized banner file under the subdirectory...
Lines 4311-4316 copy_banner(cupsd_client_t *con, /* I - Link Here
4311
      else
4733
      else
4312
        s = attrname;
4734
        s = attrname;
4313
4735
4736
#ifdef WITH_LSPP
4737
      if (strcmp(s, "mls-label") == 0)
4738
      {
4739
        if (job->scon != NULL && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
4740
        {
4741
          jobcon = context_new(job->scon);
4742
          if (_cups_strcasecmp(name, MLS_CONFIG) == 0)
4743
            mls_label = context_range_get(jobcon);
4744
          else if (_cups_strcasecmp(name, TE_CONFIG) == 0)
4745
            mls_label = context_type_get(jobcon);
4746
          else // default to using the whole context string
4747
            mls_label = context_str(jobcon);
4748
          cupsFilePuts(out, mls_label);
4749
          context_free(jobcon);
4750
        }
4751
        continue;
4752
      }
4753
#endif /* WITH_LSPP */
4314
      if (!strcmp(s, "printer-name"))
4754
      if (!strcmp(s, "printer-name"))
4315
      {
4755
      {
4316
        cupsFilePuts(out, job->dest);
4756
        cupsFilePuts(out, job->dest);
Lines 6388-6393 get_job_attrs(cupsd_client_t *con, /* I Link Here
6388
6828
6389
  exclude = cupsdGetPrivateAttrs(policy, con, printer, job->username);
6829
  exclude = cupsdGetPrivateAttrs(policy, con, printer, job->username);
6390
6830
6831
6832
#ifdef WITH_LSPP
6833
 /*
6834
  * Check SELinux...
6835
  */
6836
  if (is_lspp_config() && check_context(con, job) != 1)
6837
  {
6838
   /*
6839
    * Unfortunately we have to lie to the user...
6840
    */
6841
    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
6842
    return;
6843
  }
6844
#endif /* WITH_LSPP */
6845
6846
6391
 /*
6847
 /*
6392
  * Copy attributes...
6848
  * Copy attributes...
6393
  */
6849
  */
Lines 6741-6746 get_jobs(cupsd_client_t *con, /* I - C Link Here
6741
      if (username[0] && _cups_strcasecmp(username, job->username))
7197
      if (username[0] && _cups_strcasecmp(username, job->username))
6742
	continue;
7198
	continue;
6743
7199
7200
#ifdef WITH_LSPP
7201
      if (is_lspp_config() && check_context(con, job) != 1)
7202
	continue;
7203
#endif /* WITH_LSPP */
7204
6744
      if (count > 0)
7205
      if (count > 0)
6745
	ippAddSeparator(con->response);
7206
	ippAddSeparator(con->response);
6746
7207
Lines 11303-11308 validate_user(cupsd_job_t *job, /* I Link Here
11303
11764
11304
  strlcpy(username, get_username(con), userlen);
11765
  strlcpy(username, get_username(con), userlen);
11305
11766
11767
#ifdef WITH_LSPP
11768
  if (is_lspp_config() && check_context(con, job) != 1)
11769
    return 0;
11770
#endif /* WITH_LSPP */
11771
11306
 /*
11772
 /*
11307
  * Check the username against the owner...
11773
  * Check the username against the owner...
11308
  */
11774
  */
(-)cups-1.6.2/scheduler/job.c.lspp (+299 lines)
Lines 68-73 Link Here
68
 *   update_job_attrs() 	- Update the job-printer-* attributes.
68
 *   update_job_attrs() 	- Update the job-printer-* attributes.
69
 */
69
 */
70
70
71
/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
72
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
73
71
/*
74
/*
72
 * Include necessary headers...
75
 * Include necessary headers...
73
 */
76
 */
Lines 83-88 Link Here
83
#  endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
86
#  endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
84
#endif /* __APPLE__ */
87
#endif /* __APPLE__ */
85
88
89
#ifdef WITH_LSPP
90
#include <libaudit.h>
91
#include <selinux/selinux.h>
92
#include <selinux/context.h>
93
#include <selinux/avc.h>
94
#include <selinux/flask.h>
95
#include <selinux/av_permissions.h>
96
#endif /* WITH_LSPP */
86
97
87
/*
98
/*
88
 * Design Notes for Job Management
99
 * Design Notes for Job Management
Lines 580-585 cupsdContinueJob(cupsd_job_t *job) /* I Link Here
580
					/* PRINTER_STATE_REASONS env var */
591
					/* PRINTER_STATE_REASONS env var */
581
			rip_max_cache[255];
592
			rip_max_cache[255];
582
					/* RIP_MAX_CACHE env variable */
593
					/* RIP_MAX_CACHE env variable */
594
#ifdef WITH_LSPP
595
  char			*audit_message = NULL;	/* Audit message string */
596
  context_t		jobcon;		/* SELinux context of the job */
597
  char			*label_template = NULL;	/* SL to put in classification
598
						   env var */
599
  const char		*mls_label = NULL;	/* SL to put in classification
600
						   env var */
601
#endif /* WITH_LSPP */
583
602
584
603
585
  cupsdLogMessage(CUPSD_LOG_DEBUG2,
604
  cupsdLogMessage(CUPSD_LOG_DEBUG2,
Lines 1071-1076 cupsdContinueJob(cupsd_job_t *job) /* I Link Here
1071
    }
1090
    }
1072
  }
1091
  }
1073
1092
1093
#ifdef WITH_LSPP
1094
  if (is_lspp_config())
1095
  {
1096
    if (!job->scon || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
1097
    {
1098
      if (AuditLog != -1)
1099
      {
1100
        audit_message = NULL;
1101
        cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s",
1102
                        job->id, job->auid, job->username, job->printer->name, title);
1103
        audit_log_user_message(AuditLog, AUDIT_USER_UNLABELED_EXPORT, audit_message,
1104
                               ServerName, NULL, NULL, 1);
1105
        cupsdClearString(&audit_message);
1106
      }
1107
    }
1108
    else 
1109
    {
1110
      jobcon = context_new(job->scon);
1111
1112
      if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME)) == NULL)
1113
        label_template = strdup(Classification);
1114
      else if (attr->num_values > 1 &&
1115
               strcmp(attr->values[1].string.text, "none") != 0)
1116
        label_template = strdup(attr->values[1].string.text);
1117
      else
1118
        label_template = strdup(attr->values[0].string.text);
1119
1120
      if (_cups_strcasecmp(label_template, MLS_CONFIG) == 0)
1121
        mls_label = context_range_get(jobcon);
1122
      else if (_cups_strcasecmp(label_template, TE_CONFIG) == 0)
1123
        mls_label = context_type_get(jobcon);
1124
      else if (_cups_strcasecmp(label_template, SELINUX_CONFIG) == 0)
1125
        mls_label = context_str(jobcon);
1126
      else
1127
        mls_label = label_template;
1128
1129
      if (mls_label && (PerPageLabels || banner_page))
1130
      {
1131
        snprintf(classification, sizeof(classification), "CLASSIFICATION=LSPP:%s", mls_label);
1132
        envp[envc ++] = classification;
1133
      }
1134
1135
      if ((AuditLog != -1) && !banner_page)
1136
      {
1137
        audit_message = NULL;
1138
        cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s"
1139
                        " obj=%s label=%s", job->id, job->auid, job->username,
1140
                        job->printer->name, title, job->scon, mls_label?mls_label:"none");
1141
        audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
1142
                               ServerName, NULL, NULL, 1);
1143
        cupsdClearString(&audit_message);
1144
      }
1145
      context_free(jobcon);
1146
      free(label_template);
1147
    }
1148
  }
1149
  else
1150
   /*
1151
    * Fall through to the non-LSPP behavior
1152
    */
1153
#endif /* WITH_LSPP */
1074
  if (Classification && !banner_page)
1154
  if (Classification && !banner_page)
1075
  {
1155
  {
1076
    if ((attr = ippFindAttribute(job->attrs, "job-sheets",
1156
    if ((attr = ippFindAttribute(job->attrs, "job-sheets",
Lines 1845-1850 cupsdLoadJob(cupsd_job_t *job) /* I - J Link Here
1845
      ippSetString(job->attrs, &job->reasons, 0, "none");
1925
      ippSetString(job->attrs, &job->reasons, 0, "none");
1846
  }
1926
  }
1847
1927
1928
#ifdef WITH_LSPP
1929
  if ((attr = ippFindAttribute(job->attrs, "security-context", IPP_TAG_NAME)) != NULL)
1930
    cupsdSetString(&job->scon, attr->values[0].string.text);
1931
  else if (is_lspp_config())
1932
  {
1933
   /*
1934
    * There was no security context so delete the job
1935
    */
1936
    cupsdLogMessage(CUPSD_LOG_ERROR, "LoadAllJobs: Missing or bad security-context attribute in control file \"%s\"!",
1937
                    jobfile);
1938
    goto error;
1939
  }
1940
#endif /* WITH_LSPP */
1941
1848
  job->sheets     = ippFindAttribute(job->attrs, "job-media-sheets-completed",
1942
  job->sheets     = ippFindAttribute(job->attrs, "job-media-sheets-completed",
1849
                                     IPP_TAG_INTEGER);
1943
                                     IPP_TAG_INTEGER);
1850
  job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
1944
  job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
Lines 2235-2240 cupsdSaveJob(cupsd_job_t *job) /* I - J Link Here
2235
{
2329
{
2236
  char		filename[1024];		/* Job control filename */
2330
  char		filename[1024];		/* Job control filename */
2237
  cups_file_t	*fp;			/* Job file */
2331
  cups_file_t	*fp;			/* Job file */
2332
#ifdef WITH_LSPP
2333
  security_context_t	spoolcon;	/* context of the job control file */
2334
  context_t		jobcon;		/* contex_t container for job->scon */
2335
  context_t		tmpcon;		/* Temp context to swap the level */
2336
  char			*jobclearance;	/* SELinux low end clearance */
2337
  const char		*jobrange;	/* SELinux sensitivity range */
2338
  char			*jobrange_copy;	/* SELinux sensitivity range */
2339
#endif /* WITH_LSPP */
2238
2340
2239
2341
2240
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
2342
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
Lines 2247-2252 cupsdSaveJob(cupsd_job_t *job) /* I - J Link Here
2247
2349
2248
  fchown(cupsFileNumber(fp), RunUser, Group);
2350
  fchown(cupsFileNumber(fp), RunUser, Group);
2249
2351
2352
#ifdef WITH_LSPP
2353
  if (job->scon && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
2354
  {
2355
    if (getfilecon(filename, &spoolcon) == -1)
2356
    {
2357
      cupsdLogMessage(CUPSD_LOG_ERROR,
2358
                      "Unable to get context of job control file \"%s\" - %s.",
2359
                      filename, strerror(errno));
2360
      return;
2361
    }
2362
    jobcon = context_new(job->scon);
2363
    tmpcon = context_new(spoolcon);
2364
    freecon(spoolcon);
2365
    if (!jobcon || !tmpcon)
2366
    {
2367
      if (jobcon)
2368
        context_free(jobcon);
2369
      if (tmpcon)
2370
        context_free(tmpcon);
2371
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get SELinux contexts");
2372
      return;
2373
    }
2374
    jobrange = context_range_get(jobcon);
2375
    if (jobrange)
2376
    {
2377
      jobrange_copy = strdup(jobrange);
2378
      if ((jobclearance = strtok(jobrange_copy, "-")) != NULL)
2379
      {
2380
	if (context_range_set(tmpcon, jobclearance) == -1)
2381
	{
2382
	  cupsdLogMessage(CUPSD_LOG_ERROR,
2383
			  "Unable to set the range for job control file \"%s\" - %s.",
2384
			  filename, strerror(errno));
2385
	  free(jobrange_copy);
2386
	  context_free(tmpcon);
2387
	  context_free(jobcon);
2388
	  return;
2389
	}
2390
      }
2391
      else
2392
      {
2393
	if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
2394
	{
2395
	  cupsdLogMessage(CUPSD_LOG_ERROR,
2396
			  "Unable to set the range for job control file \"%s\" - %s.",
2397
			  filename, strerror(errno));
2398
	  free(jobrange_copy);
2399
	  context_free(tmpcon);
2400
	  context_free(jobcon);
2401
	  return;
2402
	}
2403
      }
2404
      free(jobrange_copy);
2405
    }
2406
    if (setfilecon(filename, context_str(tmpcon)) == -1)
2407
    {
2408
      cupsdLogMessage(CUPSD_LOG_ERROR,
2409
                      "Unable to set context of job control file \"%s\" - %s.",
2410
                      filename, strerror(errno));
2411
      context_free(tmpcon);
2412
      context_free(jobcon);
2413
      return;
2414
    }
2415
    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p): new spool file context=%s",
2416
                    job, context_str(tmpcon));
2417
    context_free(tmpcon);
2418
    context_free(jobcon);
2419
  }
2420
#endif /* WITH_LSPP */
2421
2250
  job->attrs->state = IPP_IDLE;
2422
  job->attrs->state = IPP_IDLE;
2251
2423
2252
  if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
2424
  if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
Lines 3756-3761 get_options(cupsd_job_t *job, /* I - Jo Link Here
3756
	  banner_page)
3928
	  banner_page)
3757
        continue;
3929
        continue;
3758
3930
3931
#ifdef WITH_LSPP
3932
     /*
3933
      * In LSPP mode refuse to honor the page-label
3934
      */
3935
      if (is_lspp_config() &&
3936
          !strcmp(attr->name, "page-label"))
3937
      {
3938
        cupsdLogMessage(CUPSD_LOG_DEBUG, "Ignoring page-label option due to LSPP mode");
3939
        continue;
3940
      }
3941
#endif /* WITH_LSPP */
3942
3759
     /*
3943
     /*
3760
      * Otherwise add them to the list...
3944
      * Otherwise add them to the list...
3761
      */
3945
      */
Lines 4480-4485 static void Link Here
4480
start_job(cupsd_job_t     *job,		/* I - Job ID */
4664
start_job(cupsd_job_t     *job,		/* I - Job ID */
4481
          cupsd_printer_t *printer)	/* I - Printer to print job */
4665
          cupsd_printer_t *printer)	/* I - Printer to print job */
4482
{
4666
{
4667
#ifdef WITH_LSPP
4668
  char			*audit_message = NULL;	/* Audit message string */
4669
  char			*printerfile = NULL;	/* Device file pointed to by the printer */
4670
  security_id_t		clisid;		/* SELinux SID for the client */
4671
  security_id_t		psid;		/* SELinux SID for the printer */
4672
  context_t		printercon;	/* Printer's context string */
4673
  struct stat		printerstat;	/* Printer's stat buffer */
4674
  security_context_t	devcon;		/* Printer's SELinux context */
4675
  struct avc_entry_ref	avcref;		/* Pointer to the access vector cache */
4676
  security_class_t	tclass;		/* Object class for the SELinux check */
4677
  access_vector_t	avr;		/* Access method being requested */
4678
#endif /* WITH_LSPP */
4679
4483
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))",
4680
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))",
4484
                  job, job->id, printer, printer->name);
4681
                  job, job->id, printer, printer->name);
4485
4682
Lines 4622-4627 start_job(cupsd_job_t *job, /* I - Link Here
4622
  fcntl(job->side_pipes[1], F_SETFD,
4819
  fcntl(job->side_pipes[1], F_SETFD,
4623
	fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC);
4820
	fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC);
4624
4821
4822
#ifdef WITH_LSPP
4823
  if (is_lspp_config())
4824
  {
4825
   /*
4826
    * Perform an access check before printing, but only if the printer starts with /dev/
4827
    */
4828
    printerfile = strstr(printer->device_uri, "/dev/");
4829
    if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
4830
      printerfile = printer->device_uri + strlen("file:");
4831
4832
    if (printerfile != NULL)
4833
    {
4834
      cupsdLogMessage(CUPSD_LOG_DEBUG,
4835
                      "StartJob: Attempting to check access on printer device %s", printerfile);
4836
      if (lstat(printerfile, &printerstat) < 0)
4837
      {
4838
	if (errno != ENOENT)
4839
	{
4840
	  cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to stat the printer");
4841
	  cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
4842
	  return ;
4843
	}
4844
	/*
4845
	 * The printer does not exist, so for now assume it's a FileDevice
4846
	 */
4847
	tclass = SECCLASS_FILE;
4848
	avr = FILE__WRITE;
4849
      }
4850
      else if (S_ISCHR(printerstat.st_mode))
4851
      {
4852
	tclass = SECCLASS_CHR_FILE;
4853
	avr = CHR_FILE__WRITE;
4854
      }
4855
      else if (S_ISREG(printerstat.st_mode))
4856
      {
4857
	tclass = SECCLASS_FILE;
4858
	avr = FILE__WRITE;
4859
      }
4860
      else
4861
      {
4862
	cupsdLogMessage(CUPSD_LOG_ERROR,
4863
			"StartJob: Printer is not a character device or regular file");
4864
	cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
4865
	return ;
4866
      }
4867
      static avc_initialized = 0;
4868
      if (!avc_initialized++)
4869
          avc_init("cupsd_dequeue_", NULL, NULL, NULL, NULL);
4870
      avc_entry_ref_init(&avcref);
4871
      if (avc_context_to_sid(job->scon, &clisid) != 0)
4872
      {
4873
        cupsdLogMessage(CUPSD_LOG_ERROR,
4874
                        "StartJob: Unable to determine the SELinux sid for the job");
4875
        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
4876
        return ;
4877
      }
4878
      if (getfilecon(printerfile, &devcon) == -1)
4879
      {
4880
        cupsdLogMessage(CUPSD_LOG_ERROR, "StartJob: Unable to get the SELinux context of %s",
4881
                        printerfile);
4882
        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
4883
        return ;
4884
      }
4885
      printercon = context_new(devcon);
4886
      cupsdLogMessage(CUPSD_LOG_DEBUG, "StartJob: printer context %s client context %s",
4887
                      context_str(printercon), job->scon);
4888
      context_free(printercon);
4889
4890
      if (avc_context_to_sid(devcon, &psid) != 0)
4891
      {
4892
        cupsdLogMessage(CUPSD_LOG_ERROR,
4893
                        "StartJob: Unable to determine the SELinux sid for the printer");
4894
        freecon(devcon);
4895
        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
4896
        return ;
4897
      }
4898
      freecon(devcon);
4899
4900
      if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
4901
      {
4902
       /*
4903
        * The access check failed, so cancel the job and send an audit message
4904
        */
4905
        if (AuditLog != -1)
4906
        {
4907
          audit_message = NULL;
4908
          cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s obj=%s canceled"
4909
                                          " unable to access printer=%s", job->id,
4910
                          job->auid, (job->username)?job->username:"?", job->scon, printer->name);
4911
          audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
4912
                                 ServerName, NULL, NULL, 0);
4913
          cupsdClearString(&audit_message);
4914
        }
4915
4916
        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
4917
4918
        return ;
4919
      }
4920
    }
4921
  }
4922
#endif /* WITH_LSPP */
4923
4625
 /*
4924
 /*
4626
  * Now start the first file in the job...
4925
  * Now start the first file in the job...
4627
  */
4926
  */
(-)cups-1.6.2/scheduler/job.h.lspp (+11 lines)
Lines 13-18 Link Here
13
 *   file is missing or damaged, see the license at "http://www.cups.org/".
13
 *   file is missing or damaged, see the license at "http://www.cups.org/".
14
 */
14
 */
15
15
16
/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
17
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
18
19
#ifdef WITH_LSPP
20
#include <selinux/selinux.h>
21
#endif /* WITH_LSPP */
22
16
/*
23
/*
17
 * Constants...
24
 * Constants...
18
 */
25
 */
Lines 82-87 struct cupsd_job_s /**** Job request * Link Here
82
  int			progress;	/* Printing progress */
89
  int			progress;	/* Printing progress */
83
  int			num_keywords;	/* Number of PPD keywords */
90
  int			num_keywords;	/* Number of PPD keywords */
84
  cups_option_t		*keywords;	/* PPD keywords */
91
  cups_option_t		*keywords;	/* PPD keywords */
92
#ifdef WITH_LSPP
93
  security_context_t	scon;		/* Security context of job */
94
  uid_t			auid;		/* Audit loginuid for this job */
95
#endif /* WITH_LSPP */
85
};
96
};
86
97
87
typedef struct cupsd_joblog_s		/**** Job log message ****/
98
typedef struct cupsd_joblog_s		/**** Job log message ****/
(-)cups-1.6.2/scheduler/main.c.lspp (+32 lines)
Lines 38-43 Link Here
38
 *   usage()               - Show scheduler usage.
38
 *   usage()               - Show scheduler usage.
39
 */
39
 */
40
40
41
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
42
41
/*
43
/*
42
 * Include necessary headers...
44
 * Include necessary headers...
43
 */
45
 */
Lines 80-85 Link Here
80
#  include <sys/param.h>
82
#  include <sys/param.h>
81
#endif /* HAVE_SYS_PARAM_H */
83
#endif /* HAVE_SYS_PARAM_H */
82
84
85
#ifdef WITH_LSPP
86
#  include <libaudit.h>
87
#endif /* WITH_LSPP */
83
88
84
/*
89
/*
85
 * Local functions...
90
 * Local functions...
Lines 143-148 main(int argc, /* I - Number of comm Link Here
143
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
148
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
144
  struct sigaction	action;		/* Actions for POSIX signals */
149
  struct sigaction	action;		/* Actions for POSIX signals */
145
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
150
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
151
#if WITH_LSPP
152
  auditfail_t           failmode;       /* Action for audit_open failure */
153
#endif /* WITH_LSPP */
146
#ifdef __sgi
154
#ifdef __sgi
147
  cups_file_t		*fp;		/* Fake lpsched lock file */
155
  cups_file_t		*fp;		/* Fake lpsched lock file */
148
  struct stat		statbuf;	/* Needed for checking lpsched FIFO */
156
  struct stat		statbuf;	/* Needed for checking lpsched FIFO */
Lines 522-527 main(int argc, /* I - Number of comm Link Here
522
#endif /* DEBUG */
530
#endif /* DEBUG */
523
  }
531
  }
524
532
533
#ifdef WITH_LSPP
534
  if ((AuditLog = audit_open()) < 0 )
535
  {
536
    if (get_auditfail_action(&failmode) == 0)
537
    {
538
      if (failmode == FAIL_LOG)
539
      {
540
        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to connect to audit subsystem.");
541
        AuditLog = -1;
542
      }
543
      else if (failmode == FAIL_TERMINATE)
544
      {
545
        fprintf(stderr, "cupsd: unable to start auditing, terminating");
546
        return -1;
547
      }
548
    }
549
  }
550
#endif /* WITH_LSPP */
551
525
 /*
552
 /*
526
  * Set the timezone info...
553
  * Set the timezone info...
527
  */
554
  */
Lines 1216-1221 main(int argc, /* I - Number of comm Link Here
1216
1243
1217
  cupsdStopSelect();
1244
  cupsdStopSelect();
1218
1245
1246
#ifdef WITH_LSPP
1247
  if (AuditLog != -1)
1248
    audit_close(AuditLog);
1249
#endif /* WITH_LSPP */
1250
1219
  return (!stop_scheduler);
1251
  return (!stop_scheduler);
1220
}
1252
}
1221
1253
(-)cups-1.6.2/scheduler/printers.c.lspp (-1 / +52 lines)
Lines 56-61 Link Here
56
 *   write_xml_string()         - Write a string with XML escaping.
56
 *   write_xml_string()         - Write a string with XML escaping.
57
 */
57
 */
58
58
59
/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
60
59
/*
61
/*
60
 * Include necessary headers...
62
 * Include necessary headers...
61
 */
63
 */
Lines 80-85 Link Here
80
#  include <asl.h>
82
#  include <asl.h>
81
#endif /* __APPLE__ */
83
#endif /* __APPLE__ */
82
84
85
#ifdef WITH_LSPP
86
#  include <libaudit.h>
87
#  include <selinux/context.h>
88
#endif /* WITH_LSPP */
83
89
84
/*
90
/*
85
 * Local functions...
91
 * Local functions...
Lines 2090-2095 cupsdSetPrinterAttrs(cupsd_printer_t *p) Link Here
2090
  ipp_attribute_t *attr;		/* Attribute data */
2096
  ipp_attribute_t *attr;		/* Attribute data */
2091
  char		*name,			/* Current user/group name */
2097
  char		*name,			/* Current user/group name */
2092
		*filter;		/* Current filter */
2098
		*filter;		/* Current filter */
2099
#ifdef WITH_LSPP
2100
  char		*audit_message;		/* Audit message string */
2101
  char		*printerfile;		/* Path to a local printer dev */
2102
  char		*rangestr;		/* Printer's range if its available */
2103
  security_context_t	devcon;		/* Printer SELinux context */
2104
  context_t	printercon;		/* context_t for the printer */
2105
#endif /* WITH_LSPP */
2093
2106
2094
2107
2095
  DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
2108
  DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
Lines 2212-2217 cupsdSetPrinterAttrs(cupsd_printer_t *p) Link Here
2212
      attr->values[1].string.text = _cupsStrAlloc(Classification ?
2225
      attr->values[1].string.text = _cupsStrAlloc(Classification ?
2213
	                                   Classification : p->job_sheets[1]);
2226
	                                   Classification : p->job_sheets[1]);
2214
    }
2227
    }
2228
#ifdef WITH_LSPP
2229
    if (AuditLog != -1)
2230
    {
2231
      audit_message = NULL;
2232
      rangestr = NULL;
2233
      printercon = 0;
2234
      printerfile = strstr(p->device_uri, "/dev/");
2235
      if (printerfile == NULL && (strncmp(p->device_uri, "file:/", 6) == 0))
2236
        printerfile = p->device_uri + strlen("file:");
2237
2238
      if (printerfile != NULL)
2239
      {
2240
        if (getfilecon(printerfile, &devcon) == -1)
2241
        {
2242
          if(is_selinux_enabled())
2243
            cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetPrinterAttrs: Unable to get printer context");
2244
        }
2245
        else
2246
        {
2247
          printercon = context_new(devcon);
2248
          freecon(devcon);
2249
        }
2250
      }
2251
2252
      if (printercon && context_range_get(printercon))
2253
        rangestr = strdup(context_range_get(printercon));
2254
      else
2255
        rangestr = strdup("unknown");
2256
2257
      cupsdSetStringf(&audit_message, "printer=%s uri=%s banners=%s,%s range=%s",
2258
                      p->name, p->sanitized_device_uri, p->job_sheets[0], p->job_sheets[1], rangestr);
2259
      audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
2260
                             ServerName, NULL, NULL, 1);
2261
      if (printercon)
2262
        context_free(printercon);
2263
      free(rangestr);
2264
      cupsdClearString(&audit_message);
2265
    }
2266
#endif /* WITH_LSPP */
2215
  }
2267
  }
2216
2268
2217
  p->raw    = 0;
2269
  p->raw    = 0;
Lines 5298-5304 write_irix_state(cupsd_printer_t *p) /* Link Here
5298
}
5350
}
5299
#endif /* __sgi */
5351
#endif /* __sgi */
5300
5352
5301
5302
/*
5353
/*
5303
 * 'write_xml_string()' - Write a string with XML escaping.
5354
 * 'write_xml_string()' - Write a string with XML escaping.
5304
 */
5355
 */

Return to bug 29477