Hello community,

here is the log from the commit of package cups for openSUSE:Factory checked in 
at 2014-02-19 09:09:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cups (Old)
 and      /work/SRC/openSUSE:Factory/.cups.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cups"

Changes:
--------
--- /work/SRC/openSUSE:Factory/cups/cups.changes        2014-02-07 
10:25:42.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.cups.new/cups.changes   2014-02-19 
09:09:45.000000000 +0100
@@ -1,0 +2,54 @@
+Wed Feb 12 11:53:45 CET 2014 - [email protected]
+
+- Added Begin/End comments in scriptlets for RPM macros 
+  so that it is easier to see in the "rpm -q --scripts cups"
+  output what each RPM macro actually does.
+
+-------------------------------------------------------------------
+Wed Feb 12 10:30:42 CET 2014 - [email protected]
+
+- Clean up how cupsd is launched (via SysVinit or systemd)
+  by maintaining strictly separated sections in cups.spec:
+  Either for launching cupsd via systemd (if have_systemd is set)
+  or for launching cupsd via SysVinit (if have_systemd is not set).
+  SysVinit support cannot be removed because CUPS 1.5.4
+  is provided for SLE11 in the OBS devel project "Printing".
+
+-------------------------------------------------------------------
+Wed Feb  5 14:04:42 CET 2014 - [email protected]
+
+- cups-1.5.4-CVE-2012-5519.patch adds better default protection
+  against misuse of privileges by normal users who have been
+  specifically allowed by root to do cupsd configuration changes
+  (CUPS STR#4223 CVE-2012-5519 Novell/Suse Bugzilla bnc#789566).
+  The new ConfigurationChangeRestriction cupsd.conf directive
+  specifies the level of restriction for cupsd.conf changes
+  that happen via HTTP/IPP requests to the running cupsd
+  (e.g. via CUPS web interface or via the cupsctl command).
+  By default certain cupsd.conf directives that deal with
+  filenames, paths, and users can no longer be changed via
+  requests to the running cupsd but only by manual editing
+  the cupsd.conf file and its default file permissions
+  permit only root to write the cupsd.conf file.
+  Those directives are: ConfigurationChangeRestriction,
+  AccessLog, BrowseLDAPCACertFile, CacheDir, ConfigFilePerm,
+  DataDir, DocumentRoot, ErrorLog, FatalErrors, FileDevice,
+  FontPath, Group, JobPrivateAccess, JobPrivateValues,
+  LogFilePerm, PageLog, Printcap, PrintcapFormat, PrintcapGUI,
+  RemoteRoot, RequestRoot, ServerBin, ServerCertificate,
+  ServerKey, ServerRoot, StateDir, SubscriptionPrivateAccess,
+  SubscriptionPrivateValues, SystemGroup, SystemGroupAuthKey,
+  TempDir, User, WebInterface.
+- The default group of users who are allowed to do cupsd
+  configuration changes via requests to the running cupsd
+  (i.e. the SystemGroup directive in cupsd.conf) is set
+  to 'root' only.
+- In this context a general security advice:
+  When root allows normal users to do system administration tasks
+  (in particular when root allows normal users to administer
+  system processes - i.e. processes that run as root), then
+  this or that kind of privilege escalation will be possible.
+  Only trustworthy users who do not misuse their privileges
+  may get allowed to do specific system administration tasks.
+
+-------------------------------------------------------------------

New:
----
  cups-1.5.4-CVE-2012-5519.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cups.spec ++++++
--- /var/tmp/diff_new_pack.UQTKFR/_old  2014-02-19 09:09:46.000000000 +0100
+++ /var/tmp/diff_new_pack.UQTKFR/_new  2014-02-19 09:09:46.000000000 +0100
@@ -45,7 +45,7 @@
 BuildRequires:  pkgconfig(systemd)
 %{?systemd_requires}
 %define have_systemd 1
-#may not be defined in older systemd macros..
+# may not be defined in older systemd macros..
 %{!?_tmpfilesdir: %global _tmpfilesdir /usr/lib/tmpfiles.d }
 %endif
 # The "BuildRequires: poppler-tools" installs /usr/bin/pdftops for the
@@ -177,7 +177,7 @@
 #   http://lists.opensuse.org/opensuse-factory/2013-01/msg00578.html
 Patch108:       cups-move-everything-to-run.patch
 # Patch109 fixes STR #4190: Send-Document failure ignored
-#(also applies to client-error-not-authorized)
+# (also applies to client-error-not-authorized)
 Patch109:       str4190.patch
 # Patch110 avoids any possible busy loop in cups-polld in case of unusual 
issues
 # by sleeping interval seconds see 
https://bugzilla.novell.com/show_bug.cgi?id=828228
@@ -192,6 +192,10 @@
 # see https://bugzilla.novell.com/show_bug.cgi?id=857372#c61
 # Patch111 must be applied on top of Patch105.
 Patch112:       cups-0003-systemd-secure-cups.service-unit-file.patch
+# Patch113 adds protection against privilege escalation by non-root users
+# who have been allowed by root to do CUPS configuration changes
+# (CUPS STR#4223 CVE-2012-5519 Novell/Suse Bugzilla bnc#789566):
+Patch113:       cups-1.5.4-CVE-2012-5519.patch
 # Install into this non-root directory (required when norootforbuild is used):
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -348,6 +352,10 @@
 # see https://bugzilla.novell.com/show_bug.cgi?id=857372#c61
 # Patch111 must be applied on top of Patch105.
 %patch112
+# Patch113 adds protection against privilege escalation by non-root users
+# who have been allowed by root to do CUPS configuration changes
+# (CUPS STR#4223 CVE-2012-5519 Novell/Suse Bugzilla bnc#789566):
+%patch113
 
 %build
 # Disable SILENT run of make so that make runs verbose as usual:
@@ -376,6 +384,7 @@
        --with-docdir=%{_datadir}/cups/webcontent \
        --with-cups-user=lp \
        --with-cups-group=lp \
+       --with-system-groups=root \
        --enable-debug \
        --enable-relro \
        --enable-gssapi \
@@ -395,8 +404,7 @@
 make %{?_smp_mflags} CXX=g++
 
 %install
-make BUILDROOT=$RPM_BUILD_ROOT install
-install -d -m755 $RPM_BUILD_ROOT/etc/init.d
+make BUILDROOT=%{buildroot} install
 # Use CUPS' own fonts (i.e. make CUPS work again in compliance with upstream).
 # In ancient times (see the RPM changelog entry dated "Thu Aug 16 17:05:19 
CEST 2001")
 # there was the general opinion it would be a great idea to deviate from CUPS 
upstream
@@ -416,48 +424,41 @@
 # and the only way out is to move CUPS' own fonts to an artificial
 # surrogate directory /usr/share/cups/CUPSfonts and have the
 # symbolic link /usr/share/cups/fonts -> /usr/share/cups/CUPSfonts:
-pushd $RPM_BUILD_ROOT/usr/share/cups/
+pushd %{buildroot}/usr/share/cups/
 mv fonts CUPSfonts && ln -s CUPSfonts fonts
 popd
-# Source101: cups.init
-install -m755 %{SOURCE101} $RPM_BUILD_ROOT/etc/init.d/cups
-ln -sf ../../etc/init.d/cups $RPM_BUILD_ROOT/usr/sbin/rccups
-%if %suse_version > 1220
-sed -i -e 's|/var/run|/run|g' $RPM_BUILD_ROOT/etc/init.d/cups
-sed -i -e 's|/var/lock|/run/lock|g' $RPM_BUILD_ROOT/etc/init.d/cups
-%endif
 # Source103: cups.sysconfig
-install -d -m755 $RPM_BUILD_ROOT/var/adm/fillup-templates
-install -m 644 %{SOURCE103} 
$RPM_BUILD_ROOT/var/adm/fillup-templates/sysconfig.cups
+install -d -m755 %{buildroot}/var/adm/fillup-templates
+install -m 644 %{SOURCE103} 
%{buildroot}/var/adm/fillup-templates/sysconfig.cups
 # Make directory for ssl files:
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/cups/ssl
+mkdir -p %{buildroot}%{_sysconfdir}/cups/ssl
 # Add a client.conf as template (Source108: cups-client.conf):
-install -m644 %{SOURCE108} $RPM_BUILD_ROOT%{_sysconfdir}/cups/client.conf
+install -m644 %{SOURCE108} %{buildroot}%{_sysconfdir}/cups/client.conf
 %if %suse_version > 1220
-sed -i -e 's|/var/run|/run|g' $RPM_BUILD_ROOT%{_sysconfdir}/cups/client.conf
+sed -i -e 's|/var/run|/run|g' %{buildroot}%{_sysconfdir}/cups/client.conf
 %endif
 # Source104: cups.xinetd
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d
-install -m 644 -D %{SOURCE104} $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/cups-lpd
+mkdir -p %{buildroot}%{_sysconfdir}/xinetd.d
+install -m 644 -D %{SOURCE104} %{buildroot}%{_sysconfdir}/xinetd.d/cups-lpd
 # Make the libraries accessible also via generic named links:
-ln -sf libcupsimage.so.2 $RPM_BUILD_ROOT%{_libdir}/libcupsimage.so
-ln -sf libcups.so.2 $RPM_BUILD_ROOT%{_libdir}/libcups.so
+ln -sf libcupsimage.so.2 %{buildroot}%{_libdir}/libcupsimage.so
+ln -sf libcups.so.2 %{buildroot}%{_libdir}/libcups.so
 # Add missing usual directories:
-install -d -m755 $RPM_BUILD_ROOT%{_datadir}/cups/drivers
-install -d -m755 $RPM_BUILD_ROOT/var/cache/cups
+install -d -m755 %{buildroot}%{_datadir}/cups/drivers
+install -d -m755 %{buildroot}/var/cache/cups
 # Add conf/pam.suse regarding support for PAM (see Patch100: cups-pam.diff):
-install -m 644 -D conf/pam.suse $RPM_BUILD_ROOT/etc/pam.d/cups
+install -m 644 -D conf/pam.suse %{buildroot}/etc/pam.d/cups
 # Add missing usual documentation:
-install -d -m755 $RPM_BUILD_ROOT/%{_defaultdocdir}/cups
+install -d -m755 %{buildroot}/%{_defaultdocdir}/cups
 for f in CHANGES*.txt CREDITS.txt INSTALL.txt LICENSE.txt README.txt
-do install -m 644 "$f" $RPM_BUILD_ROOT%{_defaultdocdir}/cups/
+do install -m 644 "$f" %{buildroot}%{_defaultdocdir}/cups/
 done
 # Source102: postscript.ppd.bz2
-bzip2 -cd < %{SOURCE102} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript.ppd
+bzip2 -cd < %{SOURCE102} > %{buildroot}%{_datadir}/cups/model/Postscript.ppd
 # Source105: PSLEVEL1.PPD.bz2
-bzip2 -cd < %{SOURCE105} > 
$RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript-level1.ppd
+bzip2 -cd < %{SOURCE105} > 
%{buildroot}%{_datadir}/cups/model/Postscript-level1.ppd
 # Source106: PSLEVEL2.PPD.bz2
-bzip2 -cd < %{SOURCE106} > 
$RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript-level2.ppd
+bzip2 -cd < %{SOURCE106} > 
%{buildroot}%{_datadir}/cups/model/Postscript-level2.ppd
 find %{buildroot}/usr/share/cups/model -name "*.ppd" | while read FILE
 do # Change default paper size from Letter to A4 if possible
    # https://bugzilla.novell.com/show_bug.cgi?id=suse30662
@@ -469,42 +470,65 @@
    gzip -9 "$FILE"
 done
 # Add files for desktop menu:
-rm -f $RPM_BUILD_ROOT/usr/share/applications/cups.desktop
+rm -f %{buildroot}/usr/share/applications/cups.desktop
 %suse_update_desktop_file -i cups PrintingUtility 2>/dev/null
-mkdir $RPM_BUILD_ROOT/usr/share/pixmaps
-install -m 644 $RPM_BUILD_ROOT/usr/share/icons/hicolor/64x64/apps/cups.png 
$RPM_BUILD_ROOT/usr/share/pixmaps
-rm -rf $RPM_BUILD_ROOT/usr/share/icons
-# Norwegian is "nb", "zh" is probably "zh_CN"
-mv $RPM_BUILD_ROOT/usr/share/locale/{no,nb}
-mv $RPM_BUILD_ROOT/usr/share/locale/{zh,zh_CN}
+mkdir %{buildroot}/usr/share/pixmaps
+install -m 644 %{buildroot}/usr/share/icons/hicolor/64x64/apps/cups.png 
%{buildroot}/usr/share/pixmaps
+rm -rf %{buildroot}/usr/share/icons
+# Norwegian is "nb", "zh" is probably "zh_CN":
+mv %{buildroot}/usr/share/locale/{no,nb}
+mv %{buildroot}/usr/share/locale/{zh,zh_CN}
 # Save /etc/cups/cupsd.conf and /etc/cups/cupsd.conf.default from becoming 
hardlinked
 # via the fdupes run below, see 
https://bugzilla.novell.com/show_bug.cgi?id=773971
 # by making their content different and at the same time fix the misleading 
comment.
 # Intentionally let the build fail if 'grep' does not find what 'sed' should 
change
 # because if upstream changed it 'sed' would silently no longer change the 
files
 # so that fdupes would make /etc/cups/cupsd.conf and 
/etc/cups/cupsd.conf.default hardlinked:
-grep -q '^# Sample configuration ' 
$RPM_BUILD_ROOT/%{_sysconfdir}/cups/cupsd.conf
-sed -i -e 's/^# Sample configuration /# Configuration /' 
$RPM_BUILD_ROOT/%{_sysconfdir}/cups/cupsd.conf
-grep -q '^# Sample configuration ' 
$RPM_BUILD_ROOT/%{_sysconfdir}/cups/cupsd.conf.default
-sed -i -e 's/^# Sample configuration /# Default configuration /' 
$RPM_BUILD_ROOT/%{_sysconfdir}/cups/cupsd.conf.default
-# systemd stuff:
+grep -q '^# Sample configuration ' %{buildroot}/%{_sysconfdir}/cups/cupsd.conf
+sed -i -e 's/^# Sample configuration /# Configuration /' 
%{buildroot}/%{_sysconfdir}/cups/cupsd.conf
+grep -q '^# Sample configuration ' 
%{buildroot}/%{_sysconfdir}/cups/cupsd.conf.default
+sed -i -e 's/^# Sample configuration /# Default configuration /' 
%{buildroot}/%{_sysconfdir}/cups/cupsd.conf.default
+# Begin how cupsd is launched (via SysVinit or systemd):
 %if 0%{?have_systemd}
-# move the installed cups.socket and cups.path into a documentation directory
+# Begin launch cupsd via systemd:
+# See http://en.opensuse.org/openSUSE:Systemd_packaging_guidelines
+# Move the installed cups.socket and cups.path into a documentation directory
 # so that experienced admins can make their own individual systemd unit files
 # for socket activation and/or path activation as they need it for their 
particular cases
 # see https://bugzilla.novell.com/show_bug.cgi?id=857372#c61
-mkdir $RPM_BUILD_ROOT/%{_defaultdocdir}/cups/systemd
-mv $RPM_BUILD_ROOT/%{_unitdir}/cups.path 
$RPM_BUILD_ROOT/%{_defaultdocdir}/cups/systemd/cups.path
-mv $RPM_BUILD_ROOT/%{_unitdir}/cups.socket 
$RPM_BUILD_ROOT/%{_defaultdocdir}/cups/systemd/cups.socket
-# install /usr/lib/tmpfiles.d/cups.conf
-mkdir -p ${RPM_BUILD_ROOT}%{_tmpfilesdir}
-cat > ${RPM_BUILD_ROOT}%{_tmpfilesdir}/cups.conf <<EOF
+mkdir %{buildroot}/%{_defaultdocdir}/cups/systemd
+mv %{buildroot}/%{_unitdir}/cups.path 
%{buildroot}/%{_defaultdocdir}/cups/systemd/cups.path
+mv %{buildroot}/%{_unitdir}/cups.socket 
%{buildroot}/%{_defaultdocdir}/cups/systemd/cups.socket
+# Install /usr/lib/tmpfiles.d/cups.conf
+mkdir -p %{buildroot}%{_tmpfilesdir}
+cat > %{buildroot}%{_tmpfilesdir}/cups.conf <<EOF
 # See tmpfiles.d(5) for details
 d /run/cups 0755 root lp -
 d /run/cups/certs 0511 lp sys -
 d /var/spool/cups/tmp - - - 30d
 EOF
+# Provide SUSE policy symlink /usr/sbin/rcFOO -> /etc/init.d/FOO
+# /usr/sbin/service exists only since openSUSE 12.3:
+%if 0%{?suse_version} > 1220
+ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rccups
+%else
+ln -s /sbin/service %{buildroot}%{_sbindir}/rccups
+%endif
+# End launch cupsd via systemd
+%else
+# Begin launch cupsd via SysVinit:
+# Source101: cups.init
+install -d -m755 %{buildroot}/etc/init.d
+install -m755 %{SOURCE101} %{buildroot}/etc/init.d/cups
+ln -sf ../../etc/init.d/cups %{buildroot}/usr/sbin/rccups
+%if %suse_version > 1220
+# Adapt init script according to Patch108 that moves everything to /run
+sed -i -e 's|/var/run|/run|g' %{buildroot}/etc/init.d/cups
+sed -i -e 's|/var/lock|/run/lock|g' %{buildroot}/etc/init.d/cups
+%endif
+# End launch cupsd via SysVinit
 %endif
+# End how cupsd is launched (via SysVinit or systemd)
 # Run fdupes:
 # The RPM macro fdupes runs /usr/bin/fdupes that links files with identical 
content.
 # Never run fdupes carelessly over the whole buildroot directory
@@ -516,42 +540,79 @@
 # so that fdupes can only run for specific directories where linking files is 
safe.
 # Using fdupes -s, which will create symlinks that are easier to grasp for rpm 
and
 # rpmlint will give a "dangling symlink" error if the file and link ended up 
in different packages:
-%fdupes -s $RPM_BUILD_ROOT/%{_datadir}/cups
+%fdupes -s %{buildroot}/%{_datadir}/cups
 
 %pre
+# Use a real bash script with an explicit "exit 0" at the end to be by default 
fail safe
+# an explicit "exit 1" must be use to enforce package install/upgrade/erase 
failure where needed
+# see the "Shared_libraries" section in 
http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
 /usr/sbin/groupadd -g 71 -o -r ntadmin 2>/dev/null || :
 %if 0%{?have_systemd}
-%service_add_pre cups.service cups.socket cups.path
+# Begin service_add_pre cups.service
+%service_add_pre cups.service
+# End service_add_pre cups.service
 %endif
 exit 0
 
 %post
-%{fillup_and_insserv -ny cups cups}
+# Use a real bash script with an explicit "exit 0" at the end to be by default 
fail safe
+# an explicit "exit 1" must be use to enforce package install/upgrade/erase 
failure where needed
+# see the "Shared_libraries" section in 
http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
 %if 0%{?have_systemd}
-%service_add_post cups.service cups.socket cups.path
+# Begin service_add_post cups.service
+%service_add_post cups.service
+# End service_add_post cups.service
+%else
+# Begin fillup_and_insserv -ny cups cups
+%{fillup_and_insserv -ny cups cups}
+# End fillup_and_insserv -ny cups cups
 %endif
 exit 0
 
 %preun
-%stop_on_removal cups
+# Use a real bash script with an explicit "exit 0" at the end to be by default 
fail safe
+# an explicit "exit 1" must be use to enforce package install/upgrade/erase 
failure where needed
+# see the "Shared_libraries" section in 
http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
 %if 0%{?have_systemd}
-%service_del_preun cups.service cups.socket cups.path
+# Begin service_del_preun cups.service
+%service_del_preun cups.service
+# End service_del_preun cups.service
+%else
+# Begin stop_on_removal cups
+%stop_on_removal cups
+# End stop_on_removal cups
 %endif
 exit 0
 
 %postun
+# Use a real bash script with an explicit "exit 0" at the end to be by default 
fail safe
+# an explicit "exit 1" must be use to enforce package install/upgrade/erase 
failure where needed
+# see the "Shared_libraries" section in 
http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
+%if 0%{?have_systemd}
+# Begin service_del_postun cups.service
+%service_del_postun cups.service
+# End service_del_postun cups.service
+%else
+# Begin restart_on_update cups
 %restart_on_update cups
+# End restart_on_update cups
+# Begin insserv_cleanup
 %{insserv_cleanup}
-%if 0%{?have_systemd}
-%service_del_postun cups.service cups.socket cups.path
+# End insserv_cleanup
 %endif
 exit 0
 
 %post libs
+# Use a real bash script with an explicit "exit 0" at the end to be by default 
fail safe
+# an explicit "exit 1" must be use to enforce package install/upgrade/erase 
failure where needed
+# see the "Shared_libraries" section in 
http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
 /sbin/ldconfig
 exit 0
 
 %postun libs
+# Use a real bash script with an explicit "exit 0" at the end to be by default 
fail safe
+# an explicit "exit 1" must be use to enforce package install/upgrade/erase 
failure where needed
+# see the "Shared_libraries" section in 
http://en.opensuse.org/openSUSE:Packaging_scriptlet_snippets
 /sbin/ldconfig
 exit 0
 
@@ -572,12 +633,17 @@
 %config(noreplace) %attr(640,root,lp) %{_sysconfdir}/cups/snmp.conf
 %config(noreplace) %attr(755,lp,lp) %{_sysconfdir}/cups/interfaces
 %config(noreplace) %{_sysconfdir}/xinetd.d/cups-lpd
-%config %attr(0755,root,root) %{_sysconfdir}/init.d/cups
 %config %{_sysconfdir}/pam.d/cups
 %config %{_sysconfdir}/dbus-1/system.d/cups.conf
 %dir %attr(700,root,lp) %{_sysconfdir}/cups/ssl
 %dir %attr(755,root,lp) %{_sysconfdir}/cups/ppd
 /var/adm/fillup-templates/sysconfig.cups
+%if 0%{?have_systemd}
+%{_unitdir}/cups.service
+%{_tmpfilesdir}/cups.conf
+%else
+%config %attr(0755,root,root) %{_sysconfdir}/init.d/cups
+%endif
 %{_bindir}/cupstestppd
 %{_sbindir}/cupsaddsmb
 %{_sbindir}/cupsctl
@@ -661,10 +727,6 @@
 %doc %{_mandir}/man8/cupsfilter.8.gz
 %{_datadir}/cups/
 %exclude %{_datadir}/cups/ppdc/
-%if 0%{?have_systemd}
-%{_unitdir}/cups.service
-%{_tmpfilesdir}/cups.conf
-%endif
 
 %files client
 # Set explicite owner, group, and permissions for lppasswd



++++++ cups-1.5.4-CVE-2012-5519.patch ++++++
--- doc/help/ref-cupsd-conf.html.in.orig        2012-01-30 22:40:21.000000000 
+0100
+++ doc/help/ref-cupsd-conf.html.in     2014-02-05 14:13:23.000000000 +0100
@@ -917,6 +917,28 @@ ConfigFilePerm 0640
 
 </BLOCKQUOTE>
 
+<H2 CLASS="title"><A 
NAME="ConfigurationChangeRestriction">ConfigurationChangeRestriction</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+ConfigurationChangeRestriction all
+ConfigurationChangeRestriction root-only
+ConfigurationChangeRestriction none
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>ConfigurationChangeRestriction</CODE> directive specifies
+the degree of restriction for changes to cupsd.conf.  Keywords dealing
+with filenames, paths, and users are security-sensitive. Changes to
+them via HTTP are forbidden by default (<CODE>all</CODE>). The value
+<CODE>none</CODE> removes any restriction altogether (note that this
+is unsafe). The value <CODE>root-only</CODE> allows only users
+authorised as user "root" to adjust security-sensitive configuration
+settings, but note that users adjusting settings using polkit (via
+cups-pk-helper) are authenticated as user "root".</P>
+
 
 <H2 CLASS="title"><A NAME="DataDir">DataDir</A></H2>
 
--- man/cupsctl.man.orig        2011-01-11 04:04:04.000000000 +0100
+++ man/cupsctl.man     2014-02-05 14:15:23.000000000 +0100
@@ -90,7 +90,8 @@ Disable printer sharing:
     cupsctl --no-shared-printers
 .fi
 .LP
-Enable printing using the file: pseudo-device:
+Enable printing using the file: pseudo-device (note that this is
+forbidden by default):
 .nf
     cupsctl FileDevice=Yes
 .fi
--- man/cupsd.conf.man.in.orig  2011-05-18 23:33:35.000000000 +0200
+++ man/cupsd.conf.man.in       2014-02-05 14:16:58.000000000 +0100
@@ -238,6 +238,21 @@ ConfigFilePerm mode
 Specifies the permissions for all configuration files that the scheduler
 writes.
 .TP 5
+ConfigurationChangeRestriction all
+.TP 5
+ConfigurationChangeRestriction root-only
+.TP 5
+ConfigurationChangeRestriction none
+.br
+Specifies the degree of restriction for changes to cupsd.conf.
+Keywords dealing with filenames, paths, and users are
+security-sensitive. Changes to them via HTTP are forbidden by default
+("all"). The value "none" removes any restriction altogether (note
+that this is unsafe). The value "root-only" allows only users
+authorised as user "root" to adjust security-sensitive configuration
+settings, but note that users adjusting settings using polkit (via
+cups-pk-helper) are authenticated as user "root".
+.TP 5
 DataDir path
 .br
 Specified the directory where data files can be found.
--- scheduler/client.c.orig     2012-03-07 07:05:39.000000000 +0100
+++ scheduler/client.c  2014-02-05 14:32:49.000000000 +0100
@@ -1685,13 +1685,10 @@ cupsdReadClient(cupsd_client_t *con)    /*
            * Validate the resource name...
            */
 
-            if (strncmp(con->uri, "/admin/conf/", 12) ||
-               strchr(con->uri + 12, '/') ||
-               strlen(con->uri) == 12)
+            if (strcmp(con->uri, "/admin/conf/cupsd.conf"))
            {
             /*
-             * PUT can only be done to configuration files under
-             * /admin/conf...
+             * PUT can only be done to the cupsd.conf file...
              */
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -3827,6 +3824,8 @@ install_conf_file(cupsd_client_t *con)    /
   char         buffer[16384];          /* Copy buffer */
   ssize_t      bytes;                  /* Number of bytes */
 
+  if (!cupsdCheckConfigurationAllowed (con))
+    return (HTTP_FORBIDDEN);
 
  /*
   * Open the request file...
--- scheduler/conf.h.orig       2011-04-22 19:47:03.000000000 +0200
+++ scheduler/conf.h    2014-02-05 14:44:49.000000000 +0100
@@ -92,6 +92,18 @@ typedef struct
 
 
 /*
+ * Configuration change restriction (CVE-2012-5519)
+ */
+
+typedef enum
+{
+  CUPSD_CONFRESTRICT_NONE,     /* No checking of PUT cupsd.conf */
+  CUPSD_CONFRESTRICT_ROOT,     /* Only allow root to change all opts */
+  CUPSD_CONFRESTRICT_ALL,      /* Restricted keywords not to be changed */
+} cupsd_confrestrict_t;
+
+
+/*
  * Globals...
  */
 
@@ -165,6 +177,8 @@ VAR int                     ClassifyOverride        
VALUE(0),
                                        /* Allow overrides? */
                        ConfigFilePerm          VALUE(0640),
                                        /* Permissions for config files */
+                        ConfigurationChangeRestriction 
VALUE(CUPSD_CONFRESTRICT_ALL),
+                                        /* CVE-2012-5519 protection */
                        LogDebugHistory         VALUE(200),
                                        /* Amount of automatic debug history */
                        FatalErrors             VALUE(CUPSD_FATAL_CONFIG),
@@ -291,6 +305,7 @@ __attribute__ ((__format__ (__printf__,
 extern int     cupsdLogPage(cupsd_job_t *job, const char *page);
 extern int     cupsdLogRequest(cupsd_client_t *con, http_status_t code);
 extern int     cupsdReadConfiguration(void);
+extern int     cupsdCheckConfigurationAllowed(cupsd_client_t *con);
 extern int     cupsdWriteErrorLog(int level, const char *message);
 
 
--- scheduler/conf.c.orig       2011-11-16 16:28:11.000000000 +0100
+++ scheduler/conf.c    2014-02-05 15:03:28.000000000 +0100
@@ -3196,6 +3196,22 @@ read_configuration(cups_file_t *fp)      /* I
       cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname,
                      pollp->port);
     }
+    else if (!strcasecmp(line, "ConfigurationChangeRestriction") && value)
+    {
+      if (!strcasecmp(value, "none"))
+       ConfigurationChangeRestriction = CUPSD_CONFRESTRICT_NONE;
+      else if (!strcasecmp(value, "root-only"))
+       ConfigurationChangeRestriction = CUPSD_CONFRESTRICT_ROOT;
+      else if (!strcasecmp(value, "all"))
+       ConfigurationChangeRestriction = CUPSD_CONFRESTRICT_ALL;
+      else
+      {
+       cupsdLogMessage(CUPSD_LOG_WARN,
+                       "Unknown restriction type %s on line %d.",
+                       value, linenum);
+       return (0);
+      }
+    }
     else if (!_cups_strcasecmp(line, "DefaultAuthType") && value)
     {
      /*
@@ -3657,6 +3673,250 @@ read_configuration(cups_file_t *fp)     /* I
 }
 
 
+static cups_array_t *
+_cupsdGetBlacklistedConfLines(cups_file_t *fp)
+{
+  cups_array_t *conf;
+  int linenum;
+  char keyword[HTTP_MAX_BUFFER],
+    *temp,
+    *value;
+  const char **kw;
+  size_t len;
+  const char *blacklist[] = {
+    "ConfigurationChangeRestriction",
+    "AccessLog",
+    "BrowseLDAPCACertFile",
+    "CacheDir",
+    "ConfigFilePerm",
+    "DataDir",
+    "DocumentRoot",
+    "ErrorLog",
+    "FatalErrors",
+    "FileDevice",
+    "FontPath",
+    "Group",
+    "JobPrivateAccess",
+    "JobPrivateValues",
+    "LogFilePerm",
+    "PageLog",
+    "Printcap",
+    "PrintcapFormat",
+    "PrintcapGUI",
+    "RemoteRoot",
+    "RequestRoot",
+    "ServerBin",
+    "ServerCertificate",
+    "ServerKey",
+    "ServerRoot",
+    "StateDir",
+    "SubscriptionPrivateAccess",
+    "SubscriptionPrivateValues",
+    "SystemGroup",
+    "SystemGroupAuthKey",
+    "TempDir",
+    "User",
+    "WebInterface",
+    NULL
+  };
+
+  conf = cupsArrayNew (NULL, NULL);
+
+ /*
+  * Loop through each line in the file...
+  */
+
+  linenum = 0;
+
+  while (cupsFileGetConf(fp, keyword, sizeof(keyword), &value, &linenum))
+  {
+    for (kw = blacklist; *kw; kw++)
+      if (!strcasecmp (keyword, *kw))
+       break;
+
+    if (*kw == NULL)
+      continue;
+
+   /*
+    * Remember lines we might need to compare against, but only the
+    * last occurrence of each keyword, except for
+    * SystemGroup. SystemGroup is special because it is cumulative:
+    * each SystemGroup line adds groups to the list. For that reason,
+    * we remember multiple SystemGroup lines and don't care about the
+    * order...
+    */
+
+    len = strlen (keyword);
+    if (strcasecmp(keyword, "SystemGroup") != 0)
+    {
+      for (temp = (char *) cupsArrayFirst(conf);
+          temp;
+          temp = (char *) cupsArrayNext(conf))
+      {
+       if (!strncasecmp (temp, keyword, len) && temp[len] == ' ')
+       {
+         cupsArrayRemove(conf, temp);
+
+         /*
+          * There can only be one such line because we do this for each
+          * line containing a blacklisted keyword
+          */
+
+         break;
+       }
+      }
+    }
+
+    len += (value ? strlen (value) : 0) + 2;
+    temp = malloc (len);
+    if (!temp)
+      goto fail;
+
+    snprintf (temp, len, "%s %s", keyword, value ? value : "");
+    cupsArrayAdd(conf, temp);
+  }
+
+  return conf;
+
+fail:
+  for (temp = (char *) cupsArrayFirst(conf);
+       temp;
+       temp = (char *) cupsArrayNext(conf))
+    free(temp);
+  cupsArrayDelete(conf);
+  return NULL;
+}
+
+
+/*
+ * 'cupsdCheckConfigurationAllowed()' - Check whether the new configuration
+ *                                      file can be installed
+ */
+
+int                                    /* O - 1 if allowed, 0 otherwise */
+cupsdCheckConfigurationAllowed(cupsd_client_t *con)
+{
+  int status = 0;
+  cups_file_t *fp;
+  cups_array_t *oldconf,
+    *newconf = NULL;
+  char *oldline,
+    *newline;
+
+  if (ConfigurationChangeRestriction == CUPSD_CONFRESTRICT_NONE)
+   /*
+    * Option checking disabled...
+    */
+    return (1);
+
+  if (ConfigurationChangeRestriction == CUPSD_CONFRESTRICT_ROOT &&
+      !strcmp (con->username, "root"))
+   /*
+    * This is requested by root and our configuration tells us to
+    * accept it.
+    */
+    return (1);
+
+ /*
+  * First read the current cupsd.conf...
+  */
+
+  if ((fp = cupsFileOpen (ConfigurationFile, "r")) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_WARN, "Unable to open configuration file?!");
+    return (0);
+  }
+
+  oldconf = _cupsdGetBlacklistedConfLines(fp);
+  cupsFileClose(fp);
+  if (!oldconf)
+    return (0);
+
+ /*
+  * Now take a look at the proposed new cupsd.conf...
+  */
+
+  if ((fp = cupsFileOpen(con->filename, "r")) == NULL)
+  {
+    cupsdLogMessage(CUPSD_LOG_WARN, "Unable to examine new config file");
+    goto fail;
+  }
+
+  newconf = _cupsdGetBlacklistedConfLines(fp);
+  cupsFileClose(fp);
+  if (!newconf)
+    goto fail;
+
+ /*
+  * Now compare the blacklisted directives in each.
+  */
+
+  status = 1;
+  for (oldline = (char *) cupsArrayFirst(oldconf);
+       oldline;
+       oldline = (char *) cupsArrayNext(oldconf))
+  {
+    for (newline = (char *) cupsArrayFirst(newconf);
+        newline;
+        newline = (char *) cupsArrayNext(newconf))
+      if (!strcmp (oldline, newline))
+       break;
+
+    if (newline == NULL)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                     "Attempt to remove or change '%s' denied", oldline);
+      status = 0;
+      break;
+    }
+
+    cupsArrayRemove(newconf, newline);
+    free(newline);
+  }
+
+  if (status)
+  {
+   /*
+    * All the original directives are still present. Have any been added?
+    */
+
+    newline = (char *) cupsArrayFirst(newconf);
+    if (newline != NULL)
+    {
+      char *p;
+
+      cupsArrayRemove(newconf, newline);      
+
+      p = strchr (newline, ' ');
+      if (p)
+       *p = '\0';
+
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Attempt to add '%s' directive denied", 
newline);
+      free(newline);
+      status = 0;
+    }
+  }
+
+fail:
+  for (oldline = (char *) cupsArrayFirst(oldconf);
+       oldline;
+       oldline = (char *) cupsArrayNext(oldconf))
+    free(oldline);
+  cupsArrayDelete(oldconf);
+
+  if (newconf)
+  {
+    for (newline = (char *) cupsArrayFirst(newconf);
+        newline;
+        newline = (char *) cupsArrayNext(newconf))
+      free(newline);
+    cupsArrayDelete(newconf);
+  }
+
+  return (status);
+}
+
+
 /*
  * 'read_location()' - Read a <Location path> definition.
  */

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to